Skip to content

Ordering TaxPointDate before CreditNoteTypeCode in credit-note output - #101

Closed
CarlosMari wants to merge 2 commits into
mainfrom
fix-creditnote-taxpointdate-order
Closed

Ordering TaxPointDate before CreditNoteTypeCode in credit-note output#101
CarlosMari wants to merge 2 commits into
mainfrom
fix-creditnote-taxpointdate-order

Conversation

@CarlosMari

@CarlosMari CarlosMari commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

BUG — credit notes with a TaxPointDate are XSD-invalid

Symptom

Any UBL credit note that carries a cbc:TaxPointDate (mapped from GOBL inv.ValueDate) is generated with the element in the wrong position and fails UBL XSD validation. This affects all contexts that emit credit notes (Peppol, EN 16931, …) — it is not context-specific.

Root cause

Invoice and CreditNote share a single Go struct, whose field order is fixed. In that struct CreditNoteTypeCode precedes TaxPointDate, which is correct for the Invoice XSD but wrong for the CreditNote XSD:

UBL-Invoice-2.1.xsd UBL-CreditNote-2.1.xsd
order InvoiceTypeCodeTaxPointDate TaxPointDateCreditNoteTypeCode

encoding/xml emits fields in the single struct order, so a credit note places TaxPointDate after CreditNoteTypeCode — violating the CreditNote sequence.

Proof (on main, before this change)

Generating a standard Peppol/EN 16931 credit note with a value_date and validating via phive (eu.peppol.bis3:creditnote:2025.5):

validation_type: "xsd"  →  external/schemas/ubl21/maindoc/UBL-CreditNote-2.1.xsd
cvc-complex-type.2.4.a: Invalid content was found starting with element 'TaxPointDate'.
One of '{Note, DocumentCurrencyCode, TaxCurrencyCode, ...}' is expected.

The CEN-EN16931 and PEPPOL-EN16931 schematron layers pass — the failure is purely the XSD sequence.

Fix

Bytes/BytesCompact post-process the marshaled output: when the document is a credit note carrying a TaxPointDate, move that element ahead of CreditNoteTypeCode to match the CreditNote XSD sequence. The reorder edits bytes directly because encoding/xml can neither vary field order per struct nor survive a decode/re-encode (it mangles the cac:/cbc: prefixes).

After the fix the same document is phive-green (TaxPointDate on the line before CreditNoteTypeCode).

Test

Adds test/data/convert/peppol/credit-note-taxpoint.json (+ golden), a standard Peppol/EN 16931 credit note with a value_date, which is phive-valid with the fix and reproduces the failure without it.

Notes

  • The same fix is also present in the in-flight OIOUBL PR Add oioubl 21 context #73 (where it was first noticed); this PR lands it as a standalone generic fix against main since the bug pre-dates and is independent of OIOUBL.
  • The reproduction GOBL is saved for console verification.

@codecov-commenter

codecov-commenter commented Jul 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.00000% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.96%. Comparing base (7669190) to head (a639790).

Files with missing lines Patch % Lines
ubl.go 79.16% 8 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #101      +/-   ##
==========================================
+ Coverage   80.91%   80.96%   +0.05%     
==========================================
  Files          28       28              
  Lines        2117     2165      +48     
==========================================
+ Hits         1713     1753      +40     
- Misses        267      274       +7     
- Partials      137      138       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@CarlosMari

Copy link
Copy Markdown
Contributor Author

Addressed in #102

@CarlosMari CarlosMari closed this Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants