[DE] Buyer Reference (BT-10) must default from Bill-to and be consistent across documents/posting/export#29951
Conversation
|
@miljance there are more changes than I expected, but most of them are new page extensions. |
miljance
left a comment
There was a problem hiding this comment.
When Routing No., Buyer Reference and Your Reference are missing, the error appears during posting of a sales document. This is a bit misleading, but I could live with it.
Generally, the changes look pretty good, they make possible what was not previously. I think none of my comment are critical but please take a look at them and act where you see the relevance.
Adding a Code Review from GitHub Copilot. No expectations on my side, just pasting the results for fun. The fun part for me is that it also notices the redundance of the function for the buyer reference.
Here is a thorough code review of PR #29951.
Code Review — [DE] Buyer Reference (BT-10)
Overall Assessment
The PR is well-scoped and the priority chain concept (Document field → Customer Routing No. → Your Reference) is implemented consistently. The new Leitweg-ID validator is solid and the test coverage for it is excellent. The main concerns are about code duplication and a few missing test scenarios.
Issues
1. GetBuyerReferenceValue priority chain is duplicated ~5 times
The exact same 3-step priority logic appears in:
EDocPEPPOLBIS30DE.Codeunit.al(GetBuyerReferenceValue)XRechnungFormat.Codeunit.al(CheckBuyerReferenceMandatory)ZUGFeRDFormat.Codeunit.al(CheckBuyerReferenceMandatory)ExportXRechnungDocument.Codeunit.al(GetBuyerReferenceValue— two overloads)ExportZUGFeRDDocument.Codeunit.al(GetBuyerReference— repeated 4× inside a case statement)
EDocumentDEHelper already exists for shared logic. Adding a public GetBuyerReferenceValue(DocumentBuyerReference; BillToCustomerNo; YourReference) method there and calling it from all the above would eliminate this duplication.
2. ExportZUGFeRDDocument — priority chain repeated 4× inside GetBuyerReference
The new GetBuyerReference(RecordVariant) has the same 3 priority-chain lines inside each branch of a 4-case case statement. This is especially verbose. The approach used in ExportXRechnungDocument (two overloads calling a shared GetBuyerReferenceValue) is better, or better yet, delegate to EDocumentDEHelper.
3. EDocumentDEHelper.HasRoutingNo — implicit field number assumption is undocumented
BuyerReferenceFieldRef := SourceDocumentHeader.Field(SalesInvoiceHeader.FieldNo("Buyer Reference"));
CustomerNoFieldRef := SourceDocumentHeader.Field(SalesInvoiceHeader.FieldNo("Bill-to Customer No."));Using SalesInvoiceHeader.FieldNo(...) to access fields on a RecordRef that could be any of 6 document tables works only because all table extensions share the same field numbers. This implicit assumption should be documented with a comment, or the IsSupportedDocumentType guard should be strengthened.
4. EDocPEPPOLBIS30DE — label declared inside procedure body
MissingBuyerReferenceErr: Label 'Buyer Reference is mandatory for document %1.', Comment = '%1 = Document No.'Labels declared as local var inside a procedure body are non-standard in AL. Move it to the codeunit-level var section with the other error labels.
5. Missing test: Priority 1 (explicit document-level Buyer Reference) in export tests
The existing export tests (ExportPostedSalesInvoiceInXRechnungFormatVerifyBuyerReference*, etc.) verify Priority 2 (customer routing no.) and Priority 3 (Your Reference). There is no test verifying that when Buyer Reference is explicitly set on the document, it takes precedence over the customer's E-Invoice Routing No. in the exported XML.
6. Missing test: OnValidate for E-Invoice Routing No. on the Customer table extension
EDocumentCustomerDE.TableExt.al adds an OnValidate trigger that calls ValidateRoutingNo. There is no test that sets an invalid value on Customer."E-Invoice Routing No." and verifies the error fires.
7. EDocumentDETests — CreateCustomerWithRoutingNo bypasses OnValidate
Customer."E-Invoice Routing No." := RoutingNo;
Customer.Modify(true);Using direct assignment bypasses the new OnValidate trigger. Using Customer.Validate("E-Invoice Routing No.", RoutingNo) would make the test more realistic and would also exercise the validator on a known-good value.
Minor Observations
EDocumentHeaderHandlerDEnaming — the name is generic.E-Document Buyer Ref. Handler DEwould better describe its single responsibility.LibraryEDocDE—ConvertToNumericString/ComputeMod97duplicated fromEDocumentDEHelper. This is unavoidable since the helper useslocalprocedures, but worth noting if the helper ever gets refactored.SetSkipVATRegNoCheckvisibility — it'sinternal. Given the codeunit isManualinstance, this is fine, but ensure no external app was using the now-#if not CLEAN29-guardedSetBuyerReference.CheckSalesInvoiceIn*FormatVATRegNoMandatoryWithYourReference— good new test. The comment says[WHEN/THEN]which is slightly non-standard; typically it's a separate[WHEN]step followed by the[THEN]asserterror.- Tests verify
Bill-to Customer No.for routing no. lookup (fixed fromSell-to) — this is a correctness fix and the updated test assertions (Customer.Get(SalesInvoiceHeader."Bill-to Customer No.")) reflect it properly.
Summary Table
| # | Severity | Area | Description |
|---|---|---|---|
| 1 | Medium | Design | Priority chain duplicated in 5+ places; move to EDocumentDEHelper |
| 2 | Medium | Design | ExportZUGFeRDDocument.GetBuyerReference repeats chain 4× |
| 3 | Low | Maintainability | Implicit field number assumption in HasRoutingNo needs comment |
| 4 | Low | Style | MissingBuyerReferenceErr label inside procedure body |
| 5 | Medium | Tests | No export test for Priority 1 (document-level Buyer Reference) |
| 6 | Medium | Tests | No test for OnValidate on Customer."E-Invoice Routing No." |
| 7 | Low | Tests | CreateCustomerWithRoutingNo should use Validate not direct assignment |
…cross documents/posting/export
Co-authored-by: Copilot <copilot@github.com>
5f9291f to
cee7385
Compare
Summary
Update Buyer Reference Logic in XRechnung and ZUGFeRD export
Work Item(s)
Fixes #29921
Fixes AB#632763