Busflow Docs

Internal documentation portal

Skip to content

ADR-012: TOMS Tax Deferral to Phase 3 (FinancialLedger) ​

Status: βœ… Approved β€” 2026-04-10 Origin: Kalkulations-Engine ProtocolResolves: SB-2 (Β§ 25 UStG per-line tax split) Impacts: schema-backoffice.md Β§price_matrices, PRODUCT_domain-model.md Β§PriceMatrix, Commerce checkout flow


Context ​

Under Β§ 25 UStG (TOMS β€” Tour Operator Margin Scheme / Margenbesteuerung), the tax authority does not calculate VAT per ticket or per line item. Instead, the system computes it on the aggregate margin of the entire departure:

TOMS margin = total_revenue βˆ’ total_Fremdleistungen (third-party procurement costs)
TOMS VAT    = margin Γ— 19/119

This depends on:

  1. Actual fixed costs β€” vendor invoices that may arrive weeks after the trip
  2. Final passenger counts β€” cancellations and no-shows alter the per-pax cost allocation

The system does not know either value at PriceMatrix generation time.

The Previous Approach (v1/v2) ​

Earlier iterations of the PriceMatrix spec attempted per-variant tax estimation using total_net_cost / break_even_pax as a proxy. This produced a numeric tax_amount on every variant.

Why this fails:

  • The result is a legal fiction β€” per-variant TOMS tax has no basis in Β§ 25 UStG
  • Displaying fictitious tax line items in B2C invoices creates compliance risk
  • Every cost change, cancellation, or no-show invalidates the estimation
  • The Steuerberater would reject these figures during Nachkalkulation

Standard VAT Has No Problem ​

Under STANDARD_VAT (no third-party procurement), the tax uses a simple net-back: gross Γ— 19/119. This approach works per variant and requires no deferral.

Decision ​

1. Tax Resolution by Strategy ​

Tax Strategytax_amountnet_priceRationale
STANDARD_VATComputed: gross Γ— 19/119Computed: gross βˆ’ taxStandard net-back. Legally correct per variant.
MARGIN_SCHEME_25null= gross_priceTax deferred to Phase 3. Customer pays full gross.

IMPORTANT

net_price under TOMS equals gross_price β€” it does not use null. Commerce needs a non-null price for cart totals, payment capture, and Mollie integration. The system defers tax decomposition, not the sellable price.

2. Phase 3 Authority ​

The FinancialLedger (Phase 3) is the sole authority for Β§ 25 UStG tax calculation. It computes margin tax at the departure level after the trip, when:

  • The operator reconciles actual vendor invoices (Fremdleistungen)
  • The system knows final passenger counts
  • The operator closes the period

3. Per-Variant DB1 via variable_cost_snapshot ​

Even though the system defers tax, the PriceMatrix still enables per-variant DB1 (Deckungsbeitrag 1 = revenue βˆ’ variable costs per ticket) via the variable_cost_snapshot field on each PriceVariant. This gives dispatchers immediate revenue-minus-variable-cost visibility without pretending to know the tax.

DB2 (DB1 βˆ’ allocated fixed costs) remains a departure-level concern computed by the Backoffice margin calculator.

4. UI Presentation ​

  • TOMS tours display gross_price with "inkl. MwSt." labeling (legally required for B2C gross prices in Germany)
  • Backoffice Dispatcher UI shows the "Seats to Break-Even" progress bar (current_booking_count vs. break_even_pax) instead of misleading per-ticket margin numbers
  • Tax columns in the dispatcher pricing view show "~" or "nach Abschluss" for TOMS departures

Consequences ​

Positive:

  • Eliminates the risk of displaying fictitious per-ticket tax estimates in invoices
  • Legally correct: the system computes Β§ 25 UStG where it should β€” at departure-level aggregate
  • Simplifies Commerce: no need to handle tax recalculation on booking changes
  • FinancialLedger has full actual data (invoices + passenger counts) for accurate tax
  • Per-variant DB1 remains available for operational visibility

Negative:

  • Commerce cannot display a tax breakdown for TOMS tours β€” only "inkl. MwSt." (this is legally correct anyway)
  • Dispatchers see deferred tax indicators instead of estimated margins (mitigated by break-even progress bar)
  • Phase 3 (FinancialLedger) becomes a hard dependency for complete financial reporting

Neutral:

  • Standard VAT tours remain unaffected β€” they continue to show full tax decomposition
  • B2C customers see no difference β€” all German prices display as gross ("inkl. MwSt.") regardless

Resolves:

  • SB-2 (Β§ 25 UStG per-line tax split) β€” deferring to the appropriate level fully resolves the strategic blind spot

Internal documentation β€” Busflow