A self-billed invoice has invoice_number null by design (the counterparty's
number lives in external_invoice_number), which broke the whole credit flow:
the confirm input was disabled and compared against null, the API minted the
literal number 'KR-null', and the credit-note PDF dropped its ML 17 kap 22
reference to the original. The editor also hid fakturadatum inside the
collapsed Forval panel, so self-billed invoices silently registered with
today's date and, being immutable, could not be corrected.
- creditConfirmNumber() falls back to external_invoice_number; the credit
page uses it for reason default, subtitle, original row, preview, confirm
label/placeholder/disabled, mismatch check and submit gate
- createCreditNote numbers 'KR-<external>' for self-billed originals and
refuses with typed 400 INVOICE_CREDIT_NO_NUMBER when no number exists
- mark-sent and send select external_invoice_number and fall back for the
credit-note PDF's reference to the original
- the Forval chip line now shows the invoice date in every mode, and
self-billed mode renders fakturadatum + mottagningsdatum uncollapsed as
transcription fields next to the external number
Fixes#1820
Claude-Session: https://claude.ai/code/session_01SyDuePXxUFowaPBKpAv8SF
Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* fix: article number ordering, free-text rows, invoice back-nav, onboarding resilience (#1053)
Four fixes from Discord feedback in issue #1053:
- Articles now order by article number with numeric-aware comparison
('2' before '10', unnumbered last, name tiebreak) in the invoice
editor's article picker and as the register's default sort, via a
shared lib/articles/sort.ts. Name order put article "1" last.
- Invoice rows with no amounts (quantity 0, unit price 0) render as
pure text rows on the PDF, the invoice detail page, and the review
step via shared isTextLikeLine(), instead of printing
"0 / 0,00 SEK / 0,00 SEK". Display-only; booking untouched.
- The invoice editor navigates with router.replace after saving, so
the detail page's back arrow returns to the list instead of
reopening a fresh editor from history.
- A transient query failure no longer reads as "no companies" /
"onboarding not done": getActiveCompanyId throws
CompanyContextError('resolution_failed') instead of returning null,
the Edge middleware fails open on a degraded resolution (no
onboarding redirect, no cookie clearing, no locale overwrite), and
the dashboard page only redirects to /onboarding on a positively
read incomplete/missing settings row. This is the likely cause of
the completed onboarding wizard reappearing.
Fixes#1053
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: CLAUDE.md tenancy line matches actual resolution order (prefs-first, cookie not read)
The middleware stopped reading the gnubok-company-id cookie when
user_preferences became authoritative (RLS parity); the stale doc line
still described cookie-first order and misled review tooling.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>