* fix(vat): map 3231-3233 to ruta 41 in the momsdeklaration
Ruta 41 (försäljning när köparen är betalningsskyldig i Sverige) existed
in the type, the eSKD file and the Skatteverket mapper, but no account
could ever reach it: 3231-3233 were deliberately parked in
RUTA_05_EXCLUDED_ACCOUNTS, so byggmoms/omvänd-skattskyldighet sales
vanished from the declaration entirely. Map them statically in
ACCOUNT_RUTA and ACCOUNT_TO_BOX; the ACCOUNT_TO_BOX guard now keeps them
out of the dynamic ruta 05 set instead of the exclusion list. RC sales
carry no output VAT, so they stay out of the ruta 05-08 vs 10-12
pairing checks, pinned by test.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: record the ruta 41 static-mapping decision
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>
Em dashes (—) and en dashes (–) had spread across comments, docs, tests,
and a few UI strings, reading as AI-generated boilerplate rather than
house style. Replaced each with punctuation matching its context: colon
for explanatory clauses, comma for asides, plain hyphen for numeric/legal
ranges (e.g. "21-23§"), "to"/"till" for date ranges, parentheses for
paired-dash asides. messages/en.json and messages/sv.json were fixed by
hand together to keep sv/en in sync.
Left untouched where the dash is the functional subject rather than
decorative punctuation: date-range-parser.ts's separator regex,
charset-repair.ts's CP1252 byte-mapping table (and its test), the SIE
encoding mojibake docs, generic-csv.ts's minus-sign normalizer, the
agent system-prompt files that already instruct against em dashes, and
a golden iXBRL test fixture compared byte-for-byte.
Also fixes two bugs surfaced along the way: an off-by-one in
ApiKeysPanel's scope-label split (a leftover from an earlier partial
pass), and a charset-repair test that had lost the literal en-dash it
exists to verify.
Regenerated the agent atom seed migration (skills:generate) since 27
SKILL.md files changed. Added a CLAUDE.md rule against em/en dashes,
with an explicit carve-out for the functional-dash cases above.
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
* feat(settings): add option for company name position in invoice PDF
* feat(migrations): add backfill for VAT account labels to correct bad seed data
* feat(migrations): add backfill for VAT account labels to correct bad seed data
* fix(ui): improve accessibility for company name position toggle in PDF settings
* fix(bookkeeping): align BAS 2026 reference data with official PDF
Reconciled lib/bookkeeping/bas-data/ against the BAS 2026 v1.1 official
chart (1286 accounts). All real discrepancies fixed:
- 2089 Fond för utvecklingsutgifter: k2_excluded → true
- 8417 Räntekostnader för dold räntekompensation: k2_excluded → true
- 1250, 1260 renamed to "(Fritt konto för Inventarier, verktyg och
installationer)" — BAS 2026 freed these slots
- Periodiseringsfond 2120-2139: added year suffixes (2120 = "...2020"
etc.) and added 8 missing accounts (2121-2127, 2129) for years
2019, 2021-2027. Dropped phantom 2022/2024 prior-parser garbage.
- 4075-4078: EUland → EU-land
- 8411: förlagsoch → förlags- och
Verified: 1282 of 1286 PDF accounts match exactly after edits (remaining
4 are PDF-parser artifacts, not real data). Build clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(migrations): backfill BAS 2026 account labels in chart_of_accounts
Companion to the TS reference fix. Updates existing companies' rows where
they still carry seed-data typos or generic names that don't match BAS 2026:
- 4075-4078: EUland → EU-land (hyphenation)
- 8411: förlagsoch → förlags- och (hyphenation)
- 2120, 2130-2137, 2139: rename "Periodiseringsfond" (generic, no year) to
the BAS 2026 canonical name with year suffix
Defensive: every WHERE clause matches an EXACT current value. Rows that
have been manually renamed by users — including those with a wrong year
that may reference legacy fonds from an earlier BAS numbering cycle — are
left untouched. No row is deleted.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(migrations): fix wrong-year labels on Periodiseringsfond accounts
Follow-up to 20260513140000. The first backfill only renamed accounts whose
name was the generic "Periodiseringsfond" (no year). Many customers were
seeded from an older BAS numbering cycle where 2126 = "2016", 2127 = "2017",
etc. — BAS 2026 reuses those account numbers for years 2026/2027.
This migration aligns the year tag with the BAS 2026 meaning of each
account number across 2120-2127, 2129, 2130-2137, 2139. Only rows whose
name still starts with "Periodiseringsfond" are touched — customers who
renamed the account to something custom keep their name.
Verified on staging: all 18 accounts now carry BAS 2026 canonical names.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(data): update account names and descriptions for clarity and consistency
* fix(migrations): backfill account names for BAS 2026 freed accounts and refine Periodiseringsfond name matching
* feat: enhance VAT handling with reverse charge logic and supplier type support
* feat: implement VAT declaration validation rules and enhance moms box mapping
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>