mirror of
https://github.com/we-promise/sure.git
synced 2026-05-12 23:25:00 +00:00
Fix foreign currency accounts using wrong exchange rate in balance sheet totals (#1010)
Balance sheet totals and accountable type summaries used a SQL JOIN on exchange_rates matching only today's date, which returned NULL (defaulting to 1:1) when no rate existed for that exact date. This caused foreign currency accounts to show incorrect totals. Changes: - Refactor BalanceSheet::AccountTotals to batch-fetch exchange rates via ExchangeRate.rates_for, with provider fallback, instead of a SQL join - Refactor Accountable.balance_money to use the same batch approach - Add ExchangeRate.rates_for helper for deduplicated rate lookups - Fix net worth chart query to fall back to the nearest future rate when no historical rate exists for a given date - Add composite index on accounts (family_id, status, accountable_type) - Reuse nearest cached exchange rate within a 5-day lookback window before calling the provider, preventing redundant API calls on weekends and holidays when providers return prior-day rates https://claude.ai/code/session_01GyssBJxQqdWnuYofQRjUu8 Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -136,13 +136,22 @@ class Balance::ChartSeriesBuilder
|
||||
LIMIT 1
|
||||
) last_bal ON TRUE
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT er.rate
|
||||
FROM exchange_rates er
|
||||
WHERE er.from_currency = accounts.currency
|
||||
AND er.to_currency = :target_currency
|
||||
AND er.date <= d.date
|
||||
ORDER BY er.date DESC
|
||||
LIMIT 1
|
||||
SELECT COALESCE(
|
||||
(SELECT er.rate
|
||||
FROM exchange_rates er
|
||||
WHERE er.from_currency = accounts.currency
|
||||
AND er.to_currency = :target_currency
|
||||
AND er.date <= d.date
|
||||
ORDER BY er.date DESC
|
||||
LIMIT 1),
|
||||
(SELECT er.rate
|
||||
FROM exchange_rates er
|
||||
WHERE er.from_currency = accounts.currency
|
||||
AND er.to_currency = :target_currency
|
||||
AND er.date > d.date
|
||||
ORDER BY er.date ASC
|
||||
LIMIT 1)
|
||||
) AS rate
|
||||
) er ON TRUE
|
||||
WHERE accounts.id = ANY(array[:account_ids]::uuid[])
|
||||
GROUP BY d.date
|
||||
|
||||
Reference in New Issue
Block a user