* feat: implement salary module with personnummer encryption, salary entries, tax tables, and AGI tracking - Added personnummer encryption and decryption functions for secure storage. - Created salary entries handling for journal entries including gross salary, tax withholding, and employer contributions. - Implemented tax table lookup functionality for calculating tax amounts based on monthly income. - Developed SQL migration for salary module including tables for payroll configuration, tax rates, employees, salary runs, salary run employees, salary line items, and AGI declarations. - Established row-level security policies for all new tables to ensure company-scoped access. * feat: add salary calculation modules for 2026 - Implemented engångsskatt calculation for one-time payments with tax brackets. - Added löneväxling functionality for salary sacrifice to pension, including employer savings and warnings. - Created pain.001 generator for salary batch payments in compliance with Swedish banking standards. - Developed PDF template for payslips, including detailed breakdowns and employer costs. - Generated seed data for Swedish tax tables for 2026, including SQL insert statements. - Implemented traktamente calculations for per diem and mileage allowances, adhering to Skatteverket regulations. - Added seed script for populating tax tables in the database. * feat: Update meal reduction percentages in traktamente calculation fix: Remove obsolete seed script for 2026 tax tables feat: Extend SalaryRunStatus type to include 'corrected' status feat: Implement KU10 XML generation endpoint for annual employee income statements feat: Add endpoint for creating corrections to booked salary runs feat: Implement endpoint for sending payslip PDFs to employees feat: Create KU10 XML generator for annual reporting feat: Add salary transaction matcher for auto-linking bank transactions to salary entries chore: Add database migration for salary correction support * feat: replace select elements with custom Select component for employment and salary types * feat: enhance salary calculations with pension entry and avgifter category support
100 lines
3.4 KiB
TypeScript
100 lines
3.4 KiB
TypeScript
/**
|
||
* AGI (Arbetsgivardeklaration) field codes per Skatteverket Teknisk beskrivning.
|
||
*
|
||
* FK = Fältkod (field code)
|
||
* Ruta = Box number on the form
|
||
*/
|
||
|
||
// ============================================================
|
||
// Huvuduppgift (Employer totals)
|
||
// ============================================================
|
||
|
||
/** Employer-level field codes */
|
||
export const HUVUDUPPGIFT_FIELDS = {
|
||
/** Total skatteavdrag — sum of all employee tax withholdings */
|
||
RUTA_001: '001',
|
||
/** Total underlag for arbetsgivaravgifter */
|
||
RUTA_020: '020',
|
||
/** Arbetsgivaravgifter — standard rate (31.42%) */
|
||
RUTA_060: '060',
|
||
/** Arbetsgivaravgifter — age-reduced (10.21%, born ≤1959 for 2026) */
|
||
RUTA_061: '061',
|
||
/** Arbetsgivaravgifter — youth rate (20.81%, ages 19-23, Apr 2026–Sep 2027) */
|
||
RUTA_062: '062',
|
||
} as const
|
||
|
||
// ============================================================
|
||
// Individuppgift (Per-employee data)
|
||
// ============================================================
|
||
|
||
/** Per-employee field codes */
|
||
export const INDIVID_FIELDS = {
|
||
/** Personnummer/samordningsnummer (12 digits, CRITICAL: must be decrypted) */
|
||
FK215: '215',
|
||
/** Specifikationsnummer — MUST stay consistent per employee for corrections */
|
||
FK570: '570',
|
||
/** Kontant bruttolön (gross cash salary) */
|
||
RUTA_011: '011',
|
||
/** Avdragen skatt (withheld preliminary tax) */
|
||
RUTA_001: '001',
|
||
/** Förmånsvärde — bilförmån */
|
||
RUTA_012: '012',
|
||
/** Förmånsvärde — drivmedel vid bilförmån */
|
||
RUTA_013: '013',
|
||
/** Förmånsvärde — bostad */
|
||
RUTA_014: '014',
|
||
/** Förmånsvärde — kost */
|
||
RUTA_015: '015',
|
||
/** Förmånsvärde — ränta */
|
||
RUTA_016: '016',
|
||
/** Förmånsvärde — övriga */
|
||
RUTA_019: '019',
|
||
/** Underlag för arbetsgivaravgifter */
|
||
RUTA_020: '020',
|
||
/** Ersättning till mottagare med F-skattsedel (not subject to avgifter) */
|
||
RUTA_131: '131',
|
||
// Absence fields (from 2025)
|
||
/** Sjukfrånvaro — antal dagar */
|
||
FK821: '821',
|
||
/** VAB — antal dagar */
|
||
FK822: '822',
|
||
/** Föräldraledighet — antal dagar */
|
||
FK823: '823',
|
||
/** Graviditetspenning — antal dagar */
|
||
FK824: '824',
|
||
/** Smittbärarpenning — antal dagar */
|
||
FK825: '825',
|
||
/** Sjuk-/aktivitetsersättning — antal dagar */
|
||
FK826: '826',
|
||
/** Rehabilitering — antal dagar */
|
||
FK827: '827',
|
||
} as const
|
||
|
||
// ============================================================
|
||
// Benefit type to ruta mapping
|
||
// ============================================================
|
||
|
||
/** Map benefit item types to AGI individuppgift rutor */
|
||
export const BENEFIT_RUTA_MAP: Record<string, string> = {
|
||
benefit_car: INDIVID_FIELDS.RUTA_012,
|
||
benefit_housing: INDIVID_FIELDS.RUTA_014,
|
||
benefit_meals: INDIVID_FIELDS.RUTA_015,
|
||
benefit_wellness: INDIVID_FIELDS.RUTA_019,
|
||
benefit_other: INDIVID_FIELDS.RUTA_019,
|
||
}
|
||
|
||
// ============================================================
|
||
// Avgifter category to ruta mapping
|
||
// ============================================================
|
||
|
||
export type AvgifterCategory = 'standard' | 'reduced_65plus' | 'youth' | 'vaxa_stod' | 'exempt'
|
||
|
||
/** Map avgifter categories to huvuduppgift rutor */
|
||
export const AVGIFTER_RUTA_MAP: Record<AvgifterCategory, string> = {
|
||
standard: HUVUDUPPGIFT_FIELDS.RUTA_060,
|
||
reduced_65plus: HUVUDUPPGIFT_FIELDS.RUTA_061,
|
||
youth: HUVUDUPPGIFT_FIELDS.RUTA_062,
|
||
vaxa_stod: HUVUDUPPGIFT_FIELDS.RUTA_061, // Växa-stöd uses same rate as 65+
|
||
exempt: '', // No avgifter
|
||
}
|