feat(accounting): Layer A frontend — chart of accounts CRUD + Treuhänder export UI

- ledger.service.ts: accounts/VAT-codes/mappings CRUD + export client
- ChartOfAccountsPage: full CRUD for the Swiss/LI KMU chart + MWST codes,
  category→account mapping, default/system accounts + tax-treatment/rate→VAT
  maps, with a 'guideline only' note
- LedgerExportPage: period + currency + target tool (generic/Banana/bexio)
  → collective-journal CSV download, with accrual-only + Treuhänder disclaimer
- AccountingLayout: 'Treuhänder export' (taxReport flag) + 'Chart of accounts'
  (accounting flag) sub-nav entries; App routes wired
- en/de translations (accounting.taxTreatment.* enum + ledger.* namespace)

de/en authored natively; no machine-translated locales touched here.
This commit is contained in:
Luca
2026-06-12 00:48:39 +02:00
parent 03cc250b47
commit 7e0098edcd
7 changed files with 687 additions and 4 deletions
@@ -9,7 +9,7 @@
import React from 'react';
import { NavLink, Outlet, Navigate, useLocation, useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { Landmark, Calculator, Inbox, Wallet } from 'lucide-react';
import { Landmark, Calculator, Inbox, Wallet, BookOpen, FileSpreadsheet } from 'lucide-react';
import type { LucideIcon } from 'lucide-react';
import { useFeatureFlags, type FeatureKey } from '../../contexts/FeatureFlagsContext';
@@ -50,7 +50,21 @@ export const AccountingLayout: React.FC = () => {
icon: Calculator,
featureFlag: 'taxReport',
},
// Future: expenses ledger, Erfolgsrechnung.
{
key: 'export',
to: '/admin/accounting/export',
label: t('accounting.subnav.export', 'Treuhänder export'),
icon: FileSpreadsheet,
featureFlag: 'taxReport',
},
{
key: 'ledger',
to: '/admin/accounting/ledger',
label: t('accounting.subnav.chartOfAccounts', 'Chart of accounts'),
icon: BookOpen,
featureFlag: 'accounting',
},
// Future: Erfolgsrechnung (Layer B).
];
const enabledItems = navItems.filter((item) => flags[item.featureFlag]);