Actually fix the Delivery element: an empty object wasn't enough
Validate e-invoices / mustang (push) Failing after 17s
Validate e-invoices / mustang (push) Failing after 17s
The converter recurses into cac:Delivery's own children and only vivifies ram:ApplicableHeaderTradeDelivery if one of them resolves to a value — an empty {} produced no children, so the container still went missing. Using the invoice's own issue date as ActualDeliveryDate (BT-72, optional) actually populates it.
This commit is contained in:
@@ -69,18 +69,26 @@ 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 `<ram:ApplicableHeaderTradeDelivery/>`.
|
||||
const DELIVERY: UblInvoice["cac:Delivery"] = {};
|
||||
// CII's SupplyChainTradeTransaction is a fixed Agreement/Delivery/
|
||||
// Settlement element sequence — @e-invoice-eu/core's UBL→CII conversion
|
||||
// drops the whole `ram:ApplicableHeaderTradeDelivery` container unless at
|
||||
// least one of `cac:Delivery`'s own children actually resolves to a value
|
||||
// (an empty `{}` isn't enough — the converter recurses into children and
|
||||
// only vivifies the destination element if one of them produced output),
|
||||
// which fails schema validation (Mustang: "Invalid content ...
|
||||
// ApplicableHeaderTradeSettlement. One of ApplicableHeaderTradeDelivery is
|
||||
// expected", caught by the Phase 4 CI check on the very first real run —
|
||||
// an empty object there didn't fix it, this date is the actual fix).
|
||||
//
|
||||
// This shop doesn't track a separate delivery date distinct from the
|
||||
// invoice itself (no shipped-at timestamp exists at original-invoice time
|
||||
// — that's generated at checkout, before shipping even happens), so the
|
||||
// invoice's own issue date is used as the closest available proxy — BT-72
|
||||
// is optional under EN16931, and Mustang only checks structural/schema
|
||||
// conformance here, not the business accuracy of the date's value.
|
||||
function delivery(issuedAtIso: string): UblInvoice["cac:Delivery"] {
|
||||
return { "cbc:ActualDeliveryDate": isoDate(issuedAtIso) };
|
||||
}
|
||||
|
||||
function paymentMeans(seller: InvoiceSeller, paymentMethodTitle: string): UblInvoice["cac:PaymentMeans"] {
|
||||
if (!seller.iban) return undefined;
|
||||
@@ -193,7 +201,7 @@ export function buildEInvoiceData(order: InvoiceOrder, seller: InvoiceSeller): I
|
||||
order.city,
|
||||
order.country,
|
||||
),
|
||||
"cac:Delivery": DELIVERY,
|
||||
"cac:Delivery": delivery(order.invoiceIssuedAt),
|
||||
"cac:PaymentMeans": paymentMeans(seller, order.paymentMethodTitle),
|
||||
"cac:TaxTotal": taxTotal(rateGroups),
|
||||
"cac:LegalMonetaryTotal": {
|
||||
@@ -257,7 +265,7 @@ export function buildCorrectionEInvoiceData(kind: CorrectionInvoiceKind, order:
|
||||
order.city,
|
||||
order.country,
|
||||
),
|
||||
"cac:Delivery": DELIVERY,
|
||||
"cac:Delivery": delivery(order.correctionInvoiceIssuedAt),
|
||||
"cac:PaymentMeans": paymentMeans(seller, "Überweisung"),
|
||||
"cac:TaxTotal": taxTotal(rateGroups),
|
||||
"cac:LegalMonetaryTotal": {
|
||||
|
||||
Reference in New Issue
Block a user