feat(accounting): expenses ledger + supplier-payment toggle

Adds Accounting → Expenses, the view of everything triaged out of the inbox:

- ExpensesLedgerPage: filter by status / disposition; each row shows the
  disposition + status badge, CHF amount, created date, and a link to the
  client invoice for re-billed items. Supplier-payment toggle ("Mark paid" ->
  method + date + reference modal; "Paid" -> click to revert) wired to
  /:id/supplier-payment. Payment status is decoupled from categorisation, per
  the locked design; declined/duplicate rows skip the toggle.
- AccountingLayout: "Expenses" sub-nav item (gated by incomingInvoices).
- App.tsx: /admin/accounting/expenses route.
- i18n: accounting.subnav.expenses, accounting.ledger/expenseStatus/
  paymentMethod (EN + DE, DE authored natively).

Verified: en/de JSON valid; npm run build green.
This commit is contained in:
Luca
2026-06-11 00:42:46 +02:00
parent 502fbad5a8
commit 0c35ac43e6
5 changed files with 246 additions and 1 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 } from 'lucide-react';
import { Landmark, Calculator, Inbox, Wallet } from 'lucide-react';
import type { LucideIcon } from 'lucide-react';
import { useFeatureFlags, type FeatureKey } from '../../contexts/FeatureFlagsContext';
@@ -36,6 +36,13 @@ export const AccountingLayout: React.FC = () => {
icon: Inbox,
featureFlag: 'incomingInvoices',
},
{
key: 'expenses',
to: '/admin/accounting/expenses',
label: t('accounting.subnav.expenses', 'Expenses'),
icon: Wallet,
featureFlag: 'incomingInvoices',
},
{
key: 'tax-report',
to: '/admin/accounting/tax-report',