'use client' import Link from 'next/link' import { useState } from 'react' import { useTranslations } from 'next-intl' import { SettingsFormWrapper } from '@/components/settings/SettingsFormWrapper' import { SettingsLoadError } from '@/components/settings/SettingsLoadError' import { SettingsLoadingSkeleton } from '@/components/settings/SettingsLoadingSkeleton' import { SettingsGroup, SettingsInput, SettingsRow, SettingsSectionHeader, SettingsSelect, } from '@/components/settings/SettingsRows' import { TaxTableStatus } from '@/components/salary/TaxTableStatus' import { useSettings } from '@/components/settings/useSettings' import { resolveDefaultSeriesForSource } from '@/lib/bookkeeping/voucher-series-resolver' import type { CompanySettings } from '@/types' const SERIES_OPTIONS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('') const BANK_OPTIONS = ['swedbank', 'seb', 'handelsbanken', 'nordea'] as const const BANK_LABEL: Record<(typeof BANK_OPTIONS)[number], string> = { swedbank: 'Swedbank', seb: 'SEB', handelsbanken: 'Handelsbanken', nordea: 'Nordea', } export function SalarySettingsContent() { const t = useTranslations('settings_salary') const tNav = useTranslations('settings_nav') const tIntro = useTranslations('settings_intro') const tSalary = useTranslations('salary') const { settings, isLoading, updateSettings, refetch } = useSettings() // Controlled so the LB sunset note reacts to the selection before save. const [format, setFormat] = useState<'bg_lb' | 'pain001' | null>(null) if (isLoading) return if (!settings) return const effectiveFormat = format ?? settings.preferred_payment_format ?? 'pain001' const currentSeries = resolveDefaultSeriesForSource(settings, 'salary_payment') function handleSave(formData: FormData) { const payDayRaw = parseInt((formData.get('salary_pay_day') as string) || '25', 10) const payDay = Number.isFinite(payDayRaw) ? Math.min(28, Math.max(1, payDayRaw)) : 25 const paymentFormat = (formData.get('preferred_payment_format') as string) || 'pain001' const bank = (formData.get('salary_default_bank') as string) || 'none' const series = (formData.get('salary_voucher_series') as string) || 'A' const updates: Record = { salary_pay_day: payDay, preferred_payment_format: paymentFormat, salary_default_bank: bank === 'none' ? null : bank, } // The booking engine resolves the series from the per-source-type map; // salary entries pass run.voucher_series explicitly, seeded from this // entry at run creation. Merge, never replace, the map so other // source-type overrides survive. if (series !== currentSeries) { updates.default_voucher_series_per_source_type = { ...(settings?.default_voucher_series_per_source_type || {}), salary_payment: series, } } return { updates, onSuccess: (data: Record) => { updateSettings(data as Partial) }, } } return (
setFormat(e.target.value as 'bg_lb' | 'pain001')} > {effectiveFormat === 'bg_lb' && (

{t('sunset_warning')}

)} {BANK_OPTIONS.map((key) => ( ))}
{SERIES_OPTIONS.map((letter) => ( ))}
{/* Tax tables: automatic, read-only status. Lives outside the form so the recheck action never interacts with the save flow. */} {chunks}, })} > {/* Vacation is configured per employee; this row only points there. */} {t('vacation_info_link')}
) }