[E-Document Formats] Fix defects in V2 draft migration for XRechnung, PINT A-NZ and Factura-E - #9784
Merged
Merged
Conversation
… PINT A-NZ and Factura-E Verification of the local e-document formats migrated to the V2 (draft) import pipeline found several defects where the migrated formats deviated from the OIOUBL reference implementation. XRechnung (DE): - ReadIntoDraft never called ResetDraft, so re-running "Read into Draft" appended a second set of purchase lines (GetNextLineNo keeps incrementing). ResetDraft was effectively dead code. - ResetDraft used GetFromEDocument + Delete(true), which errors when no draft header exists yet. Aligned with the OIOUBL implementation that deletes the header and line ranges. - The root element case had no else branch and did not validate the root namespace, so unsupported documents (for example CII CrossIndustryInvoice) silently produced an empty draft with an uninitialised process draft enum. Unsupported roots and namespaces are now rejected with an error. - Added regression tests for unsupported root element, unexpected root namespace, and re-running Read into Draft. PINT A-NZ (APAC): - GetVendorRelatedData declared VendorParticipantId, VendorName and VendorAddress by value, so the participant-id and name/address vendor matching fallbacks in TryMatchVendor always received empty values. - Credit notes did not map BillingReference/InvoiceDocumentReference/ID, so "Applies-to Ext. Invoice No." stayed empty and finish draft could not apply the credit memo to the original invoice. Factura-E (ES): - InvoiceHeader/Corrective/InvoiceNumber was mapped to "Purchase Order No." instead of "Applies-to Ext. Invoice No.". Finish draft treats the former as a vendor order number, so rectificative invoices were never applied to the original invoice. Co-authored-by: Copilot <[email protected]>
…ests Resolves 'Build Apps DE' compile failure in Pull Request Build: AL0789 'Using directives are ignored if a namespace is not specified.' in E-Document for Germany Tests. XRechnungStructuredTests.Codeunit.al declares no namespace, so the added using directive is ignored by the compiler; IStructuredFormatReader resolves without it. [bcapps-fix-loop attempt 1] Co-authored-by: Copilot <[email protected]>
Groenbech96
enabled auto-merge
July 29, 2026 05:55
darjoo
approved these changes
Jul 29, 2026
gggdttt
approved these changes
Jul 29, 2026
djukicmilica
approved these changes
Jul 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes AB#644279
Summary
Verification of the local e-document formats migrated to the V2 (draft) import pipeline found several defects where the migrated formats deviate from the DK OIOUBL reference implementation. This PR fixes the high-confidence functional defects.
Related migrations: #9426 (PINT A-NZ, Factura-E), #9682 (OIOUBL), #9690 (XRechnung).
Fixes
XRechnung (DE) —
EDocumentXRechnungHandler.Codeunit.alResetDraftwas never called fromReadIntoDraftGetNextLineNokeeps incrementing.ResetDraftwas dead code.ResetDraftusedGetFromEDocument+Delete(true)EDocumentOIOUBLHandler.casehad noelseand did not validate the root namespaceCrossIndustryInvoice) silently produced an empty draft and returned an uninitialised"E-Doc. Process Draft". Now rejected with an error, matching OIOUBL.PINT A-NZ (APAC)
GetVendorRelatedDatadeclaredVendorParticipantId/VendorName/VendorAddressby value (PINTANZImport.Codeunit.al)TryMatchVendoralways received empty strings — dead fallback logic.cac:BillingReference/cac:InvoiceDocumentReference/cbc:ID"Applies-to Ext. Invoice No."stayed empty, soEDocCreatePurchCrMemocould not apply the credit memo to the original invoice. Core PEPPOL and OIOUBL both map this.Factura-E (ES)
InvoiceHeader/Corrective/InvoiceNumbermapped to"Purchase Order No.""Applies-to Ext. Invoice No.".Tests
Added three regression tests to
XRechnungStructuredTests.Codeunit.al, mirroring the existing OIOUBL suite:TestXRechnungUnsupportedRootElement_IsRejectedTestXRechnungUnexpectedRootNamespace_IsRejectedTestXRechnungInvoice_ReadIntoDraftTwice_DoesNotDuplicateLinesNot included (tracked separately)
The following gaps were also identified during verification and are being filed as work items rather than fixed here, since they need schema review and new test fixtures:
cac:TaxTotal/cbc:TaxAmount(OIOUBL, PINT A-NZ)cac:AdditionalDocumentReference) not imported (OIOUBL, PINT A-NZ, Factura-E, XRechnung)GeneralDiscounts/ lineDiscountsAndRebatesnot mapped; multi-invoice batches merge all lines into one draft"E-Document Format"::Mockrather than the real formatReviewer note: Factura-E mapping deliberately diverges from V1
The V1 importer maps
Corrective/InvoiceNumberto a different field than this PR does:Corrective/InvoiceNumbertargetFacturaEImport.Codeunit.al:217-218)"Applies-to Doc. No."EDocumentFacturaEHandler.Codeunit.al:116)"Purchase Order No.""Applies-to Ext. Invoice No."EDocCreatePurchCrMemo.Codeunit.al:62-73treats the two draft fields differently:"Applies-to Doc. No."is used verbatim as a BC posted-invoice number."Applies-to Ext. Invoice No."is resolved by looking upPurch. Inv. Header."Vendor Invoice No."for the vendor, and only then sets"Applies-to Doc. No.".On an inbound credit memo,
Corrective/InvoiceNumberis the original invoice number as issued by the vendor, not a BC document number. Therefore the resolving field is the correct target, and this matches every other V2 reader:EDocumentPEPPOLHandler.Codeunit.al:151-152EDocumentOIOUBLHandler.Codeunit.al:144V1's direct write to
"Applies-to Doc. No."only applies correctly when the vendor's numbering happens to equal BC's posted invoice number; otherwise it fails to apply or mis-applies to an unrelated document. This PR intentionally does not preserve that V1 behavior. Please confirm this is acceptable.