fix(skattekonto): route AGI draw back to 2731 to match salary module (#1905)
* fix(skattekonto): route AGI draw back to 2731 to match salary module (#1870) Migration 20260519160000 moved the skattekonto AGI seed to 2730 while the salary module kept crediting 2731, splitting the employer-contribution liability across two accounts that never net at account level (both carry SRU 7231, so only huvudbok reconciliation exposes the drift). Revert the system seed to 2731: BAS 2026 defines 2731 as the reported-but-unpaid arbetsgivaravgift liability (the accrual account is 2940), and the salary ore-residual logic is built around 2731. Historical 2730 debits since 2026-05-19 are left for per-company reclass verifikat; the migration touches the system seed only. Fixes #1870 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(skattekonto): bump migration version to avoid collision with 20260825120000_create_company_for_user Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(payroll): align remaining 2730 guidance surfaces on 2731 (#1870) Skeptic regression finding: companies booking salary manually were taught 7510/2730 by in-product guidance, so the seed revert alone would re-create the #1870 split mirrored for them. Align every guidance surface on 2731: - packs/loneutbetalning.yaml legal_note - MCP payroll-monthly skill (booking recipe and rate notes) - swedish-payroll SKILL.md + references/bas-7xxx.md (2731 convention, 2730 group-account alternative, never mixed; accrual is 2940) + regenerated agent atom seed (skills:generate -> 20260825180001) - public/docs/systemdokumentation-mall.md Also addresses the compliance review finding that the swedish-payroll skill contradicted the migration. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
a82328da84
commit
436cbf5304
@@ -52,7 +52,7 @@ Variable lines (overtime, weekend supplement, milage, traktamente, förmåner) a
|
||||
- **Skatteavdrag**: tax-table lookup (skattetabell + kolumn → table column for the gross level)
|
||||
- **Nettolön** (net): bruttolön − skatteavdrag
|
||||
- **Sociala avgifter (arbetsgivaravgifter)**: 31.42 % of bruttolön (standard 2025). Reduced rates apply to specific age groups: always check the current statutory rates before relying on these:
|
||||
- **Born 1937 or earlier**: **0 %**: no avgifter at all (oldest cohort, never paid into the modern pension system). Easy to miss; the BAS journal entries for 7510/2730 simply don't apply for these employees.
|
||||
- **Born 1937 or earlier**: **0 %**: no avgifter at all (oldest cohort, never paid into the modern pension system). Easy to miss; the BAS journal entries for 7510/2731 simply don't apply for these employees.
|
||||
- **Age 66+ on 1 January of the income year (67+ from income year 2026)**: 10.21 % (only ålderspensionsavgift). The threshold rises with the riktålder; verify the cohort year for the current run rather than hard-coding a birth year.
|
||||
- **växa-stöd / temporary youth reduction**: ages 19-23, salary ≤ 25 000 SEK/month, capped duration. The exact rate and window vary year-over-year (e.g. 20.81 % during 1 Apr 2026: 30 Sep 2027 per Prop. 2025/26:34): confirm against Skatteverket's current published table before applying.
|
||||
- **Semesterlöneskuld** (vacation accrual): 12 % of bruttolön (default). Booked monthly to 2920.
|
||||
@@ -73,11 +73,11 @@ Errors at this stage usually mean missing tax-table data: fall back to \`getDefa
|
||||
- Debit **7210** (lön tjänstemän) or **7010** (lön arbetare): bruttolön
|
||||
- Debit **7510** (sociala avgifter): \`avgift_base × applicable_rate\`: **per employee**, using the rate from Step 4 (default 31.42 %, or a reduced rate when applicable: 10.21 % for 66+, växa-stöd, etc.)
|
||||
- Credit **2710** (källskatt): skatteavdrag
|
||||
- Credit **2730** (lagstadgade arbetsgivaravgifter): same amount as the 7510 debit (the avgift cost is the same number as the avgift liability)
|
||||
- Credit **2731** (avräkning lagstadgade sociala avgifter): same amount as the 7510 debit (the avgift cost is the same number as the avgift liability). 2731 is what the engine books and what the skattekonto AGI draw debits; crediting the group account 2730 instead splits the liability across two accounts (issue #1870)
|
||||
- Credit **2920** (semesterlöneskuld): 12 % × bruttolön (debit 7290 to balance)
|
||||
- Credit **1930** (bank): nettolön (when paid)
|
||||
|
||||
When a run mixes full-rate and reduced-rate employees, the 7510/2730 lines are summed across all employees: the *total* avgift line equals \`Σ(per-employee avgift_base × per-employee rate)\`, **not** \`Σ bruttolön × 31.42 %\`. \`gnubok_calculate_salary_run\` already does this aggregation.
|
||||
When a run mixes full-rate and reduced-rate employees, the 7510/2731 lines are summed across all employees: the *total* avgift line equals \`Σ(per-employee avgift_base × per-employee rate)\`, **not** \`Σ bruttolön × 31.42 %\`. \`gnubok_calculate_salary_run\` already does this aggregation.
|
||||
|
||||
### Step 7: Generate AGI
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ const SEED_RULES = [
|
||||
{
|
||||
id: 'sys-4', priority: 20, pattern: 'arbetsgivaravgift,sociala avgifter,agi',
|
||||
amount_min: null, amount_max: null, company_type: 'all',
|
||||
counter_account: '2730', counter_account_ef: null,
|
||||
counter_account: '2731', counter_account_ef: null,
|
||||
label: 'Arbetsgivaravgifter', active: true, requires_employer: false,
|
||||
},
|
||||
{
|
||||
@@ -135,17 +135,19 @@ describe('guessCounterAccount', () => {
|
||||
).toBe('2013')
|
||||
})
|
||||
|
||||
it('routes employer payroll taxes to 2730 (clearing/redovisningskonto, not 2731 accrual)', async () => {
|
||||
// 2731 matches the salary module's AVGIFTER_LIABILITY credit so the SKV draw
|
||||
// clears the same account (issue #1870); the accrual account is 2940, not 2731.
|
||||
it('routes employer payroll taxes to 2731 (same account the salary module credits)', async () => {
|
||||
const { supabase, enqueue } = makeSupabase()
|
||||
enqueue({ data: SEED_RULES })
|
||||
expect(
|
||||
(await guessCounterAccount(supabase as unknown as SupabaseClient, 'company-1', 'Arbetsgivaravgifter januari', 'aktiebolag'))?.account,
|
||||
).toBe('2730')
|
||||
).toBe('2731')
|
||||
|
||||
enqueue({ data: SEED_RULES })
|
||||
expect(
|
||||
(await guessCounterAccount(supabase as unknown as SupabaseClient, 'company-1', 'Sociala avgifter Q1', 'aktiebolag'))?.account,
|
||||
).toBe('2730')
|
||||
).toBe('2731')
|
||||
})
|
||||
|
||||
it('routes deducted income tax to 2710 for an aktiebolag', async () => {
|
||||
|
||||
Reference in New Issue
Block a user