Extract NL customization to object extensions (TrMode)#8933
Extract NL customization to object extensions (TrMode)#8933Alexander-Ya wants to merge 27 commits into
Conversation
|
Fixes AB#640601 |
Copilot PR ReviewIteration 17 · Outcome: completed Knowledge source: https://github.com/microsoft/BCQuality@186d8a131465475c79244d994acb872cd5c0d4bf Findings by domainFindings split into Knowledge-backed (cite a BCQuality article) and Agent (the agent's own judgement, no matching BCQuality rule).
Totals: 3 knowledge-backed · 0 agent findings. Orchestrator pre-filter (2 file(s) excluded)
Findings produced by the AL review agent v1.7.3. Reply 👎 on any inline comment to flag false positives. |
The model-reported anchor for a single-line suggestion can be off by more than 8 lines (e.g. PR #8933 VendorNL Confirm() was off by 10, label rename off by 9). Widen the search window to 40 lines either side so the correct target within the same procedure is considered, while the 0.5 similarity floor and 0.1 ambiguity margin keep an unrelated look-alike from winning. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Widening the search window exposed a precision problem: a label-rename suggestion whose added Comment text echoes the field captions at the Error()/Confirm() call site would re-anchor onto the call site (PR #8933 GenJournalLineNL/GeneralLedgerSetupNL 'Text1000000/1' findings), which is worse than the original mis-anchor. Raise the similarity floor to 0.6 and use a bounded window (20). Genuine edit targets - an edited statement or a renamed declaration - score ~0.75-0.99 and re-anchor confidently (the PR #8933 Confirm() findings and the PartnerTypeMismatchMsg->Qst rename now land on the right line). Lower- confidence look-alikes stay below the floor and are suppressed, so the caller posts a manual snippet instead of a wrong auto-applicable anchor. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…Extract-NL-customization-to-object-extensions-v2
…Extract-NL-customization-to-object-extensions-v2
This comment was marked as resolved.
This comment was marked as resolved.
…Extract-NL-customization-to-object-extensions-v2
Agentic PR Review - Round 5Recommendation: Request ChangesWhat this PR doesThis PR extracts NL BaseApp Transaction Mode customization into extension objects for AB#640601. Since round 4, the author-owned AL changes are test-only: one commit fixes setup in an NL purchase document amount test, and one commit disables a W1 service-order warehouse shipment test. The NL test setup change looks like a real test fix: it enables Status of previous suggestions
New observations (commits since round 4)S6 - Do not disable unrelated W1 tests Risk assessment and necessityRisk: The main product risk is still that non-NL companies can receive NL Transaction Mode behavior through unguarded subscribers that copy or enforce Transaction Mode outside the guarded field Necessity: The extraction remains necessary for AB#640601 because it removes NL full-object customization and lowers future merge cost. The round-5 test changes are not enough to make the PR safe: the Transaction Mode scope must cover all paths, and unrelated tests should not be disabled to get the branch green.
|
The [Test] attribute on procedure PullServiceLineNoShipmentUsingUseFilter was commented out (changed to '// [Test]'), which silently removes this test case from the test run instead of deleting it or marking it Obsolete with a documented reason.The test body, assertions, and helper calls remain fully intact, indicating this was very likely a leftover debugging change rather than an intentional removal. If genuinely intentional, impact would be major (a real regression test for warehouse-shipment source filtering with no matching orders would stop running in CI without any record of why); capped to minor per agent-finding severity rules. Recommend restoring the [Test] attribute, or if the test is no longer valid, deleting it or using [Test, Disabled] equivalent tracked in an issue with a comment explaining the reason. Suggested fix (apply manually — could not be anchored as a one-click suggestion): [Test]Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why |
…Extract-NL-customization-to-object-extensions-v2
| Access = Internal; | ||
|
|
||
| [EventSubscriber(ObjectType::Page, Page::"Purch. Invoice Subform", 'OnAfterNoOnAfterValidate', '', false, false)] | ||
| local procedure OnAfterNoOnAfterValidate(var PurchaseLine: Record "Purchase Line"; xPurchaseLine: Record "Purchase Line") |
There was a problem hiding this comment.
The new EventSubscriber OnAfterNoOnAfterValidate on Page::"Purch.
Invoice Subform" declares its second parameter as xPurchaseLine: Record "Purchase Line" (no var), but the publisher (PurchInvoiceSubform.Page.al line 1593) declares it as var xPurchaseLine: Record "Purchase Line". AL requires a subscriber to reproduce the publisher's parameter list, including var/byref modifiers, verbatim. This var mismatch will fail to compile/bind. Compare with the sibling PurchCrMemoSubformNL.Codeunit.al, which correctly copies both var modifiers from its own publisher.
| local procedure OnAfterNoOnAfterValidate(var PurchaseLine: Record "Purchase Line"; xPurchaseLine: Record "Purchase Line") | |
| local procedure OnAfterNoOnAfterValidate(var PurchaseLine: Record "Purchase Line"; var xPurchaseLine: Record "Purchase Line") |
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| Access = Internal; | ||
|
|
||
| [EventSubscriber(ObjectType::Codeunit, Codeunit::"Sales-Post Prepayments", 'OnBeforePostCustomerEntry', '', false, false)] | ||
| local procedure OnBeforePostCustomerEntry(var GenJnlLine: Record "Gen. Journal Line"; SalesHeader: Record "Sales Header") |
There was a problem hiding this comment.
The new EventSubscriber OnBeforePostCustomerEntry on Codeunit::"Sales-Post Prepayments" is declared with only two parameters, `(var GenJnlLine: Record "Gen.
Journal Line"; SalesHeader: Record "Sales Header"), but the publisher (SalesPostPrepayments.Codeunit.al line 2431) declares six parameters: (var GenJnlLine: Record "Gen. Journal Line"; TotalPrepmtInvLineBuffer: Record "Prepayment Inv. Line Buffer"; TotalPrepmtInvLineBufferLCY: Record "Prepayment Inv. Line Buffer"; CommitIsSuppressed: Boolean; SalesHeader: Record "Sales Header"; DocumentType: Option Invoice,"Credit Memo")`. A subscriber cannot cherry-pick a subset of the publisher's parameters; the full parameter list, in order, must be reproduced. As written this subscriber will not bind to the publisher and the extracted NL Transaction Mode Code/Bank Account Code logic that used to run inline in the old NL override of Sales-Post Prepayments will silently stop firing.
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| @@ -7581,7 +7582,7 @@ table 36 "Sales Header" | |||
| if ReplaceVATDate then | |||
| "VAT Reporting Date" := VATDateReq; | |||
|
|
|||
| if ReplaceDocDate and ("Document Date" <> PostingDateReq) then begin | |||
| if ReplacePostingDate and ReplaceDocDate and ("Document Date" <> PostingDateReq) then begin | |||
There was a problem hiding this comment.
SalesHeader.Table.al's BatchConfirmUpdatePostingDate procedure was changed to if ReplacePostingDate and ReplaceDocDate and (...), but the procedure already exits immediately at its top with if not ReplacePostingDate then exit;.
By the time execution reaches this line, ReplacePostingDate is always true, so the added conjunct is dead/redundant code. The same change is duplicated identically across every per-country-layer copy of SalesHeader.Table.al touched by this PR (W1, NO, and others), suggesting an unrelated, mechanically-applied edit rather than an intentional fix. Recommend removing the redundant ReplacePostingDate and or clarifying the actual intent if this guard is meant to protect against a future refactor of the early exit.
| if ReplacePostingDate and ReplaceDocDate and ("Document Date" <> PostingDateReq) then begin | |
| if ReplaceDocDate and ("Document Date" <> PostingDateReq) then begin |
Agent judgement — not directly backed by a BCQuality knowledge article.
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
…Extract-NL-customization-to-object-extensions-v2
| } | ||
| } | ||
|
|
||
| procedure UpdateElecTaxDeclCategoryCode() |
There was a problem hiding this comment.
VATStatementLineNL.TableExt widens UpdateElecTaxDeclCategoryCode from a local procedure in the original full-object NL override to a public tableextension procedure, but it is only invoked from the companion VATStatementLineNL.Codeunit.al within the same app.
Publishing it needlessly turns an internal helper into an external contract that must now be preserved across future refactors.
| procedure UpdateElecTaxDeclCategoryCode() | |
| internal procedure UpdateElecTaxDeclCategoryCode() |
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| UpdateBankAccountsQst: Label 'Do you want to update the bank accounts for this customer to reflect the new value of %1?', Comment = '%1 = Field Caption'; | ||
| PartnerTypeMismatchQst: Label 'The Partner Type does not match the Partner Type defined in Transaction Mode. Do you still want to change the Partner Type?'; | ||
|
|
||
| [Scope('OnPrem')] |
There was a problem hiding this comment.
CustomerNL.TableExt widens UpdateCustomerBankAccounts from a local procedure in the original full-object NL override to a published, non-local procedure marked only with [Scope('OnPrem')], even though every call site remains inside the same tableextension.
That turns an implementation detail into a supported API surface for no functional reason, freezing a contract that was never meant to be external.
Suggested fix (apply manually — could not be anchored as a one-click suggestion):
[Scope('OnPrem')]
local procedure UpdateCustomerBankAccounts(UseFieldCaption: Text[250])Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
…Extract-NL-customization-to-object-extensions-v2
| { | ||
| addafter("Industrial Classification") | ||
| { | ||
| field("Fiscal Entity No."; Rec."Fiscal Entity No.") |
There was a problem hiding this comment.
The new namespaced NL layer repeatedly adds unaffixed members to standard objects, for example field(11400; "Cash Journal"; ...) in src/Layers/NL/BaseApp/Local/Foundation/AuditCodes/SourceCodeSetupNL.TableExt.al:14, field("Fiscal Entity No."; ...) in src/Layers/NL/BaseApp/Local/Foundation/Company/CompanyInformationNL.PageExt.al:13, and action("Post Code Updates") in src/Layers/NL/BaseApp/Local/RoleCenters/AdministratorMainRCNL.PageExt.al:15. A two-level namespace only replaces the owned object affix; fields, controls, and actions added to base objects still need the registered member affix.
Knowledge:
- microsoft/knowledge/appsource/two-level-namespace-replaces-object-affix-not-extension-member-affix.md
- microsoft/knowledge/appsource/object-affixes-prevent-collisions.md
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.12.4
|
The public IntegrationEvent Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.12.4 |
| end; | ||
| } | ||
| field(11000002; "Currency Euro"; Code[10]) | ||
| { |
There was a problem hiding this comment.
The Currency Euro OnValidate path dead-ends with a plain Error even though the code already knows the immediate
Recommendation:
- when Local Currency is Euro, Currency Euro must be cleared. Raise an ErrorInfo with a Fix-it action so the user can apply the correction in one step instead of dismissing a blocking dialog.
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.12.4
| } | ||
|
|
||
| var | ||
| TransactionModeAccountTypeErrorQst: Label '%1 can only be filled in when %2 %3 is equal to Customer or Vendor.', Comment = '%1 - Field Caption of the field causing the error, %2 - Field Caption of the Account Type field, %3 - Field Caption of the Bal. Account Type field'; |
There was a problem hiding this comment.
The validation error text on GenJournalLineNL.TableExt.al says Transaction Mode Code is allowed only for Customer or Vendor, but the surrounding TableRelation and lookup logic also accept Employee. Update the message so users who hit this error are told the real set of supported account types.
| TransactionModeAccountTypeErrorQst: Label '%1 can only be filled in when %2 %3 is equal to Customer or Vendor.', Comment = '%1 - Field Caption of the field causing the error, %2 - Field Caption of the Account Type field, %3 - Field Caption of the Bal. Account Type field'; | |
| TransactionModeAccountTypeErrorQst: Label '%1 can only be filled in when %2 %3 is equal to Customer, Vendor, or Employee.', Comment = '%1 - Field Caption of the field causing the error, %2 - Field Caption of the Account Type field, %3 - Field Caption of the Bal. Account Type field'; |
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.12.4
|
The touched Knowledge: Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.12.4 |
|
|
||
| tableextension 11382 "G/L Entry NL" extends "G/L Entry" | ||
| { | ||
| fields |
There was a problem hiding this comment.
src/Layers/NL/BaseApp/Local/Finance/GeneralLedger/Ledger/GLEntryNL.TableExt.al reintroduces field 11301 Open (moved verbatim, including its InitValue = true, from the base G/L Entry table which had the same field removed in this diff) as a new tableextension field, but the NL upgrade work added in this PR only registers upgrade tags for Local SEPA Instr. Priority and Elec. Tax Declaration Setup. Moving a field's ownership from a base table to a table extension does not automatically carry over existing row values; without a tagged upgrade step, pre-upgrade G/L Entry rows will read back the Boolean default false instead of their real historical Open value.
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.12.4
What & why
Linked work
Fixes AB#640601
How I validated this
What I tested and the outcome (required — be specific: scenarios, commands, screenshots for UI changes)
Risk & compatibility