Files
accounted/lib/bookkeeping/__tests__/bas-ef-equity-accounts.test.ts
T
5b9605d8e9 fix(packs): repair the four broken system templates the validator found (#1388)
Phase 2a quarantined four defects rather than guessing at Swedish accounting.
Each is now resolved against a domain source. KNOWN_BROKEN is empty.

Löneutbetalning could never post. It debited 2710 @0.3 + 2920 @0.12 + 7010 @1.0
against a single 1.0 credit, totalling 1.42x the amount, so the balance trigger
would reject every entry built from it. Rebuilt per the swedish-payroll skill:
Debit 7010 gross, Credit 2710 tax, Credit 1930 net. The 2920 semesterlöneskuld
line is gone because vacation accrual is its own verifikat (7290/2920), and a
legal_note now says the 30% split is schablon and must be adjusted to the actual
skatteavdrag.

Periodiseringsfond avsättning/återföring referenced account 2113. Per
swedish-year-end-closing the year-tagged block is 2120-2129 (2126 = tax year
2026), so 2113 was the fund for tax year 2013: long since reversed and absent
from BAS 2026. Both now use 2110 Periodiseringsfonder, which does not rot
annually, with a legal_note pointing at the year-tagged accounts for a company
that tracks funds per year.

Preliminär F-skatt (EF) turned out to be RIGHT, and the reference was wrong.
Account 2012 "Avräkning för skatter och avgifter" was simply missing from
lib/bookkeeping/bas-data (the file jumps 2011 -> 2013), while the
swedish-year-end-closing skill uses it in two places as an enskild firma equity
sub-account. That is not cosmetic: account-backfill.ts only seeds accounts
present in BAS_REFERENCE, so any entry touching 2012 failed with
AccountsNotInChartError. Added it with the equity SRU code its siblings share,
and a description separating it from 1630, which carries a confusingly similar
name on the asset side.

The port test now distinguishes deliberate divergence from accidental drift:
a pack not listed in INTENTIONAL_DIVERGENCES must still match the seeded JSONB
exactly, and a listed pack must actually differ, so neither an unnoticed edit
nor a stale entry can survive.

Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 18:46:55 +02:00

55 lines
2.4 KiB
TypeScript

import { describe, it, expect } from 'vitest'
import { getBASReference } from '@/lib/bookkeeping/bas-reference'
/**
* The enskild firma equity block must be complete.
*
* 2012 was missing from the reference, which is not cosmetic:
* `lib/bookkeeping/account-backfill.ts` only seeds accounts that appear in
* BAS_REFERENCE, so an account absent from it can never be added to a company's
* chart on demand. Any entry touching 2012 failed with AccountsNotInChartError,
* which is exactly what the "Preliminär F-skatt (EF)" template did.
*
* The gap was found by the pack validator asserting that every account a
* template references exists in BAS 2026.
*/
describe('enskild firma equity accounts (20xx)', () => {
it('has no hole in the 2010-2013 run', () => {
for (const account of ['2010', '2011', '2012', '2013']) {
expect(getBASReference(account), `${account} missing from BAS reference`).toBeDefined()
}
})
it('2012 is the owner-tax equity account, distinct from the 1630 skattekonto asset', () => {
const equity = getBASReference('2012')
const skattekonto = getBASReference('1630')
expect(equity?.account_type).toBe('equity')
expect(equity?.normal_balance).toBe('debit')
// Both are called "avräkning", which is precisely why they get confused.
expect(skattekonto?.account_type).toBe('asset')
expect(equity?.account_number).not.toBe(skattekonto?.account_number)
})
it('shares the equity SRU code with its siblings, since they all net into 2010', () => {
const siblings = ['2011', '2012', '2013', '2018'].map((a) => getBASReference(a)?.sru_code)
expect(new Set(siblings).size).toBe(1)
expect(siblings[0]).toBe(getBASReference('2010')?.sru_code)
})
})
describe('periodiseringsfond accounts', () => {
it('offers the generic account plus the year-tagged block', () => {
expect(getBASReference('2110')?.account_name).toContain('Periodiseringsfond')
// 2120-2129 are year-tagged (2126 = tax year 2026).
expect(getBASReference('2126')?.account_name).toContain('2026')
})
it('does not carry 2113: the pre-2020 year-tagged funds are long reversed', () => {
// The seeded "Periodiseringsfond" templates referenced 2113 (tax year 2013),
// so they could never resolve. Pinning this prevents a well-meaning
// "fix" that re-adds an obsolete account instead of correcting the template.
expect(getBASReference('2113')).toBeUndefined()
})
})