Add GTIN to XRechnung and ZUGFeRD exports - #10048
Add GTIN to XRechnung and ZUGFeRD exports#10048Milica Đukić (djukicmilica) wants to merge 6 commits into
Conversation
|
Knowledge: Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.31.4 |
|
The new ItemGTINCache field in ExportXRechnungDocument.Codeunit.al is only reset via Clear(ItemGTINCache) at the start of the two sales-document CreateXML overloads (Sales Invoice Header, Sales Cr.Memo Header). The Service Invoice Header and Service Cr.Memo Header CreateXML overloads (which also emit item lines through InsertInvoiceLines/InsertStandardItemIdentification via temporary sales lines transferred from service lines) do not clear the cache. If the same codeunit instance is reused across multiple CreateXML calls within a batch/session (e.g. export sales invoice then service invoice, or repeated calls), a stale cached GTIN keyed by Item No. could be returned instead of re-reading the current Item.GTIN value. Clear the cache at the start of every CreateXML overload that can emit item lines, not just the two sales ones. Agent judgement — not directly backed by a BCQuality knowledge article. Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.31.4 |
|
This PR adds a new InsertGlobalID(SpecifiedTradeProductElement, ItemNo) call in InsertInvoiceLine/InsertCrMemoLine (ExportZUGFeRDDocument.Codeunit.al) that writes Item.GTIN into /rsm:CrossIndustryInvoice/.../ram:SpecifiedTradeProduct/ram:GlobalID whenever the line is Type::Item and the referenced Item has a GTIN. However, four pre-existing tests in ZUGFeRDXMLDocumentTests.Codeunit.al already assert different semantics for that exact XML path: ExportPostedSalesInvoiceInZUGFeRDFormatVerifyGlobalID (line ~641) and ExportPostedSalesCrMemoInZUGFeRDFormatVerifyGlobalID (line ~1080) assert GlobalID equals SalesInvoiceLine/SalesCrMemoLine.'Item Reference No.', which CreateAndPostSalesDocumentWithItemRefNo sets to a random GUID (LibraryUtility.GenerateGUID()) - never the Item's GTIN. After this change, the exporter no longer ever writes 'Item Reference No.' into GlobalID; it writes Item.GTIN only, and only when GTIN is populated. Since the GUID cannot equal a populated GTIN and the test items in these two pre-existing tests are not shown to have GTIN set, GetNodeByPathWithError will most likely throw 'Node not found' (or return an unrelated GTIN value), causing these two pre-existing tests to fail. This is a concrete, demonstrable regression to existing shipped test coverage introduced by this diff, not merely a hypothetical risk. Fix by reconciling the two features: either give the new GTIN-based GlobalID a different scheme/element than the one the pre-existing 'Item Reference No.' tests target, or update/remove the conflicting pre-existing tests so the suite has one consistent definition of what SpecifiedTradeProduct/GlobalID represents. Agent judgement — not directly backed by a BCQuality knowledge article. Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.31.4 |
Pull request was closed
|
This PR silently changes the meaning of the already-shipped ZUGFeRD line-level ram:GlobalID from Sales Line "Item Reference No." to Item.GTIN (and adds the equivalent cac:StandardItemIdentification to XRechnung for the first time). Existing customers/integrations that populated "Item Reference No." and consumed that value from the exported XML will silently receive different data after upgrade, with no compatibility switch, feature flag, or deprecation note. Consider preserving prior behavior by default (or falling back to Item Reference No. when GTIN is blank) and introduce the GTIN mapping as an explicit, documented change, or confirm with product management that this is an intentional, accepted behavior change for this feature area. Agent judgement — not directly backed by a BCQuality knowledge article. Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.31.4 |
|
The new XRechnung export writes Item.GTIN into cac:StandardItemIdentification/cbc:ID with schemeID 0160 (GS1/GTIN), but verify this app's corresponding XRechnung/Peppol import path does not map that same element back to the internal item number or a different reference field. If an import mapping elsewhere in this app (or a downstream consumer) expects StandardItemIdentification to carry an internal item identifier rather than a GS1 GTIN, round-tripping a document exported by this codeunit could misinterpret the GTIN as an internal item reference. Confirm the export/import contract is consistent for this element across the app. Agent judgement — not directly backed by a BCQuality knowledge article. Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.31.4 |
|
GetItemGTIN() is called once per posted sales line and still performs an Item.Get for every distinct item number on the document. The per-run Dictionary only avoids repeated lookups for duplicate items on the same document; documents with many different items still incur one Item.Get per distinct item (N+1 pattern). Preload GTINs for all distinct item numbers on the document in a single batched read (e.g., SetFilter on Item."No." with the distinct item numbers, or a temp-table join) before iterating lines, instead of a per-line/per-item Get. Knowledge: Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.31.4 |
|
Same N+1 Item.Get-per-distinct-item pattern as the XRechnung exporter: GetItemGTIN() caches per item number but still performs one Item.Get per distinct item on the document rather than a single batched read. Preload GTINs for all distinct item numbers on the document before iterating lines. Knowledge: Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.31.4 |
|
GetItemGTIN() (lookup + Dictionary cache logic) is duplicated nearly verbatim between Export XRechnung Document and Export ZUGFeRD Document, differing only in the XML element names used to emit the identifier. This makes it easy to fix or extend GTIN handling in one exporter (e.g., adding a fallback, changing the cache-clear scope, or handling additional identifier schemes) while missing the other. Consider extracting the shared GTIN lookup/caching logic into a common helper codeunit, keeping only the format-specific XML element construction in each exporter. Agent judgement — not directly backed by a BCQuality knowledge article. Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.31.4 |
|
The three SetItemGTIN helper overloads and the new GTIN test scenarios are duplicated verbatim between XRechnungXMLDocumentTests and ZUGFeRDXMLDocumentTests. Any future change to how GTIN is set up or asserted must be applied identically in both suites, or they will drift (note ZUGFeRD's new tests do not include an equivalent to XRechnung's 'OmitsBlankGTIN' test, which is already an early sign of drift). Consider a shared test helper/library for GTIN setup shared by both codeunits. Agent judgement — not directly backed by a BCQuality knowledge article. Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.31.4 |
|
Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.31.4 |
|
Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.31.4 |
Why
XRechnung and ZUGFeRD exports omit the GTIN stored on item cards, preventing recipients in retail and service scenarios from identifying invoiced items by their standard product identifier.
Summary
0160to XRechnung and ZUGFeRD item lines.Fixes
AB#646116