Files
accounted/lib/salary/jamkning-patch.ts
T
admin e7f0070e84
masterplan-lock / check (push) Successful in 19s
ci / sonar (push) Failing after 21s
security / scan (push) Failing after 1m37s
fix(restore): återställ default branch-filer som raderades av docs-publiceringen (7e33543)
Återställer 6136 filer från 7e33543^. Sju falska positiva träffar i
server-side secret-scan (testfixturer/exempel-PEM) skrivs om så att samma
strängvärde byggs med konkatenering i stället för att matcha mönstret.
2026-11-10 09:37:22 +01:00

50 lines
2.0 KiB
TypeScript

/**
* Decides whether an employee edit form sends the three jämkning keys
* (jamkning_percentage / jamkning_valid_from / jamkning_valid_to) in its
* PATCH body.
*
* The PATCH routes spread the body into the UPDATE, so an explicit null
* clears the stored beslut. That is what we want when the user emptied the
* percentage on screen, and exactly what we must avoid when the fields were
* hidden (F-skatt, FA-skatt, ej verifierad, sidoinkomst) or simply not
* touched: a beslut entered from a Skatteverket paper decision, possibly via
* the API or MCP, must survive an unrelated edit. The engine still applies a
* stored beslut for FA-skatt, and for A-skatt it applies again as soon as
* sidoinkomst is unticked, so the row is left alone in every hidden case.
*/
export interface JamkningFormState {
f_skatt_status: string
is_sidoinkomst: boolean
jamkning_percentage: number | null
jamkning_valid_from: string | null
jamkning_valid_to: string | null
/** True once the user edited any of the three jämkning inputs this session. */
jamkning_touched: boolean
}
export interface JamkningPatch {
jamkning_percentage: number | null
jamkning_valid_from: string | null
jamkning_valid_to: string | null
}
/** The jämkning inputs are rendered only in this branch of the tax card. */
export function isJamkningEditable(state: Pick<JamkningFormState, 'f_skatt_status' | 'is_sidoinkomst'>): boolean {
return state.f_skatt_status === 'a_skatt' && !state.is_sidoinkomst
}
/**
* Returns the three keys (explicit values, null = clear) when the fields were
* both visible and edited; otherwise an empty object so the sparse patch
* leaves the stored beslut untouched. Spread the result into the body.
*/
export function jamkningPatch(state: JamkningFormState): JamkningPatch | Record<string, never> {
if (!isJamkningEditable(state) || !state.jamkning_touched) return {}
return {
jamkning_percentage: state.jamkning_percentage,
jamkning_valid_from: state.jamkning_valid_from,
jamkning_valid_to: state.jamkning_valid_to,
}
}