fix(salary): book lonevaxling pension provision from frozen run snapshot (#1382)
The book flow never populated pension_contribution/pension_slp, so a gross_deduction_pension line item reduced the salary entry but the 7410/2740 pension provision and 7533/2514 SLP lines were never posted. Derive both at the createSalaryRunEntries boundary from the run's frozen calculation_params.slpRate snapshot so the dashboard, MCP and v1 booking paths all emit the pension verifikat, and reuse the exact 1.058 factor via calculateLoneVaxlingPensionProvision shared with the planning calculator. Fixes #317 Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
6782da3e9e
commit
c9625fa45c
@@ -41,6 +41,7 @@ const makeRun = (overrides: Record<string, unknown> = {}) => ({
|
||||
total_net: 23000,
|
||||
total_avgifter: 9426,
|
||||
total_vacation_accrual: 0,
|
||||
calculation_params: { slpRate: 0.2426 },
|
||||
...overrides,
|
||||
})
|
||||
|
||||
@@ -194,5 +195,11 @@ describe('bookPaidSalaryRun', () => {
|
||||
expect(result.ok).toBe(true)
|
||||
if (result.ok) expect(result.data.entryIds).toEqual(['je-1', 'je-2'])
|
||||
expect(createSalaryRunEntries).toHaveBeenCalledTimes(1)
|
||||
expect(createSalaryRunEntries).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
'company-1',
|
||||
'user-1',
|
||||
expect.objectContaining({ calculation_params: { slpRate: 0.2426 } }),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -83,6 +83,7 @@ function makeRun(employees: ReturnType<typeof makeEmployee>[]) {
|
||||
total_net: employees.reduce((s, e) => s + e.net_salary, 0),
|
||||
total_avgifter: employees.reduce((s, e) => s + e.avgifter_amount, 0),
|
||||
total_vacation_accrual: employees.reduce((s, e) => s + e.vacation_accrual, 0),
|
||||
calculation_params: { slpRate: 0.2426 },
|
||||
employees,
|
||||
}
|
||||
}
|
||||
@@ -276,6 +277,36 @@ describe('salary entries: dimensions propagation (PR8)', () => {
|
||||
assertBalanced(pension)
|
||||
})
|
||||
|
||||
it('derives pension + SLP from gross_deduction_pension line items', async () => {
|
||||
const run = makeRun([
|
||||
makeEmployee({
|
||||
employee_id: 'a',
|
||||
default_dimensions: { '1': 'KS01' },
|
||||
line_items: [
|
||||
{
|
||||
item_type: 'gross_deduction_pension',
|
||||
amount: -2000,
|
||||
account_number: '7218',
|
||||
is_net_deduction: false,
|
||||
is_gross_deduction: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
])
|
||||
|
||||
const result = await createSalaryRunEntries(makeSupabase(), 'company-1', 'user-1', run)
|
||||
const pension = entryByDescription('Pensionsavsättning')
|
||||
|
||||
expect(result.pensionEntry).not.toBeNull()
|
||||
expect(linesOn(pension, '7410')).toEqual([
|
||||
expect.objectContaining({ debit_amount: 2116, dimensions: { '1': 'KS01' } }),
|
||||
])
|
||||
expect(linesOn(pension, '2740')[0].credit_amount).toBe(2116)
|
||||
expect(linesOn(pension, '7533')[0].debit_amount).toBe(513.34)
|
||||
expect(linesOn(pension, '2514')[0].credit_amount).toBe(513.34)
|
||||
assertBalanced(pension)
|
||||
})
|
||||
|
||||
it('rejects an invalid bag (coerce gate) rather than booking junk keys', async () => {
|
||||
const run = makeRun([
|
||||
makeEmployee({ employee_id: 'a', default_dimensions: { '0': 'BAD' } as Record<string, string> }),
|
||||
|
||||
Reference in New Issue
Block a user