fix(ui): stop mislabeling unconverted FX amounts as kr in aggregates and toasts (#1182)

Fixes #1173. invoices.total_sek stays NULL when the Riksbanken rate
fetch fails at creation, and every `total_sek || total` fallback then
treated a raw foreign amount as kronor:

- lib/calendar/utils: new invoiceSekAmount() returns null for
  unconverted non-SEK invoices; period summaries and day totals skip
  them and PeriodSummary exposes unconvertedCount. PaymentSummaryCard
  shows a one-line note when invoices were excluded; CalendarDayView
  renders each invoice in its own currency instead.
- Deadlines page: the overdue attn sum now skips unconverted FX
  invoices and appends "(+N i utlandsk valuta)" instead of adding EUR
  into a kr total.
- Supplier-invoice payment toast formats the amount with the invoice's
  currency (key drops its hardcoded " kr" in both locales).
- AR aging drill-down row labels Betalt with the invoice currency,
  mirroring the outstanding cell.
- BankFileColumnMappingStep: comment pinning why SEK is safe there
  (generic-csv hardcodes it).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-07-25 12:59:14 +02:00
committed by GitHub
co-authored by Claude Fable 5
parent 6d5a435ed9
commit aead2bc1d1
10 changed files with 133 additions and 21 deletions
@@ -22,6 +22,17 @@ interface CalendarDayViewProps {
onAddDeadline: (date: Date) => void
}
// Per-invoice amount label. Shows the SEK conversion when one exists;
// otherwise the invoice's own amount in its own currency: total_sek is NULL
// for non-SEK invoices whose rate fetch failed, and labelling the raw foreign
// amount "kr" would misstate it.
function invoiceAmountLabel(invoice: Invoice): string {
if (invoice.total_sek != null || !invoice.currency || invoice.currency === 'SEK') {
return `${(invoice.total_sek ?? invoice.total).toLocaleString('sv-SE')} kr`
}
return `${invoice.total.toLocaleString('sv-SE')} ${invoice.currency}`
}
export function CalendarDayView({
date,
invoices,
@@ -105,7 +116,7 @@ export function CalendarDayView({
)}
</div>
<div className="text-xs text-muted-foreground">
{invoice.customer?.name} • {(invoice.total_sek || invoice.total).toLocaleString('sv-SE')} kr
{invoice.customer?.name} • {invoiceAmountLabel(invoice)}
</div>
</div>
</div>
@@ -132,7 +143,7 @@ export function CalendarDayView({
</span>
</div>
<div className="text-xs text-muted-foreground">
{invoice.customer?.name} • {(invoice.total_sek || invoice.total).toLocaleString('sv-SE')} kr
{invoice.customer?.name} • {invoiceAmountLabel(invoice)}
</div>
</div>
</div>
@@ -92,6 +92,16 @@ export function PaymentSummaryCard({ invoices, year, month }: PaymentSummaryCard
</p>
</div>
)}
{/* Foreign-currency invoices without a stored SEK conversion are
excluded from the sums above rather than silently mixed in. */}
{summary.unconvertedCount > 0 && (
<p className="text-xs text-warning">
{summary.unconvertedCount === 1
? '1 faktura i utländsk valuta utan växelkurs ingår inte i beloppen.'
: `${summary.unconvertedCount} fakturor i utländsk valuta utan växelkurs ingår inte i beloppen.`}
</p>
)}
</CardContent>
</Card>
)