rueckbau
All checks were successful
Deploy / deploy-staging (push) Successful in 7s
Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-04-27 00:11:03 +02:00
parent 39ea8da129
commit 7ce9173d57
11 changed files with 259 additions and 345 deletions

View File

@@ -214,15 +214,25 @@ final class InstrumentPage
{
$instrumentId = (int) ($_POST['instrument_id'] ?? 0);
$instrument = $this->assertInstrumentAccessible($instrumentId);
$isin = strtoupper(trim((string) ($instrument['isin'] ?? '')));
if ($isin === '') {
throw new RuntimeException('Fuer diese Aktie ist keine ISIN hinterlegt.');
$symbol = strtoupper(trim((string) ($instrument['symbol'] ?? '')));
if ($symbol === '') {
throw new RuntimeException('Fuer diese Aktie ist kein Symbol hinterlegt.');
}
$apiResult = \module_fn('boersenchecker', 'bavest_fetch_quote_by_isin', $isin);
$apiResult = \module_fn('boersenchecker', 'alpha_vantage_fetch_quote_by_symbol', $symbol);
if (empty($apiResult['ok'])) {
throw new RuntimeException((string) ($apiResult['message'] ?? 'API-Abruf fehlgeschlagen.'));
}
$latestApiQuote = $this->latestApiQuoteForInstrument($instrumentId);
if ($this->isApiSnapshotStale($latestApiQuote, (string) ($apiResult['fetched_at'] ?? ''))) {
$displayTime = (string) \module_fn(
'boersenchecker',
'format_datetime_for_display',
(string) ($apiResult['fetched_at'] ?? ''),
(string) ($apiResult['source'] ?? 'alphavantage:global_quote')
);
return 'Alpha Vantage lieferte keinen neueren Snapshot als ' . $displayTime . '.';
}
$storeResult = \module_fn(
'boersenchecker',
@@ -235,14 +245,14 @@ final class InstrumentPage
);
return !empty($storeResult['inserted'])
? 'Bavest-Kurs gespeichert.'
: 'Vorhandener Bavest-Snapshot wiederverwendet.';
? 'Alpha-Vantage-Kurs gespeichert.'
: 'Vorhandener Alpha-Vantage-Snapshot wiederverwendet.';
}
private function searchSymbol(): string
{
$this->searchKeywords = trim((string) ($_POST['search_keywords'] ?? ''));
$result = \module_fn('boersenchecker', 'bavest_search_symbols', $this->searchKeywords);
$result = \module_fn('boersenchecker', 'alpha_vantage_search_symbols', $this->searchKeywords);
$this->searchResults = is_array($result['results'] ?? null) ? $result['results'] : [];
if (empty($result['ok'])) {
throw new RuntimeException((string) ($result['message'] ?? 'Symbolsuche fehlgeschlagen.'));
@@ -294,4 +304,37 @@ final class InstrumentPage
return (new \DateTimeImmutable('now', $timezone))->format('Y-m-d H:i:s');
}
}
private function latestApiQuoteForInstrument(int $instrumentId): ?array
{
$stmt = $this->pdo->prepare(
'SELECT *
FROM ' . $this->quoteTable . '
WHERE instrument_id = :instrument_id
AND source LIKE :source
ORDER BY quoted_at DESC, created_at DESC, id DESC
LIMIT 1'
);
$stmt->execute([
'instrument_id' => $instrumentId,
'source' => 'alphavantage:%',
]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
return is_array($row) ? $row : null;
}
private function isApiSnapshotStale(?array $latestQuote, string $incomingQuotedAt): bool
{
if (!is_array($latestQuote)) {
return false;
}
$latestTimestamp = strtotime((string) ($latestQuote['quoted_at'] ?? ''));
$incomingTimestamp = strtotime(trim($incomingQuotedAt));
if ($latestTimestamp === false || $incomingTimestamp === false) {
return false;
}
return $incomingTimestamp <= $latestTimestamp;
}
}