mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-10-07 15:46:55 +01:00
Review feedback: the five value sets sharing exit(false) should be comma separated. Applied to the three that are pure field reads with no order dependency. The Get and the Blocked read keep their own value sets. The documentation guarantees that the first matching value set executes, which orders matching across separate value sets; it says nothing about evaluation within one comma-separated set, and the natural lowering of that is an equality-or chain — where AL's or does not short-circuit. Grouping the Get with the checks that must precede it would rest the sample's correctness on undocumented behaviour, which is the defect these two articles exist to prevent. Encodes the boundary in the Best Practice section so the grouping is applied where it is safe and not where it is not, and scopes the repeated-exit detection signal explicitly to nested chains so the case sample does not read as its own anti-pattern. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
52 lines
2.1 KiB
AL
52 lines
2.1 KiB
AL
codeunit 50542 "Perf Sample CaseChain Good"
|
|
{
|
|
procedure IsShippableLine(SalesLine: Record "Sales Line"): Boolean
|
|
var
|
|
Item: Record Item;
|
|
begin
|
|
// 'case false of' matches the value sets in order and stops at the first
|
|
// match, so each value set is reached only when the previous one passed —
|
|
// and Item.Get is never called for a non-item line.
|
|
case false of
|
|
// Pure field reads with no side effects and no order dependency, so
|
|
// they share one value set and one action.
|
|
(SalesLine.Type = SalesLine.Type::Item),
|
|
(SalesLine."No." <> ''),
|
|
(SalesLine."Qty. to Ship" > 0):
|
|
exit(false);
|
|
// These two keep their own value sets even though the action repeats:
|
|
// ordering across separate value sets is what the documentation
|
|
// guarantees. The Get must not run until the checks above pass, and
|
|
// Blocked must not be read until the Get succeeded.
|
|
Item.Get(SalesLine."No."):
|
|
exit(false);
|
|
(not Item.Blocked):
|
|
exit(false);
|
|
end;
|
|
exit(true);
|
|
end;
|
|
|
|
procedure FindOpenDocumentType(CustomerNo: Code[20]): Text
|
|
begin
|
|
// 'case true of' stops at the first condition that holds, so the later
|
|
// lookups never run once an earlier one matched.
|
|
case true of
|
|
HasOpenDocument(CustomerNo, "Sales Document Type"::Quote):
|
|
exit('Quote');
|
|
HasOpenDocument(CustomerNo, "Sales Document Type"::Order):
|
|
exit('Order');
|
|
HasOpenDocument(CustomerNo, "Sales Document Type"::Invoice):
|
|
exit('Invoice');
|
|
end;
|
|
exit('None');
|
|
end;
|
|
|
|
local procedure HasOpenDocument(CustomerNo: Code[20]; DocumentType: Enum "Sales Document Type"): Boolean
|
|
var
|
|
SalesHeader: Record "Sales Header";
|
|
begin
|
|
SalesHeader.SetRange("Document Type", DocumentType);
|
|
SalesHeader.SetRange("Sell-to Customer No.", CustomerNo);
|
|
exit(not SalesHeader.IsEmpty());
|
|
end;
|
|
}
|