fix(dimensions): exempt system source types from account dimension rules (#888)

SIE import books three system entries through the engine (opening
balances, IB resynk, the omföring adjustment for excluded vouchers) —
after PR10 those passed through the rules layer, so a required rule
could block an import and default/fixed rules could inject dimensions
into derived historical entries. Year-end, currency revaluation and
credit instruments had the same exposure.

Policy now governs NEW business events only: source types in
DIMENSION_RULE_EXEMPT_SOURCE_TYPES (opening_balance, import, year_end,
storno, correction, credit_note, supplier_credit_note,
currency_revaluation, system) skip both the draft-time apply and the
commit-time assert — imported history lands verbatim (BFL 5 kap),
bokslut can never be blocked by a dimension rule, and crediting an
entry that pre-dates a rule always works. Operational sources (manual,
bank_transaction, invoice_*, supplier_* registrations/payments,
salary_payment) stay enforced.

The SIE round-trip test now also covers a PR10-created custom dimension
(#DIM 20) with a custom child (#UNDERDIM 25 ... 20) and a tagged line —
proving user-created dims survive export → parse structurally.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-07-03 17:17:16 +02:00
committed by GitHub
co-authored by Claude Fable 5
parent 764348e99c
commit 86c924a6e9
4 changed files with 130 additions and 9 deletions
@@ -54,14 +54,26 @@ const SOURCE_SIE = [
'#DIM 1 "Kostnadsställe"',
'#DIM 6 "Projekt"',
'#UNDERDIM 2 "Kostnadsbärare" 1',
// Custom dimension + custom child — exactly what PR10's "Ny dimension"
// (SIE 20+, optional parent) produces. Proves the round-trip covers
// user-created dims, not just the reserved 1/2/6 set.
'#DIM 20 "Avdelning"',
'#UNDERDIM 25 "Team" 20',
'#OBJEKT 1 "KS01" "Butiken"',
'#OBJEKT 2 "KB1" "Bärare ett"',
'#OBJEKT 6 "P001" "Villa Almgren"',
'#OBJEKT 20 "SYD" "Avdelning Syd"',
'#OBJEKT 25 "T1" "Team ett"',
'#VER A 1 20260115 "Hyra januari"',
'{',
'#TRANS 5010 {1 "KS01" 2 "KB1" 6 "P001"} 15000.00',
'#TRANS 1930 {} -15000.00',
'}',
'#VER A 3 20260117 "Avdelningskostnad"',
'{',
'#TRANS 5010 {20 "SYD" 25 "T1"} 800.00',
'#TRANS 1930 {} -800.00',
'}',
'#VER A 2 20260116 "Odeklarerat projekt"',
'{',
// P002 is referenced but never declared via #OBJEKT — import synthesizes