Busflow Docs

Internal documentation portal

Skip to content

ADR-015: TaxLedgerEntry 1:N Cardinality per FinancialLedger

Status: ✅ Approved — 2026-04-12 Origin: Invoice Service ProtocolImpacts: schema-commerce.md §tax_ledger_entries, PRODUCT_domain-model.md §TaxLedgerEntry, tax-engine.md, datev-integration.md


Context

The original schema defined a 1:1 relationship between FinancialLedger and TaxLedgerEntry. However, a single departure can produce revenue from two distinct tax regimes simultaneously:

  1. Tour marginMARGIN_SCHEME_25 (§ 25 UStG), when any Fremdleistung is present
  2. Onboard sales (beverages, snacks) → STANDARD_VAT (19%), always Eigenleistung

tax-engine.md §Edge Cases explicitly states: "OnboardSales (beverages, snacks) → STANDARD_VAT — always Eigenleistung, tracked separately." This means a departure with both hotel bookings and onboard sales requires two separate tax computations with different strategies — impossible under a 1:1 constraint.

Decision

Change FINANCIAL_LEDGER ||--|| TAX_LEDGER_ENTRY to FINANCIAL_LEDGER ||--o{ TAX_LEDGER_ENTRY.

The tax_strategy column (STANDARD_VAT or MARGIN_SCHEME_25) discriminates each TaxLedgerEntry. A FinancialLedger can have 0..N entries, typically:

ScenarioTaxLedgerEntries
Pure charter (bus only, no hotel)1 × STANDARD_VAT
Tour with hotel (no onboard sales)1 × MARGIN_SCHEME_25
Tour with hotel + onboard sales1 × MARGIN_SCHEME_25 + 1 × STANDARD_VAT
Ledger still OPEN (trip not yet completed)0 (entries created at finalization)

Consequences

Positive:

  • Correctly models mixed tax strategies on a single departure
  • The system can report OnboardSale VAT independently from tour margin tax
  • DATEV export can group entries by tax_strategy for correct BU-Schlüssel mapping

Negative:

  • tax-calculator.service.ts must produce one TLE per tax strategy per departure (increased complexity)
  • Invoice rendering must handle multiple tax lines per ledger
  • DATEV CSV export must aggregate entries per strategy (separate BU-Schlüssel rows)

Neutral:

  • Departures with only one tax strategy continue to produce exactly one entry — backwards compatible

Internal documentation — Busflow