feat(expenses): expense claims module (utlägg) (#2145)

Contributed by @joakimhew. Maintainer commits on top: migration re-versioned to 20260904170000 (main's 20260901210000 took the original version), payout batches booked atomically through the create_expense_payout_batch RPC, accounted-api skill regenerated, main merged. Closes #2143.
This commit is contained in:
Joakim Hansson
2026-09-05 13:36:51 +02:00
committed by GitHub
parent f7f40c04e4
commit 397a3b9bca
24 changed files with 5085 additions and 5 deletions
+6
View File
@@ -9,6 +9,7 @@ import { Button } from '@/components/ui/button'
import {
LayoutDashboard,
Home,
Receipt,
ReceiptText,
Users,
ArrowLeftRight,
@@ -137,6 +138,7 @@ type NavLabelKey =
| 'reports'
| 'import'
| 'salary'
| 'expenses'
| 'mileage'
| 'employees'
| 'vat_declaration'
@@ -244,6 +246,10 @@ const navItems: NavItem[] = [
// must still reach its already-imported orders (accounting underlag).
{ href: '/orders', labelKey: 'webshop_orders', icon: ShoppingCart, group: 'arbeta', requiresWebshop: true, betaBadge: true },
{ href: '/supplier-invoices', labelKey: 'supplier_invoices', icon: Wallet, group: 'arbeta' },
// Utlägg: out-of-pocket purchases and their reimbursement batches. The
// /expenses route previously redirected to supplier invoices; the nav key
// has existed in the nav namespace since then.
{ href: '/expenses', labelKey: 'expenses', icon: Receipt, group: 'arbeta' },
{ href: '/salary', labelKey: 'salary', icon: HandCoins, group: 'arbeta', employerOnly: true },
// Körjournal: hidden by default (most companies have no car); shows when
// the settings toggle is on or trips already exist (hybrid gate, same