fix: credit-note overdue countdown + voucher sequence resync after SIE import (#1069)

* fix(invoices): hide overdue countdown for credit notes in invoice list

Credit notes stay in status 'sent' forever (invoices_credit_note_not_paid
blocks paid states), so the relative due-date label rendered an ever-growing
'X dagar forsenad' on every issued credit note. Skip the label for rows with
credited_invoice_id set.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(bookkeeping): resync voucher_sequences counters left behind by pre-RPC SIE imports

The batch SIE import path that predated import_sie_journal_entries
(20260712150000) inserted vouchers with explicit numbers but never
updated voucher_sequences, leaving counters behind max (year-end
integrity error, duplicate-key crash on the next voucher) or missing
entirely (next_voucher_number restarts at 1 and collides). Idempotent
data repair: raise lagging counters to the observed max and insert
missing rows attributed to the company owner. Already applied to prod
and staging; replay is a no-op.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(bookkeeping): harden voucher-sequence resync per PR review

Address PR #1069 review findings: close the ON CONFLICT race by
upgrading DO NOTHING to DO UPDATE with GREATEST (a row created by
next_voucher_number between snapshot and insert is raised instead of
left at 1), unify the voucher_number > 0 filter across both statements,
and record the manual prod/staging execution timestamps as the change
record (ISO 27001 A.8.32, BFNAR 2013:2 behandlingshistorik).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Mattsson
2026-07-19 13:35:52 +02:00
committed by GitHub
co-authored by Claude Fable 5
parent 9c8e540338
commit ebf69d2933
3 changed files with 71 additions and 1 deletions
+3 -1
View File
@@ -282,7 +282,9 @@ export default function InvoicesPage() {
!invoice.is_self_billed
const statusLabelKey = isUnsentInvoice ? 'status_unsent' : status.labelKey
const statusVariant: InvoiceStatusVariant | 'outline' = isUnsentInvoice ? 'outline' : status.variant
const relativeTime = invoice.due_date ? getRelativeTimeLabel(invoice.due_date, invoice.status) : null
// Credit notes are never payable (invoices_credit_note_not_paid),
// so a due-date countdown ("X dagar försenad") is meaningless for them.
const relativeTime = invoice.due_date && !isCreditNote ? getRelativeTimeLabel(invoice.due_date, invoice.status) : null
const displayedTotal = getDisplayTotal(
{ total: Number(invoice.total), currency: invoice.currency, ore_rounding: invoice.ore_rounding },
{ ore_rounding: oreRounding },