'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 { PeriodLockingSettings } from '@/components/settings/PeriodLockingSettings' import { FiscalYearsManager } from '@/components/settings/FiscalYearsManager' import { VoucherSeriesManager } from '@/components/settings/VoucherSeriesManager' import { VoucherSeriesPerSourceTypeForm } from '@/components/settings/VoucherSeriesPerSourceTypeForm' import { applyDefaultSeriesToMap } from '@/lib/bookkeeping/voucher-series-resolver' import { PeriodiseringAutoDetectToggle } from '@/components/settings/PeriodiseringAutoDetectToggle' import { AccountingFrameworkForm } from '@/components/settings/AccountingFrameworkForm' import { useSettings } from '@/components/settings/useSettings' import { useCompany } from '@/contexts/CompanyContext' import { Label } from '@/components/ui/label' import { ExternalLink } from 'lucide-react' import type { AccountingFramework, CompanySettings } from '@/types' const SERIES_OPTIONS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('') export function BookkeepingSettingsContent() { const t = useTranslations('settings_bookkeeping') const { settings, isLoading, updateSettings, refetch } = useSettings() const { company } = useCompany() // Local mirror of the company-level accounting_framework so the K2/K3 // selector can reflect its own saves without waiting for the layout to // re-render through the server. Falls back to k2 (matches the column // default) until the company row is loaded. const [framework, setFramework] = useState( company?.accounting_framework ?? 'k2', ) if (isLoading) return if (!settings) return function handleSave(formData: FormData) { const autoLockValue = formData.get('auto_lock_period_days') as string const lockedThrough = (formData.get('bookkeeping_locked_through') as string) || null const accountingMethod = (formData.get('accounting_method') as string) || 'accrual' const defaultVoucherSeries = (formData.get('default_voucher_series') as string) || 'A' const updates: Record = { bookkeeping_locked_through: lockedThrough, auto_lock_period_days: autoLockValue === 'none' ? null : parseInt(autoLockValue), accounting_method: accountingMethod, default_voucher_series: defaultVoucherSeries, } // Write-through: the booking engine resolves the series from the // per-source-type map, NOT from default_voucher_series. So when the user // changes the global default, propagate it across the map — but only for // types that were still following the previous default, leaving explicit // per-type overrides (set via VoucherSeriesPerSourceTypeForm) untouched. // Without this the "Standardserie" dropdown is a no-op for bookkeeping. // Only runs when the series actually changed, so saving the form for an // unrelated reason (e.g. the lock date) never rewrites the map. const prevDefault = settings?.default_voucher_series || 'A' const currentMap = settings?.default_voucher_series_per_source_type if (currentMap && defaultVoucherSeries !== prevDefault) { updates.default_voucher_series_per_source_type = applyDefaultSeriesToMap( currentMap, prevDefault, defaultVoucherSeries, ) } return { updates, onSuccess: (data: Record) => { updateSettings(data as Partial) }, } } // K2/K3 selector is only meaningful for AB. EF stays on EF rules and never // picks a framework. Use the company row (source of truth) since // company_settings.entity_type can be stale on legacy data. const isAktiebolag = company?.entity_type === 'aktiebolag' return (
{isAktiebolag && ( setFramework(next)} /> )} {/* Accounting method */}

{t('method_heading')}

{t('method_help')}

{/* Default voucher series */}

{t('series_heading')}

{t('series_help')}

{/* Period locking */}
{/* Fiscal years */}
{/* Voucher series — per-source-type mapping */}
{/* Voucher series — read-only display */}
{/* Periodisering auto-detect toggle */}
{/* Cross-links */}

{t('related_heading')}

{t('related_fiscal_year')} {t('related_chart_of_accounts')}
) }