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

This commit is contained in:
2026-04-29 02:43:40 +02:00
parent ef87dc6cd3
commit 235630ee1e
2 changed files with 73 additions and 21 deletions

View File

@@ -214,30 +214,32 @@ final class FxRatesService
}
$inverse = $this->repository->listDirectHistory($toCurrency, $fromCurrency, $this->normalizeTimestamp($from), $this->normalizeTimestamp($to), $limit);
if ($inverse === []) {
return [];
}
if ($inverse !== []) {
$result = [];
foreach ($inverse as $row) {
$inverseRate = is_numeric($row['rate'] ?? null) ? (float) $row['rate'] : null;
if ($inverseRate === null || $inverseRate <= 0) {
continue;
}
$result = [];
foreach ($inverse as $row) {
$inverseRate = is_numeric($row['rate'] ?? null) ? (float) $row['rate'] : null;
if ($inverseRate === null || $inverseRate <= 0) {
continue;
$result[] = [
'fetch_id' => $row['fetch_id'] ?? null,
'base_currency' => $fromCurrency,
'target_currency' => $toCurrency,
'rate' => 1 / $inverseRate,
'rate_date' => $row['rate_date'] ?? null,
'provider' => $row['provider'] ?? null,
'fetched_at' => $row['fetched_at'] ?? null,
'is_exact_pair' => false,
];
}
$result[] = [
'fetch_id' => $row['fetch_id'] ?? null,
'base_currency' => $fromCurrency,
'target_currency' => $toCurrency,
'rate' => 1 / $inverseRate,
'rate_date' => $row['rate_date'] ?? null,
'provider' => $row['provider'] ?? null,
'fetched_at' => $row['fetched_at'] ?? null,
'is_exact_pair' => false,
];
if ($result !== []) {
return array_map(fn (array $row): array => $this->localizeRateResult($row), $result);
}
}
return array_map(fn (array $row): array => $this->localizeRateResult($row), $result);
return $this->crossHistory($fromCurrency, $toCurrency, $from, $to, $limit);
}
public function runScheduledRefresh(array $context = []): array
@@ -647,6 +649,49 @@ final class FxRatesService
return $filtered;
}
private function crossHistory(string $fromCurrency, string $toCurrency, ?string $from = null, ?string $to = null, int $limit = 200): array
{
$fromAt = $this->normalizeTimestamp($from);
$toAt = $this->normalizeTimestamp($to);
$candidates = array_reverse($this->repository->listRecentFetches(max($limit * 4, 50)));
$result = [];
foreach ($candidates as $fetch) {
$fetchedAt = (string) ($fetch['fetched_at'] ?? '');
if ($fetchedAt === '') {
continue;
}
if ($fromAt !== null && strcmp($fetchedAt, $fromAt) < 0) {
continue;
}
if ($toAt !== null && strcmp($fetchedAt, $toAt) > 0) {
continue;
}
$snapshot = $this->repository->getSnapshotByFetchId((int) ($fetch['id'] ?? 0), [$fromCurrency, $toCurrency]);
if ($snapshot === null) {
continue;
}
$rates = is_array($snapshot['rates'] ?? null) ? $snapshot['rates'] : [];
$resolved = $this->resolveRateFromSnapshot($snapshot, $rates, $fromCurrency, $toCurrency);
if ($resolved === null) {
continue;
}
$result[] = $this->localizeRateResult($resolved + [
'fetch_id' => $fetch['id'] ?? null,
]);
if (count($result) >= $limit) {
break;
}
}
return $result;
}
private function localizeFetch(?array $fetch): ?array
{
if (!is_array($fetch)) {