diff --git a/apps/edr-freight-web/backoffice/src/pages/invoices/InvoicesPage.tsx b/apps/edr-freight-web/backoffice/src/pages/invoices/InvoicesPage.tsx index 2b319de30..085556f9d 100644 --- a/apps/edr-freight-web/backoffice/src/pages/invoices/InvoicesPage.tsx +++ b/apps/edr-freight-web/backoffice/src/pages/invoices/InvoicesPage.tsx @@ -235,8 +235,33 @@ export default function InvoicesPanel() { const { data: exchangeSettings } = useExchangeSettingsQuery(); const etbCollected = summary?.ETB ?? 0; const usdCollected = summary?.USD ?? 0; - const rate = exchangeSettings?.feed?.rate ?? exchangeSettings?.fallbackRate; - const etbFromUsd = rate ? usdCollected * rate : null; + const djfCollected = summary?.DJF ?? 0; + + /** Live rate when CBE is answering, this currency's stored fallback when it is not. */ + const rateFor = (code: string): number | null => + exchangeSettings?.feed?.rates?.[code] ?? + exchangeSettings?.currencies.find((c) => c.currency === code)?.fallbackRate ?? + null; + + // Every non-birr currency converted into birr, so one headline figure covers the whole + // book. A currency with no usable rate is left OUT of the total rather than added at + // face value — silently treating 1 DJF as 1 ETB would overstate it ~100x. + const foreign = [ + { code: "USD", amount: usdCollected }, + { code: "DJF", amount: djfCollected }, + ] + .filter((row) => row.amount > 0) + .map((row) => ({ ...row, rate: rateFor(row.code) })); + + const convertible = foreign.filter( + (row): row is typeof row & { rate: number } => (row.rate ?? 0) > 0, + ); + const etbFromForeign = convertible.reduce( + (sum, row) => sum + row.amount * row.rate, + 0, + ); + const totalHint = ["ETB", ...convertible.map((r) => r.code)].join(" + "); + const unconverted = foreign.length - convertible.length; const columns: ColumnDef[] = useMemo( () => [ @@ -356,8 +381,11 @@ export default function InvoicesPanel() { items={[ { label: "Total collected", - hint: etbFromUsd !== null ? "ETB + USD" : "ETB only", - value: formatMoney(etbCollected + (etbFromUsd ?? 0), "ETB"), + hint: + unconverted > 0 + ? `${totalHint} — ${unconverted} currency without a rate excluded` + : totalHint, + value: formatMoney(etbCollected + etbFromForeign, "ETB"), icon: CircleDollarSign, color: "edr-green", }, @@ -373,6 +401,12 @@ export default function InvoicesPanel() { icon: Landmark, color: "violet", }, + { + label: "Collected in DJF", + value: formatMoney(djfCollected, "DJF"), + icon: Landmark, + color: "grape", + }, ]} />