* feat(supplier-invoices): sarskild loneskatt (SLP) pair on pension premium lines
Booking a tjanstepension invoice (e.g. Avanza) needs the buyer's own SLP
beyond the payable: debit 7533 / credit 2514 at 24.26% of the premium
(SLF 1991:687). The item-based debit-only form could not express the
self-balancing pair, so users had to hand-edit the verifikat.
- new leaf module lib/bookkeeping/slp-lines.ts: SLP_RATE (single source,
re-exported by the bokslut calculator), isSlpPensionAccount (741x),
generateSlpLines (7533 D / 2514 K, nets to zero)
- migration adds supplier_invoice_items.apply_slp boolean default false
- registration, cash, and privately-paid generators inject the pair for
flagged 741x items, mirroring the reverse-charge injection; the balance
guarantees keep 2440/1930/2893 at exactly the invoice total; the credit
note generator reverses the pair (7533 K / 2514 D)
- privately-paid balance guarantee now subtracts existing credits so the
SLP 2514 leg never inflates the owner account
- schema field apply_slp + guards in all create paths (main route, inbox
convert, v1 REST, pending-operations executor): 400
SI_CREATE_SLP_INVALID_ACCOUNT on non-741x accounts, 400
SI_CREATE_SLP_ACCRUAL combined with periodisering
- form: advisory hint on unflagged 741x rows with one-click opt-in and a
quiet confirmation line when applied; totals box untouched (the invoice
total stays the payable); AB review preview injects the same pair via
the same generator for parity
- year-end double-count guard: calculateSarskildLoneskatt subtracts SLP
already posted to 7533 during the year (floored at zero) so bokslut
never provisions flagged premiums twice
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* chore(api-skill): regenerate suppliers reference for apply_slp
The apiskill:check CI gate requires the generated accounted-api skill to
stay in sync with the endpoint registry after the apply_slp addition.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(slp): carry apply_slp through v1 routes, MCP staging, preview and credit reversal
Review findings on the SLP PR:
- v1 credit route: SI_FULL_COLUMNS now projects items.apply_slp, so
createSupplierCreditNoteEntry sees the flag and reverses the 7533/2514
pair booked at registration (it previously stood forever and the
year-end netting under-provisioned). The flag is also copied onto the
created credit-note items for parity with the web credit route.
- v1 mark-paid: the items sub-select now includes apply_slp, so a
kontantmetoden payment via v1 books the cash entry WITH the SLP pair,
matching the web mark-paid.
- v1 GET ?expand=items: SI_ITEM_COLUMNS includes apply_slp so the flag
is readable back through the public API.
- credit-note SLP base is abs of the SIGNED sum of flagged line_totals,
not per-item abs: a mixed-sign flagged original (+10000/-2000) booked
SLP on 8000 at registration and now reverses exactly that, not 12000.
The expense-bucket per-item abs convention is untouched.
- kontantmetod bank-match preview appends the same generateSlpLines pair
the POST books, so the approved lines equal the committed lines.
- MCP gnubok_create_supplier_invoice_from_inbox: line_overrides accepts
apply_slp (optional boolean), plumbs it into the staged operation's
items, and rejects non-741x resolved accounts at staging time with the
bilingual SI_CREATE_SLP_INVALID_ACCOUNT texts.
- DECISIONS.md: five entries for today's decisions.
Every behavioral fix has a test verified to fail without it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>