VAT System Alignment (LEGAL - Critical): - Align frontend VAT codes with backend (S25→U25, K25→I25, etc.) - Add missing codes: UEU, IVV, IVY, REP - Fix output VAT account 5710→5611 to match StandardDanishAccounts - Invoice posting now checks fiscal year status before allowing send - Disallow custom invoice number override (always use auto-numbering) Security: - Fix open redirect in AuthController (validate returnUrl is local) - Store seller CVR/name/address on invoice events (Momsloven §52) Backend Compliance: - Add description validation at posting (Bogføringsloven §7) - SAF-T: add DefaultCurrencyCode, TaxAccountingBasis to header - SAF-T: add TaxTable to MasterFiles with all VAT codes - SAF-T: always write balance elements even when zero - Add financial income account 9100 Renteindtægter Danish Encoding (~25 fixes): - Kassekladde: Bogført, Bogføring, Vælg, være, på, Tilføj, Differens - AttachmentUpload: træk, Understøtter, påkrævet, Bogføringsloven - keyboardShortcuts: Bogfør, Bogføring display name - ShortcutsHelpModal: åbne - DataTable: Genindlæs - documentProcessing: være - CloseFiscalYearWizard: årsafslutning Bugs Fixed: - Non-null assertion crashes in Kunder.tsx and Produkter.tsx (company!.id) - StatusBadge typo "Succces"→"Succes" - HTML entity ø in Kassekladde→proper UTF-8 - AmountText showSign prop was dead code (true || showSign) UX Improvements: - Add PageHeader to Bankafstemning and Dashboard loading/empty states - Responsive columns in Bankafstemning (xs/sm/lg breakpoints) - Disable misleading buttons: Settings preferences, Kontooversigt edit, Loenforstaelse export — with tooltips explaining status - Add DemoDataDisclaimer to UserSettings - Fix breadcrumb self-references on 3 pages - Replace Dashboard fake progress bar with honest message - Standardize date format DD-MM-YYYY in Bankafstemning and Ordrer - Replace Input type="number" with InputNumber in Ordrer Quality: - Remove 8 redundant console.error statements - Fix Kreditnotaer breadcrumb "Salg"→"Fakturering" for consistency Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
231 lines
17 KiB
C#
231 lines
17 KiB
C#
using Books.Api.Domain.Accounts;
|
|
|
|
namespace Books.Api.EventFlow.Subscribers;
|
|
|
|
/// <summary>
|
|
/// Standard Danish chart of accounts following Danish accounting standards.
|
|
/// Account number ranges:
|
|
/// - 1xxx: Revenue (Omsætning) + Current Assets (Omsætningsaktiver)
|
|
/// - 17xx: Fixed Assets (Anlægsaktiver)
|
|
/// - 2xxx: Cost of Goods Sold (Vareforbrug)
|
|
/// - 3xxx: Equity (Egenkapital) - ONLY equity accounts per Danish standards
|
|
/// - 4xxx: Sales Expenses (Salgsomkostninger)
|
|
/// - 5xxx: Location Costs (Lokaleomkostninger) + Personnel (Personaleomkostninger)
|
|
/// - 6xxx: Vehicle/Travel Expenses (Kørselsomkostninger)
|
|
/// - 7xxx: Administrative Expenses (Administrationsomkostninger) + Liabilities
|
|
/// - 8xxx: Depreciation (Afskrivninger)
|
|
/// - 9xxx: Financial Items (Finansielle poster)
|
|
///
|
|
/// StandardAccountNumber refers to Erhvervsstyrelsens standardkontoplan for SAF-T compliance.
|
|
/// Mapping based on official SAF-T 2.0 specification (mandatory from Jan 2027).
|
|
/// </summary>
|
|
public static class StandardDanishAccounts
|
|
{
|
|
public record StandardAccount(
|
|
string AccountNumber,
|
|
string Name,
|
|
AccountType AccountType,
|
|
string? Description,
|
|
string? DefaultVatCode,
|
|
string? StandardAccountNumber,
|
|
bool IsSystemAccount = false);
|
|
|
|
public static IEnumerable<StandardAccount> GetAll()
|
|
{
|
|
// =========================================
|
|
// OMSÆTNING (Revenue) - 1xxx
|
|
// Standard: 1010 = Salg af varer og ydelser med moms
|
|
// =========================================
|
|
yield return new("1000", "Salg af varer, DK", AccountType.Revenue, "Salg med 25% moms", "U25", "1010", true);
|
|
yield return new("1010", "Salg af varer, momsfrit", AccountType.Revenue, "Momsfrit salg", null, "1010", true);
|
|
yield return new("1050", "Salg af varer, EU", AccountType.Revenue, "EU-salg af varer", "UEU", "1050", true);
|
|
yield return new("1100", "Salg af varer, verden", AccountType.Revenue, "Eksport uden for EU", "UEXP", "1100", true);
|
|
yield return new("1200", "Salg af ydelser, DK", AccountType.Revenue, "Salg med 25% moms", "U25", "1010", true);
|
|
yield return new("1250", "Salg af ydelser, EU", AccountType.Revenue, "EU-salg af ydelser", "UEU", "1210", true);
|
|
yield return new("1300", "Salg af ydelser, verden", AccountType.Revenue, "Eksport uden for EU", "UEXP", "1310", true);
|
|
yield return new("1400", "Øvrig omsætning", AccountType.Revenue, null, "U25", "1510");
|
|
yield return new("1500", "Valutakursdifferencer, salg", AccountType.Revenue, null, null, "1510");
|
|
|
|
// =========================================
|
|
// ANLÆGSAKTIVER (Fixed Assets) - 17xx
|
|
// Standard: 5530 = Grunde og bygninger, 5570 = Produktionsanlæg
|
|
// =========================================
|
|
yield return new("1710", "Bygninger", AccountType.Asset, "Ejendomme og bygninger", null, "5530");
|
|
yield return new("1720", "Maskiner og inventar", AccountType.Asset, "Driftsmidler og maskiner", null, "5570");
|
|
yield return new("1730", "Køretøjer", AccountType.Asset, "Biler og transportmidler", null, "5570");
|
|
|
|
// =========================================
|
|
// OMSÆTNINGSAKTIVER (Current Assets) - 18xx-19xx
|
|
// Standard: 6140 = Varebeholdninger, 6190 = Tilgodehavender fra salg
|
|
// =========================================
|
|
yield return new("1800", "Varelager", AccountType.Asset, null, null, "6140");
|
|
yield return new("1850", "Igangværende arbejder", AccountType.Asset, null, null, "6150");
|
|
yield return new("1900", "Debitorer", AccountType.Asset, "Tilgodehavender fra salg", null, "6190", true);
|
|
yield return new("1950", "Andre tilgodehavender", AccountType.Asset, null, null, "6300");
|
|
|
|
// =========================================
|
|
// LIKVIDE BEHOLDNINGER (Cash & Bank) - 197x-198x
|
|
// Standard: 6470 = Kontanter, 6480 = Bankindeståender
|
|
// =========================================
|
|
yield return new("1970", "Bankkonto", AccountType.Asset, "Bankkonto til Open Banking", null, "6480");
|
|
|
|
// =========================================
|
|
// VAREFORBRUG (COGS) - 2xxx
|
|
// Standard: 1610 = Anvendt råvarer, 2070 = Køb af ydelser
|
|
// =========================================
|
|
yield return new("2000", "Vareforbrug", AccountType.Cogs, "Køb af varer til videresalg", "I25", "1610");
|
|
yield return new("2050", "EU-erhvervelser varer", AccountType.Cogs, "Varekøb fra EU-lande", "IEUV", "1610");
|
|
yield return new("2100", "EU-erhvervelser ydelser", AccountType.Cogs, "Ydelseskøb fra EU-lande", "IEUY", "2070");
|
|
yield return new("2150", "Varekøb verden", AccountType.Cogs, "Varekøb fra lande uden for EU", "IVV", "1610");
|
|
yield return new("2200", "Ydelseskøb verden", AccountType.Cogs, "Ydelseskøb fra lande uden for EU", "IVY", "2070");
|
|
yield return new("2250", "Fragt med moms", AccountType.Cogs, "Fragtomkostninger med moms", "I25", "1810");
|
|
yield return new("2300", "Fragt uden moms", AccountType.Cogs, "Fragtomkostninger uden moms", null, "1810");
|
|
yield return new("2400", "Valutakursdifferencer, import", AccountType.Cogs, null, null, "3690");
|
|
yield return new("2450", "Varelagerregulering", AccountType.Cogs, null, null, "1640");
|
|
yield return new("2800", "Fremmed arbejde", AccountType.Cogs, "Underleverandører og freelancere", "I25", "2010");
|
|
|
|
// =========================================
|
|
// EGENKAPITAL (Equity) - 3xxx
|
|
// Standard: 6510 = Virksomhedskapital, 6935 = Overført resultat
|
|
// Per Danish accounting standards, 3xxx should ONLY contain equity accounts
|
|
// =========================================
|
|
yield return new("3000", "Aktiekapital/Anpartskapital", AccountType.Equity, "Indskudt kapital", null, "6510", true);
|
|
yield return new("3100", "Overkurs ved emission", AccountType.Equity, "Share premium", null, "6530");
|
|
yield return new("3900", "Overført resultat", AccountType.Equity, "Akkumuleret resultat", null, "6935", true);
|
|
yield return new("3910", "Årets resultat", AccountType.Equity, "Resultat for indeværende år", null, "6940", true);
|
|
|
|
// =========================================
|
|
// SALGSOMKOSTNINGER (Sales Expenses) - 4xxx
|
|
// Standard: 2170 = Reklame, 2180 = Rejser og møder
|
|
// =========================================
|
|
yield return new("4000", "Annoncer og reklame", AccountType.Expense, "Marketing og annoncering", "I25", "2170");
|
|
yield return new("4040", "Hotel, personale", AccountType.Expense, "Fuldt fradrag", "I25", "2180");
|
|
yield return new("4060", "Hotel, forretningsforbindelser", AccountType.Expense, "Delvis fradrag", "I25", "2180");
|
|
yield return new("4080", "Konferencer", AccountType.Expense, null, null, "2180");
|
|
yield return new("4100", "Messer", AccountType.Expense, null, "I25", "2170");
|
|
yield return new("4120", "Repræsentation, restaurant, personale", AccountType.Expense, "Fuldt fradrag", "REP", "2190");
|
|
yield return new("4140", "Repræsentation, restaurant, forretningsforbindelser", AccountType.Expense, "Delvis fradrag", "REP", "2190");
|
|
yield return new("4180", "Repræsentation, gaver og blomster", AccountType.Expense, "Delvis fradrag", null, "2190");
|
|
yield return new("4280", "Rejseomkostninger", AccountType.Expense, null, null, "2180");
|
|
|
|
// =========================================
|
|
// LOKALEOMKOSTNINGER (Location Costs) - 50xx
|
|
// Standard: 2150 = Lokaleomkostninger
|
|
// =========================================
|
|
yield return new("5000", "Husleje", AccountType.Expense, "Husleje med moms", "I25", "2150");
|
|
yield return new("5010", "Husleje uden moms", AccountType.Expense, "Husleje uden moms", null, "2150");
|
|
yield return new("5025", "El", AccountType.Expense, null, "I25", "2150");
|
|
yield return new("5030", "Vand", AccountType.Expense, null, "I25", "2150");
|
|
yield return new("5035", "Varme", AccountType.Expense, null, "I25", "2150");
|
|
yield return new("5040", "Elafgift", AccountType.Expense, null, null, "2150");
|
|
yield return new("5060", "Rengøring og affaldshåndtering", AccountType.Expense, null, "I25", "2150");
|
|
yield return new("5080", "Reparation og vedligeholdelse", AccountType.Expense, null, "I25", "2150");
|
|
yield return new("5100", "Ejendomsskat", AccountType.Expense, null, null, "2150");
|
|
|
|
// =========================================
|
|
// PERSONALEOMKOSTNINGER (Personnel) - 53xx
|
|
// Standard: 2310 = Lønninger, 2330 = Pensioner
|
|
// Moved from 3xxx to comply with Danish standards (3xxx = Equity only)
|
|
// =========================================
|
|
yield return new("5300", "AM-indkomst", AccountType.Personnel, "Løn til ansatte", null, "2310");
|
|
yield return new("5310", "Arbejdsgiver ATP", AccountType.Personnel, null, null, "2350");
|
|
yield return new("5320", "Medarbejder ATP", AccountType.Personnel, null, null, "2350");
|
|
yield return new("5330", "Sygepenge mv.", AccountType.Personnel, null, null, "2390");
|
|
yield return new("5340", "Personalegoder", AccountType.Personnel, "Herunder fri telefon", null, "2390");
|
|
yield return new("5350", "B-honorar", AccountType.Personnel, null, null, "2310");
|
|
yield return new("5360", "Barsel", AccountType.Personnel, null, null, "2390");
|
|
yield return new("5370", "Feriepenge og SH", AccountType.Personnel, null, null, "2310");
|
|
yield return new("5380", "Pension", AccountType.Personnel, null, null, "2330");
|
|
yield return new("5390", "Diæter/rejsegodtgørelse", AccountType.Personnel, null, null, "2310");
|
|
yield return new("5400", "Kørsel i egen bil", AccountType.Personnel, "Kilometergodtgørelse", null, "2140");
|
|
yield return new("5410", "AER/AES/ATP-finansieringsbidrag", AccountType.Personnel, null, null, "2350");
|
|
yield return new("5420", "Arbejdstøj", AccountType.Personnel, null, "I25", "2390");
|
|
yield return new("5430", "Mad under kursus/møder", AccountType.Personnel, "Fuldt fradrag", "I25", "2180");
|
|
yield return new("5440", "Gaver til personalet", AccountType.Personnel, "Fuldt fradrag", null, "2390");
|
|
yield return new("5450", "Uddannelsesudgifter", AccountType.Personnel, null, "I25", "2180");
|
|
yield return new("5460", "Regulering feriepenge", AccountType.Personnel, null, null, "2310");
|
|
|
|
// =========================================
|
|
// KØRSELSOMKOSTNINGER (Vehicle/Travel) - 6xxx
|
|
// Standard: 2140 = Bilomkostninger
|
|
// =========================================
|
|
yield return new("6000", "Billeje (gulplade)", AccountType.Expense, null, "I25", "2140");
|
|
yield return new("6020", "Brændstof (gulplade)", AccountType.Expense, null, "I25", "2140");
|
|
yield return new("6040", "Vedligeholdelse af bil", AccountType.Expense, null, "I25", "2140");
|
|
yield return new("6060", "Vægtafgift og forsikringer", AccountType.Expense, null, null, "2140");
|
|
yield return new("6080", "Parkering", AccountType.Expense, null, "I25", "2140");
|
|
yield return new("6100", "Broafgift", AccountType.Expense, null, "I25", "2140");
|
|
yield return new("6120", "Taxa", AccountType.Expense, null, null, "2140");
|
|
yield return new("6140", "Tog", AccountType.Expense, null, null, "2180");
|
|
yield return new("6160", "Fly", AccountType.Expense, null, null, "2180");
|
|
|
|
// =========================================
|
|
// PASSIVER - KREDITORER (Liabilities) - 69xx
|
|
// Standard: 7350 = Leverandører af varer og tjenesteydelser
|
|
// =========================================
|
|
yield return new("6900", "Kreditorer", AccountType.Liability, "Leverandørgæld", null, "7350", true);
|
|
yield return new("6950", "Anden gæld", AccountType.Liability, null, null, "7790");
|
|
|
|
// =========================================
|
|
// ADMINISTRATIONSOMKOSTNINGER (Admin Expenses) - 7xxx
|
|
// Standard: 2110 = Administrationsomkostninger
|
|
// =========================================
|
|
yield return new("7005", "Revision og regnskabsmæssig assistance", AccountType.Expense, null, "I25", "2110");
|
|
yield return new("7010", "Advokat", AccountType.Expense, null, "I25", "2110");
|
|
yield return new("7020", "Bogføringsassistance", AccountType.Expense, null, "I25", "2110");
|
|
yield return new("7040", "Konsulentbistand", AccountType.Expense, null, "I25", "2110");
|
|
yield return new("7060", "Kontingenter inkl. moms", AccountType.Expense, null, "I25", "2110");
|
|
yield return new("7080", "Kontingenter ekskl. moms", AccountType.Expense, null, null, "2110");
|
|
yield return new("7100", "Aviser", AccountType.Expense, null, null, "2110");
|
|
yield return new("7120", "Faglitteratur", AccountType.Expense, null, "I25", "2110");
|
|
yield return new("7160", "Erhvervsforsikringer", AccountType.Expense, null, null, "2110");
|
|
yield return new("7200", "Kontorartikler og tryksager", AccountType.Expense, null, "I25", "2110");
|
|
yield return new("7220", "Porto og gebyrer", AccountType.Expense, null, null, "2110");
|
|
yield return new("7240", "Telefoni", AccountType.Expense, null, "I25", "2110");
|
|
yield return new("7300", "Internet og webhotel", AccountType.Expense, null, "I25", "2110");
|
|
yield return new("7320", "Køb af software", AccountType.Expense, "SaaS og licenser", "I25", "2110");
|
|
yield return new("7360", "Offentlige bøder og gebyrer", AccountType.Expense, null, null, "2110");
|
|
yield return new("7400", "Betalingsløsning", AccountType.Expense, "Stripe, MobilePay mv.", "I25", "2110");
|
|
yield return new("7420", "Indløsere", AccountType.Expense, "Nets, Clearhaus mv.", null, "2110");
|
|
yield return new("7460", "Diverse inkl. moms", AccountType.Expense, null, "I25", "2110");
|
|
yield return new("7480", "Diverse ekskl. moms", AccountType.Expense, null, null, "2110");
|
|
|
|
// =========================================
|
|
// MOMSKONTI (VAT Accounts) - 56xx
|
|
// Standard: 5610 = Købsmoms, 5611 = Salgsmoms, 5620 = EU-erhvervelsesmoms
|
|
// Required for VAT calculation and reporting
|
|
// =========================================
|
|
yield return new("5610", "Købsmoms", AccountType.Liability, "Indgående moms (Input VAT)", null, "5610", true);
|
|
yield return new("5611", "Salgsmoms", AccountType.Liability, "Udgående moms (Output VAT)", null, "5611", true);
|
|
yield return new("5620", "EU-erhvervelsesmoms", AccountType.Liability, "EU acquisition VAT", null, "5620", true);
|
|
|
|
// =========================================
|
|
// PASSIVER - SKYLDIG SKAT OG MOMS (Tax Liabilities) - 79xx
|
|
// Standard: 7680 = Anden gæld til SKAT, 7920 = A-skat
|
|
// =========================================
|
|
yield return new("7900", "Skyldig moms", AccountType.Liability, "Afregning med SKAT", null, "7680", true);
|
|
yield return new("7910", "Skyldig A-skat", AccountType.Liability, null, null, "7920", true);
|
|
yield return new("7920", "Skyldig AM-bidrag", AccountType.Liability, null, null, "7930", true);
|
|
yield return new("7930", "Skyldig ATP", AccountType.Liability, null, null, "7940", true);
|
|
yield return new("7940", "Skyldig feriepenge", AccountType.Liability, null, null, "8190", true);
|
|
yield return new("7950", "Skyldig selskabsskat", AccountType.Liability, "Selskabsskat til betaling", null, "7670", true);
|
|
|
|
// =========================================
|
|
// AFSKRIVNINGER (Depreciation) - 8xxx
|
|
// Standard: 3210 = Af- og nedskrivninger af materielle og immaterielle anlægsaktiver
|
|
// =========================================
|
|
yield return new("8010", "Afskrivning, bygninger", AccountType.Expense, "Afskrivning på bygninger", null, "3210");
|
|
yield return new("8020", "Afskrivning, maskiner", AccountType.Expense, "Afskrivning på maskiner og inventar", null, "3210");
|
|
yield return new("8030", "Afskrivning, køretøjer", AccountType.Expense, "Afskrivning på køretøjer", null, "3210");
|
|
yield return new("8040", "Småanskaffelser", AccountType.Expense, "Straksafskrivning", "I25", "3210");
|
|
|
|
// =========================================
|
|
// FINANSIELLE POSTER (Financial) - 9xxx
|
|
// Standard: 3510 = Finansielle indtægter, 3670 = Øvrige finansielle omkostninger
|
|
// =========================================
|
|
yield return new("9100", "Renteindtægter", AccountType.Revenue, "Finansielle indtægter", null, "9100");
|
|
yield return new("9200", "Bankrenter", AccountType.Financial, null, null, "3670");
|
|
yield return new("9210", "Leverandører mv.", AccountType.Financial, "Renter til leverandører", null, "3670");
|
|
yield return new("9220", "Ikke-fradragsberettigede renter", AccountType.Financial, null, null, "3670");
|
|
}
|
|
}
|