""" Dual-currency dashboard figures. The AR Ledger shows every movement in the marketplace's local currency AND in USD, converted at each TRANSACTION DATE's exchange rate (a daily override when one exists, the marketplace month rate otherwise). The opening balance has no transaction date, so it converts at the month rate. Also the regression for the fx-daily endpoint: after payouts moved out of _daily_rows into _payout_events, fx_daily still unpacked 4-tuples and crashed on every session with data — the "Daily exchange rates" table never rendered. Fixture dates (make_amazon_xlsx, USA, month-end 2026-01-31, lag 2 → cutoff Jan 29): revenue: Jan 5 +1000 · Jan 10 +300 · Jan 15 +2000 · Jan 20 +80 · Jan 31 +500 payouts: Jan 6 −1000 (received) · Jan 12 −300 (received) · Jan 30 −2000 (in transit) → closing = 3880 − 1300 = 2580 """ from __future__ import annotations from fastapi.testclient import TestClient from app.api.main import app from app.db.database import init_db from tests.test_payout_receipts import _fresh def test_fx_daily_no_longer_crashes_and_covers_payout_dates(): init_db() with TestClient(app) as c: sid = _fresh(c, "fx daily regression") r = c.get(f"/api/sessions/{sid}/fx-daily") assert r.status_code == 200 data = r.json() assert data["available"] is True by_date = {row["date"]: row for row in data["rows"]} # Revenue sits on its transaction date… assert by_date["2026-01-15"]["revenue"] == 2000.0 # …and payouts on their effective date, in the same table. assert by_date["2026-01-06"]["payouts"] == -1000.0 assert by_date["2026-01-30"]["payouts"] == -2000.0 # USA converts 1:1 — USD total equals local total = 3880 − 3300 net movement. assert data["month_rate"] == 1.0 assert data["total_local"] == 580.0 assert data["total_usd"] == data["total_local"] def test_ledger_detail_shows_usd_at_transaction_date_rates(): init_db() with TestClient(app) as c: sid = _fresh(c, "dual currency ledger") # Daily override for the big revenue day; every other date uses the month rate. assert c.put(f"/api/sessions/{sid}/fx-daily", json=[ {"marketplace": "USA", "rate_date": "2026-01-15", "rate": 1.25}, ]).status_code == 200 d = c.get(f"/api/sessions/{sid}/ledger-detail").json() per = {p["key"]: p for p in d["periods"]} # Jan 15's revenue converts at ITS OWN day's rate… assert per["2026-01-15"]["revenue"] == 2000.0 assert per["2026-01-15"]["revenue_usd"] == 2500.0 # …every other date at the month rate (1.0 for USA). assert per["2026-01-05"]["revenue_usd"] == per["2026-01-05"]["revenue"] == 1000.0 assert per["2026-01-06"]["payouts_received_usd"] == -1000.0 assert per["2026-01-30"]["payouts_in_transit_usd"] == -2000.0 # Opening has no transaction date → month rate; the USD running balance then # absorbs the daily-rate spread: closing_usd = closing + 2000 × (1.25 − 1). assert d["month_rate"] == 1.0 assert d["opening_usd"] == 0.0 assert d["closing"] == 2580.0 assert d["closing_usd"] == 3080.0 assert d["in_transit_total_usd"] == -2000.0 # The local-currency figures are untouched by the daily override. assert per["2026-01-15"]["balance"] == per["2026-01-15"]["balance_usd"] - 500.0