// Innergemeinschaftliche Lieferung (§4 Nr. 1b UStG) — a cross-border EU B2B // sale with a VIES-validated buyer VAT ID is zero-rated. Kept separate from // cartTotals.ts/computeTaxBreakdown (which assume each item's own // catalog tax rate) rather than bolted onto them — this is a genuinely // different computation (every rate forced to 0%, every price de-grossed // from its normal VAT-inclusive catalog price to net), used in exactly two // places: CheckoutContent.tsx's live preview and api/checkout/route.ts's // authoritative recompute, which must stay in exact agreement. // // Deliberate simplification: `discountAmount` is carried over unchanged // (not itself re-derived against the de-grossed subtotal) — a discount // code combined with a validated cross-border exemption is a narrow // overlap, and the existing discount math (percent-of-subtotal or a flat // amount, see cartTotals.ts's computeCartTotals) already produces a // reasonable number either way. Revisit only if this combination turns out // to matter in practice. export type ExemptLine = { quantity: number; grossUnitPrice: number; taxRatePercent: number }; function roundMoney(amount: number): number { return Math.round(amount * 100) / 100; } function degross(grossAmount: number, ratePercent: number): number { return grossAmount / (1 + ratePercent / 100); } export type ExemptTotals = { subtotal: number; shippingCost: number; total: number }; // `shippingCostGross`/`defaultTaxRate` — shipping has no per-line tax rate // of its own (see taxBreakdown.ts's proportional-scale comment), so it's // de-grossed at the tenant's default rate as the representative rate, // same fallback cartTotals.ts's effectiveTaxRate() already uses elsewhere. export function computeExemptTotals(items: ExemptLine[], shippingCostGross: number, defaultTaxRate: number, discountAmount: number): ExemptTotals { const subtotal = roundMoney(items.reduce((sum, i) => sum + i.quantity * degross(i.grossUnitPrice, i.taxRatePercent), 0)); const shippingCost = roundMoney(degross(shippingCostGross, defaultTaxRate)); const total = roundMoney(Math.max(0, subtotal - discountAmount) + shippingCost); return { subtotal, shippingCost, total }; } // The destination the goods actually ship to, not necessarily the billing // address — the exemption depends on where the goods physically move to, // which is the shipping override's country when one is set (see Orders.ts's // own hasDifferentShippingAddress comment), the billing country otherwise. export function destinationCountry(country: string, hasDifferentShippingAddress: boolean, shippingCountry: string | null | undefined): string { return hasDifferentShippingAddress && shippingCountry ? shippingCountry : country; } // Only Österreich is a real candidate today — this checkout offers exactly // three countries (Deutschland/Österreich/Schweiz, see CheckoutContent.tsx's // own PLZ_DIGITS), and Deutschland (domestic) / Schweiz (non-EU export, a // different exemption entirely) never qualify for this specific one. export function isExemptionEligibleCountry(country: string): boolean { return country === "Österreich"; }