feat(reconciliation): propose the explaining voucher set for a bank row before offering Bokför (#2359)

* feat(reconciliation): propose the explaining voucher set for a bank row before offering Bokför (#2293)

The bridge table said "ej matchad" and steered to Bokför when a Bankgirot
aggregate was already booked as two or three unlinked vouchers. The booking
doors have refused that double booking since #2300 and #2346 with
detectExplainingVoucherSet; the view never ran it.

- duplicate-payment-detection: split the set detector into fetch and pure
  steps and add detectExplainingVoucherSets, the batch form (one ledger
  scan, one anchor lookup, per-row verdict identical to the single
  detector; a voucher explains at most one row per call). ExplainingVoucher
  now also carries voucher_series and voucher_number.
- reconciliation/covering-set-candidate (new): maps sets to proposals
  (0.95 same date, 0.85 within seven days), SEK accounts only, fails open.
- items: open bank rows nothing explains 1:1 are searched before they land
  in unmatched_external; a hit lands in proposed with proposal.vouchers.
- schemas: ReconciliationProposal.vouchers (optional, set proposals only).
- AccountOverview: "= A57 + A58" with the legs' amounts, one Koppla that
  posts every voucher as a 1:N pair to the existing links route.
- i18n: reconciliation.proposal_set_title and proposal_set_same_day (sv, en).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LvMaHcTnwAfxzgYD1fGYX1

* chore(skill): regenerate accounted-api for ReconciliationProposal.vouchers (#2293)

The set proposal field added to the reconciliation items response shape
flows into the generated agent skill; regenerated with
`npm run apiskill:generate`, which changes one line of references/banking.md.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LvMaHcTnwAfxzgYD1fGYX1

---------

Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-09-06 21:03:42 +02:00
committed by GitHub
co-authored by Claude Fable 5.1 Jakob Wennberg
parent fcda4a75dd
commit 6776cb4fc6
12 changed files with 1055 additions and 163 deletions
+3 -1
View File
@@ -8124,7 +8124,9 @@
"manual_spec_hint": "The specification comes from the system: {label}. The difference should be zero before you sign; otherwise sign with a note.",
"signoff_external_balance": "Balance per supporting documents",
"signoff_external_balance_help": "Same sign as in the books, liabilities with a minus. Booked: {amount}.",
"signoff_external_balance_optional": "Leave empty to sign with a note only."
"signoff_external_balance_optional": "Leave empty to sign with a note only.",
"proposal_set_title": "{count} vouchers that together make up the amount",
"proposal_set_same_day": "same day"
},
"skattekonto": {
"help_text": "The balance and events are fetched from Skatteverket and synced automatically every night. Completed events are booked against 1630 Skattekonto, usually automatically; anything that cannot be matched is flagged in the list. Pay in via bankgiro 5050-1055 with your OCR number.",
+3 -1
View File
@@ -8124,7 +8124,9 @@
"manual_spec_hint": "Specifikationen kommer från systemet: {label}. Differensen ska vara noll innan du signerar, annars signerar du med en notering.",
"signoff_external_balance": "Saldo enligt underlag",
"signoff_external_balance_help": "Samma tecken som i bokföringen, skulder anges med minus. Bokfört: {amount}.",
"signoff_external_balance_optional": "Lämna tomt om du bara vill signera med en notering."
"signoff_external_balance_optional": "Lämna tomt om du bara vill signera med en notering.",
"proposal_set_title": "{count} verifikat som tillsammans ger beloppet",
"proposal_set_same_day": "samma dag"
},
"skattekonto": {
"help_text": "Saldot och händelserna hämtas från Skatteverket och synkas automatiskt varje natt. Genomförda händelser bokförs mot 1630 Skattekonto, oftast automatiskt; det som inte kan matchas flaggas i listan. Betala in via bankgiro 5050-1055 med ditt OCR-nummer.",