04dbb31d7e
* 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
107 lines
3.6 KiB
TypeScript
107 lines
3.6 KiB
TypeScript
import type { SupabaseClient } from '@supabase/supabase-js'
|
|
|
|
export interface PayrollConfig {
|
|
configYear: number
|
|
avgifterTotal: number
|
|
avgifterAlderspension: number
|
|
avgifterSjukforsakring: number
|
|
avgifterForaldraforsakring: number
|
|
avgifterEfterlevandepension: number
|
|
avgifterArbetsmarknad: number
|
|
avgifterArbetsskada: number
|
|
avgifterAllmanLoneavgift: number
|
|
avgifterReduced65plus: number
|
|
avgifterYouthRate: number | null
|
|
avgifterYouthSalaryCap: number | null
|
|
avgifterVaxaStodRate: number | null
|
|
avgifterVaxaStodCap: number | null
|
|
avgifterMinimumAnnual: number
|
|
egenavgifterTotal: number
|
|
slpRate: number
|
|
prisbasbelopp: number
|
|
inkomstbasbelopp: number
|
|
maxPgi: number
|
|
sgiCeiling: number
|
|
statligSkattBrytpunkt: number
|
|
traktamenteHeldag: number
|
|
traktamenteHalvdag: number
|
|
traktamenteNatt: number
|
|
milersattningEgenBil: number
|
|
milersattningFormansbilFossil: number
|
|
milersattningFormansbilEl: number
|
|
kostformanHeldag: number
|
|
kostformanLunch: number
|
|
kostformanFrukost: number
|
|
friskvardCap: number
|
|
bilformanSlr: number
|
|
sjuklonRate: number
|
|
karensavdragFactor: number
|
|
maxKarensavdragPerYear: number
|
|
reducedAvgiftAge: number
|
|
}
|
|
|
|
/**
|
|
* Load payroll configuration for a given year.
|
|
*/
|
|
export async function loadPayrollConfig(
|
|
supabase: SupabaseClient,
|
|
year: number
|
|
): Promise<PayrollConfig> {
|
|
const { data, error } = await supabase
|
|
.from('salary_payroll_config')
|
|
.select('*')
|
|
.eq('config_year', year)
|
|
.single()
|
|
|
|
if (error || !data) {
|
|
throw new Error(`Payroll configuration not found for year ${year}`)
|
|
}
|
|
|
|
return {
|
|
configYear: data.config_year,
|
|
avgifterTotal: data.avgifter_total,
|
|
avgifterAlderspension: data.avgifter_alderspension,
|
|
avgifterSjukforsakring: data.avgifter_sjukforsakring,
|
|
avgifterForaldraforsakring: data.avgifter_foraldraforsakring,
|
|
avgifterEfterlevandepension: data.avgifter_efterlevandepension,
|
|
avgifterArbetsmarknad: data.avgifter_arbetsmarknad,
|
|
avgifterArbetsskada: data.avgifter_arbetsskada,
|
|
avgifterAllmanLoneavgift: data.avgifter_allman_loneavgift,
|
|
avgifterReduced65plus: data.avgifter_reduced_65plus,
|
|
avgifterYouthRate: data.avgifter_youth_rate,
|
|
avgifterYouthSalaryCap: data.avgifter_youth_salary_cap,
|
|
avgifterVaxaStodRate: data.avgifter_vaxa_stod_rate,
|
|
avgifterVaxaStodCap: data.avgifter_vaxa_stod_cap,
|
|
avgifterMinimumAnnual: data.avgifter_minimum_annual,
|
|
egenavgifterTotal: data.egenavgifter_total,
|
|
slpRate: data.slp_rate,
|
|
prisbasbelopp: data.prisbasbelopp,
|
|
inkomstbasbelopp: data.inkomstbasbelopp,
|
|
maxPgi: data.max_pgi,
|
|
sgiCeiling: data.sgi_ceiling,
|
|
statligSkattBrytpunkt: data.statlig_skatt_brytpunkt,
|
|
traktamenteHeldag: data.traktamente_heldag,
|
|
traktamenteHalvdag: data.traktamente_halvdag,
|
|
traktamenteNatt: data.traktamente_natt,
|
|
milersattningEgenBil: data.milersattning_egen_bil,
|
|
milersattningFormansbilFossil: data.milersattning_formansbil_fossil,
|
|
milersattningFormansbilEl: data.milersattning_formansbil_el,
|
|
kostformanHeldag: data.kostforman_heldag,
|
|
kostformanLunch: data.kostforman_lunch,
|
|
kostformanFrukost: data.kostforman_frukost,
|
|
friskvardCap: data.friskvard_cap,
|
|
bilformanSlr: data.bilforman_slr,
|
|
sjuklonRate: data.sjuklon_rate,
|
|
karensavdragFactor: data.karensavdrag_factor,
|
|
maxKarensavdragPerYear: data.max_karensavdrag_per_year,
|
|
reducedAvgiftAge: data.reduced_avgift_age,
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Serialize payroll config for snapshot storage in salary_runs.calculation_params.
|
|
*/
|
|
export function serializePayrollConfig(config: PayrollConfig): Record<string, unknown> {
|
|
return { ...config }
|
|
}
|