fix(salary): recompute entitled_days on existing ledger rows and record pre-cutover taken days (#1403)
The vacation ledger sync carried entitled_days verbatim on existing open rows while re-deriving accrued and taken, so a stale entitled value (for example the flat 25 stored before Semesterlagen 7 § pro-rating existed) survived every sync. The recompute loop now re-derives entitled the same way the lazy-seed path does, with the opening-balance cutover still outranking recomputation for the year containing cutover_date. Opening balances could also not record paid vacation days already taken in the cutover year under the previous payroll system. New additive column employee_opening_balances.vacation_days_taken_this_year (NUMERIC NOT NULL DEFAULT 0, CHECK 0..40) threaded through the shared service, the Zod schema, the MCP staging tool (schema + mergeable fields), the staged-operation executor, the v1 REST routes, and the employee editor form. Ledger semantics for the cutover year, on both seed and recompute paths: entitled = remaining + taken_this_year, taken = booked-run taken + taken_this_year, so remaining keeps meaning remaining and the seeded value survives every subsequent sync. Fixes #1347 Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Jakob Wennberg
Claude Fable 5
parent
2296c0cd59
commit
9f5a43310b
@@ -11811,7 +11811,7 @@ export const tools: McpTool[] = [
|
||||
{
|
||||
name: 'gnubok_set_employee_opening_balances',
|
||||
title: 'Set Employee Opening Balances (Cutover)',
|
||||
description: 'Stage payroll cutover state per employee: YTD gross/tax/net, vacation days remaining, sparade dagar by origin year, opening semesterlöneskuld SEK, karens adjustment. An omitted field keeps its stored value; send 0 to clear it. Locked after a booked run.',
|
||||
description: 'Stage payroll cutover state per employee: YTD gross/tax/net, vacation days remaining and taken this year, sparade dagar by origin year, opening semesterlöneskuld SEK, karens adjustment. An omitted field keeps its stored value; send 0 to clear it. Locked after a booked run.',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
@@ -11830,6 +11830,7 @@ export const tools: McpTool[] = [
|
||||
ytd_tax: { type: 'number' },
|
||||
ytd_net: { type: 'number' },
|
||||
vacation_paid_days_remaining: { type: 'number' },
|
||||
vacation_days_taken_this_year: { type: 'number', description: 'Paid days already taken this vacation year under the previous system (0-40)' },
|
||||
vacation_saved_days_by_year: { type: 'object', description: 'Origin year -> days, e.g. {"2025": 5}; {} clears' },
|
||||
opening_semester_liability: { type: 'number', description: 'SEK on 2920 (report-only; booked via SIE)' },
|
||||
opening_semester_liability_avgifter: { type: 'number', description: 'SEK on 2940' },
|
||||
@@ -11845,9 +11846,9 @@ export const tools: McpTool[] = [
|
||||
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
||||
async execute(args, companyId, userId, supabase, actor) {
|
||||
// Sparse merge, NOT full replace. OpeningBalancesBulkSchema carries a
|
||||
// .default() on all eight non-key fields (and .partial() would not strip
|
||||
// .default() on all nine non-key fields (and .partial() would not strip
|
||||
// them: Zod applies defaults through it), so parsing the caller's args
|
||||
// straight into the 9-column upsert resets ytd_tax, ytd_net, vacation
|
||||
// straight into the 10-column upsert resets ytd_tax, ytd_net, vacation
|
||||
// days, sparade dagar, the opening semesterlöneskuld and the karens
|
||||
// adjustment to 0 whenever an agent corrects a single figure. Same
|
||||
// defence as gnubok_update_employee: keep only the keys actually sent,
|
||||
@@ -11875,7 +11876,8 @@ export const tools: McpTool[] = [
|
||||
|
||||
const MERGEABLE_FIELDS = [
|
||||
'ytd_gross', 'ytd_tax', 'ytd_net',
|
||||
'vacation_paid_days_remaining', 'vacation_saved_days_by_year',
|
||||
'vacation_paid_days_remaining', 'vacation_days_taken_this_year',
|
||||
'vacation_saved_days_by_year',
|
||||
'opening_semester_liability', 'opening_semester_liability_avgifter',
|
||||
'karens_periods_adjustment',
|
||||
] as const
|
||||
|
||||
Reference in New Issue
Block a user