bcquality/microsoft/knowledge/data-modeling/check-blocked-in-referencing-code-not-in-master.good.al
Jesper Schulz-Wedde 766046b85d
Add data-modeling and appsource knowledge articles (MICROSOFT layer) (#65)
Author 7 remedial BCQuality knowledge articles plus good/bad AL samples
(21 files) covering AL master-table and data-model design:

- data-modeling: master No. from number series in OnInsert; use codeunit
  "No. Series" not obsolete NoSeriesManagement; setup table is a singleton;
  set Last Date Modified in OnModify and OnRename; enforce Blocked in
  referencing code not in the master.
- style: ApplicationArea required on page controls (AS0062).
- appsource: object affixes prevent collisions (AS0011).

Clean-room authored from own BC knowledge; specifics verified against public
sources only (learn.microsoft.com, microsoft/BCApps). Introduces two new
domains (data-modeling, appsource).

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-13 10:35:31 +02:00

84 lines
1.9 KiB
AL

table 50370 "Loyalty Member"
{
Caption = 'Loyalty Member';
DataClassification = CustomerContent;
fields
{
field(1; "No."; Code[20])
{
Caption = 'No.';
}
field(10; Name; Text[100])
{
Caption = 'Name';
}
// Blocked is inert data here: the master carries the flag but no logic.
field(20; Blocked; Boolean)
{
Caption = 'Blocked';
}
}
keys
{
key(PK; "No.")
{
Clustered = true;
}
}
}
table 50371 "Loyalty Point Entry"
{
Caption = 'Loyalty Point Entry';
DataClassification = CustomerContent;
fields
{
field(1; "Entry No."; Integer)
{
Caption = 'Entry No.';
AutoIncrement = true;
}
field(10; "Member No."; Code[20])
{
Caption = 'Member No.';
TableRelation = "Loyalty Member"."No.";
trigger OnValidate()
var
LoyaltyMember: Record "Loyalty Member";
begin
if "Member No." = '' then
exit;
// Enforcement lives at the point of use: reject a blocked master
// as soon as a line references it.
LoyaltyMember.Get("Member No.");
LoyaltyMember.TestField(Blocked, false);
end;
}
field(20; Points; Integer)
{
Caption = 'Points';
}
}
keys
{
key(PK; "Entry No.")
{
Clustered = true;
}
}
procedure Post()
var
LoyaltyMember: Record "Loyalty Member";
begin
// Re-check before committing the transaction, in case the member was
// blocked after the line was created.
LoyaltyMember.Get("Member No.");
LoyaltyMember.TestField(Blocked, false);
end;
}