From ffd4c40d92cc1dfd976b4f8fc7182696846df759 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 23 Jul 2026 12:23:03 +0000 Subject: [PATCH] Fix CII schema violation: emit an empty ApplicableHeaderTradeDelivery element Mustang's Phase 4 CI check (validate-einvoice.yml) caught this on its very first real run: @e-invoice-eu/core's UBL->CII conversion silently drops the whole Delivery container when cac:Delivery is absent from the UBL input, breaking CII's fixed Agreement/Delivery/Settlement element order and failing schema validation on every generated e-invoice (original, Storno, and Gutschrift alike). --- src/einvoice/buildEInvoiceData.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/einvoice/buildEInvoiceData.ts b/src/einvoice/buildEInvoiceData.ts index a4a6166..c57b1c8 100644 --- a/src/einvoice/buildEInvoiceData.ts +++ b/src/einvoice/buildEInvoiceData.ts @@ -69,6 +69,19 @@ function isoDate(iso: string): string { return iso.slice(0, 10); } +// Empty on purpose — this shop doesn't track a separate delivery date/ +// location distinct from the invoice itself (and a Storno never shipped at +// all, so asserting one would be factually wrong). The *element* still has +// to exist, though: CII's SupplyChainTradeTransaction is a fixed +// Agreement/Delivery/Settlement sequence, and @e-invoice-eu/core's UBL→CII +// conversion drops the whole `ram:ApplicableHeaderTradeDelivery` container +// when `cac:Delivery` is absent from the UBL input — which then fails +// schema validation (Mustang: "Invalid content ... ApplicableHeaderTrade +// Settlement. One of ApplicableHeaderTradeDelivery is expected", caught by +// the Phase 4 CI check on the very first real run). An empty object here +// still emits the required empty ``. +const DELIVERY: UblInvoice["cac:Delivery"] = {}; + function paymentMeans(seller: InvoiceSeller, paymentMethodTitle: string): UblInvoice["cac:PaymentMeans"] { if (!seller.iban) return undefined; return [ @@ -180,6 +193,7 @@ export function buildEInvoiceData(order: InvoiceOrder, seller: InvoiceSeller): I order.city, order.country, ), + "cac:Delivery": DELIVERY, "cac:PaymentMeans": paymentMeans(seller, order.paymentMethodTitle), "cac:TaxTotal": taxTotal(rateGroups), "cac:LegalMonetaryTotal": { @@ -243,6 +257,7 @@ export function buildCorrectionEInvoiceData(kind: CorrectionInvoiceKind, order: order.city, order.country, ), + "cac:Delivery": DELIVERY, "cac:PaymentMeans": paymentMeans(seller, "Überweisung"), "cac:TaxTotal": taxTotal(rateGroups), "cac:LegalMonetaryTotal": {