Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@ tableextension 31028 "Cash Document Line CZZ" extends "Cash Document Line CZP"
var
SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ";
PurchAdvLetterHeaderCZZ: Record "Purch. Adv. Letter Header CZZ";
IsHandled: Boolean;
begin
IsHandled := false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟠\ High\ Severity\ —\ Events}$

The new OnBeforeValidateAdvanceLetterNoCZZ IsHandled hook wraps the entire OnValidate trigger of "Advance Letter No. CZZ", so a subscriber that sets IsHandled := true silently skips all referential and consistency validation below it: the Gen. Document Type payment check, the Document Type/Account Type case validation, the Get()/TestField() cross-checks against the sales/purchase advance letter header (Bill-to Customer No./Pay-to Vendor No., Currency Code), and the Amount/Dimension Set ID defaulting. Per BCQuality guidance, IsHandled should scope only a safe, side-effect-free value calculation - critical referential-integrity validation should run unconditionally, or be exposed via a separate OnAfter... event, not be bypassable via IsHandled.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.31.4

OnBeforeValidateAdvanceLetterNoCZZ(Rec, xRec, IsHandled);
if IsHandled then
exit;

if "Advance Letter No. CZZ" <> '' then begin
TestField("Gen. Document Type", "Gen. Document Type"::Payment);
case "Document Type" of
Expand Down Expand Up @@ -59,7 +65,13 @@ tableextension 31028 "Cash Document Line CZZ" extends "Cash Document Line CZP"
var
SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ";
PurchAdvLetterHeaderCZZ: Record "Purch. Adv. Letter Header CZZ";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeLookupAdvanceLetterNoCZZ(Rec, IsHandled);
if IsHandled then
exit;

TestField("Gen. Document Type", "Gen. Document Type"::Payment);
if not ((("Document Type" = "Document Type"::Receipt) and ("Account Type" = "Account Type"::Customer)) or
(("Document Type" = "Document Type"::Withdrawal) and ("Account Type" = "Account Type"::Vendor))) then
Expand Down Expand Up @@ -145,4 +157,14 @@ tableextension 31028 "Cash Document Line CZZ" extends "Cash Document Line CZP"
("Applies-To Doc. Type" = "Applies-To Doc. Type"::Payment) and
("Applies-To Doc. No." <> ''));
end;

[IntegrationEvent(false, false)]
local procedure OnBeforeValidateAdvanceLetterNoCZZ(var CashDocumentLineCZP: Record "Cash Document Line CZP"; xCashDocumentLineCZP: Record "Cash Document Line CZP"; var IsHandled: Boolean)
begin
end;

[IntegrationEvent(false, false)]
local procedure OnBeforeLookupAdvanceLetterNoCZZ(var CashDocumentLineCZP: Record "Cash Document Line CZP"; var IsHandled: Boolean)
begin
end;
}
Original file line number Diff line number Diff line change
Expand Up @@ -202,16 +202,20 @@ codeunit 11725 "Cash Document-Release CZP"
local procedure CheckMandatoryFields(CashDocumentHeaderCZP: Record "Cash Document Header CZP")
var
SkipPaymentPurposeTestField: Boolean;
SkipAmountsTestFields: Boolean;
begin
SkipPaymentPurposeTestField := false;
OnBeforeCheckMandatoryFields(CashDocumentHeaderCZP, SkipPaymentPurposeTestField);
SkipAmountsTestFields := false;
OnBeforeCheckMandatoryFields(CashDocumentHeaderCZP, SkipPaymentPurposeTestField, SkipAmountsTestFields);

CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."No.");
CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Posting Date");
CashDocumentHeaderCZP.VATRounding();
CashDocumentHeaderCZP.CalcFields(CashDocumentHeaderCZP."Amount Including VAT", CashDocumentHeaderCZP."Amount Including VAT (LCY)");
CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Amount Including VAT");
CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Amount Including VAT (LCY)");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟡\ Medium\ Severity\ —\ Performance}$

The new SkipAmountsTestFields extension point lets a subscriber skip the two TestField checks on the Amount Including VAT FlowFields, but CalcFields for both FlowFields still runs unconditionally beforehand. When SkipAmountsTestFields is set true, this performs a database-backed FlowField recalculation whose result is now never used. Move CalcFields inside the if not SkipAmountsTestFields then block so the expensive read is skipped together with the validation it exists to support.

Suggested fix (apply manually — could not be anchored as a one-click suggestion):

        CashDocumentHeaderCZP.VATRounding();
        if not SkipAmountsTestFields then begin
            CashDocumentHeaderCZP.CalcFields(CashDocumentHeaderCZP."Amount Including VAT", CashDocumentHeaderCZP."Amount Including VAT (LCY)");
            CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Amount Including VAT");
            CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Amount Including VAT (LCY)");
        end;

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.31.4

if not SkipAmountsTestFields then begin
CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Amount Including VAT");
CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Amount Including VAT (LCY)");
end;
CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Document Date");
if not SkipPaymentPurposeTestField then
CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Payment Purpose");
Expand Down Expand Up @@ -373,7 +377,7 @@ codeunit 11725 "Cash Document-Release CZP"
end;

[IntegrationEvent(false, false)]
local procedure OnBeforeCheckMandatoryFields(CashDocumentHeaderCZP: Record "Cash Document Header CZP"; var SkipPaymentPurposeTestField: Boolean)
local procedure OnBeforeCheckMandatoryFields(CashDocumentHeaderCZP: Record "Cash Document Header CZP"; var SkipPaymentPurposeTestField: Boolean; var SkipAmountsTestFields: Boolean)
begin
end;
}
Loading