'use client' import { useState } from 'react' import { Button } from '@/components/ui/button' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog' import { useToast } from '@/components/ui/use-toast' import { SettingsRow, SettingsRowNote, SettingsSelect, } from '@/components/settings/SettingsRows' import type { AccountingFramework } from '@/types' import { Loader2 } from 'lucide-react' interface AccountingFrameworkFormProps { /** Current framework on the company row. */ current: AccountingFramework /** Bubble up after a successful save so parent state can refresh. */ onSaved?: (next: AccountingFramework) => void } /** * K2/K3 selector row for AB. Lives in the Grunder group on the bookkeeping * settings page. Renders nothing for non-AB entities: the parent gates this * component by entity_type. * * UX rules (regulatory area: kept in Swedish): * - Default is K2 (matches the column default and BFNAR 2016:10 baseline). * - Switching in either direction fires a confirmation dialog. K2 → K3 * warns about the added obligations; the recommendation per BFN is that * the choice is permanent once made, surfaced as a warning, not a block. * K3 → K2 warns about what the system does NOT do: uppskjuten skatt * (2240/8940) balances and komponentavskrivningar are not unwound * automatically, and the K3 årsredovisning content stops applying. * - The save is its own request (PATCH /api/company/current): separate * from /api/settings because the column lives on companies, not on * company_settings. */ export function AccountingFrameworkForm({ current, onSaved }: AccountingFrameworkFormProps) { const { toast } = useToast() const [selected, setSelected] = useState(current) const [pending, setPending] = useState(null) const [saving, setSaving] = useState(false) async function persist(next: AccountingFramework) { setSaving(true) try { const res = await fetch('/api/company/current', { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ accounting_framework: next }), }) const body = await res.json() if (!res.ok) { toast({ title: 'Kunde inte spara', description: body?.error ?? 'Försök igen.', variant: 'destructive', }) setSelected(current) return } toast({ title: 'Sparat', description: next === 'k3' ? 'Bolaget redovisar nu enligt K3 (BFNAR 2012:1).' : 'Bolaget redovisar nu enligt K2 (BFNAR 2016:10).', }) onSaved?.(next) } catch { toast({ title: 'Kunde inte spara', description: 'Försök igen.', variant: 'destructive', }) setSelected(current) } finally { setSaving(false) setPending(null) } } function handleChange(next: string) { const value = next as AccountingFramework if (value === selected) return // Both directions are consequential: K2 → K3 adds obligations, K3 → K2 // leaves K3-only balances behind. Confirm before persisting either way. setPending(value) } return ( <> K2 är standard för mindre bolag och innebär förenklade regler. K3 krävs när bolaget når två av tre tröskelvärden (nettoomsättning > 80 MSEK, tillgångar > 40 MSEK, eller fler än 50 anställda). K3 ställer högre krav: kassaflödesanalys, komponentavskrivning på materiella anläggningstillgångar och mer omfattande noter. Obeskattade reserver redovisas brutto i juridisk person enligt K3 punkt 29.37. } > handleChange(e.target.value)} // Saves via its own PATCH; the row sits inside the page's // SettingsFormWrapper form, so keep the wrapper's dirty tracking // (onInput on the form) from reacting to this select. No `name` // either, so the wrapper's FormData never picks it up. onInput={(e) => e.stopPropagation()} disabled={saving} > {saving && Sparar…} { if (!open) setPending(null) }} > {pending === 'k2' ? 'Byta till K2?' : 'Byta till K3?'} {pending === 'k2' ? ( <> Bokförda saldon för uppskjuten skatt (konto 2240 / 8940) och gjorda komponentavskrivningar återförs inte automatiskt: de måste hanteras manuellt. Årsredovisningens K3-innehåll (kassaflödesanalys, K3-noter och uppskjuten skatt) gäller inte längre. Fortsätt? ) : ( <> K3 medför löpande att kassaflödesanalys upprättas, att komponentavskrivning kan användas och att årsredovisningen får ett utökat notinnehåll. Bytet är permanent enligt rekommendation. Fortsätt? )} ) }