Address review: notification recall defect is a lost identity, not an unassigned or generated Id

- notification-recall-needs-known-id: the defect is a Recall() whose Id
  cannot be the sent one (fresh local Notification, new CreateGuid at
  recall time) while neither the sent instance nor its Id is kept. A
  retained global instance (CreateGuid once in OnOpenPage, or Id left for
  Send to assign), a generated Id saved after Send and reassigned before
  Recall, and correctly tracked per-record Ids are explicitly not findings.
  Findings require evidence that the recalled identity differs from or
  cannot recover the sent identity. Notification Lifecycle Mgt. is
  recommended for per-record tracking, not mandatory. Cites VAT Bus. Post.
  Grp. Part, Certificate, and Data Search Lines, and the lifecycle
  helper's Send-then-read-Id sequence.
- good sample: adds a page with a retained global Notification (CreateGuid
  in OnOpenPage, Send in an action, Recall in a later action and
  OnClosePage) and a pageextension that saves the Send-assigned Id and
  recalls it from a later action. Bad sample comments name the lost
  identity.
- al-ui-review: notification cue requires that evidence and lists the
  retained-instance, saved-Id, and direct per-record tracking controls as
  exclusions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Michael Dieringer 2026-10-05 16:05:59 +02:00
parent a37f45ada4
commit cff8917ecb
4 changed files with 144 additions and 12 deletions

View file

@ -22,3 +22,124 @@ pageextension 50720 "Sample Customer Card Ext" extends "Customer Card"
var
NoCreditLimitMsg: Label 'This customer has no credit limit.';
}
page 50721 "Sample Credit Review"
{
PageType = Card;
SourceTable = Customer;
Caption = 'Credit Review';
layout
{
area(Content)
{
field("No."; Rec."No.")
{
ApplicationArea = All;
ToolTip = 'Specifies the number of the customer.';
}
}
}
actions
{
area(Processing)
{
action(FlagForReview)
{
ApplicationArea = All;
Caption = 'Flag for Review';
ToolTip = 'Shows a reminder that this customer needs a credit review.';
trigger OnAction()
begin
if ReviewNotification.Recall() then;
ReviewNotification.Message := ReviewNeededMsg;
ReviewNotification.Scope := NotificationScope::LocalScope;
ReviewNotification.Send();
end;
}
action(ClearReviewFlag)
{
ApplicationArea = All;
Caption = 'Clear Review Flag';
ToolTip = 'Removes the credit review reminder.';
trigger OnAction()
begin
// The same global instance that was sent carries its Id here.
if ReviewNotification.Recall() then;
end;
}
}
}
trigger OnOpenPage()
begin
// A generated Id is fine: it is assigned once and kept with the instance.
ReviewNotification.Id := CreateGuid();
end;
trigger OnClosePage()
begin
if ReviewNotification.Recall() then;
end;
var
ReviewNotification: Notification;
ReviewNeededMsg: Label 'This customer needs a credit review.';
}
pageextension 50722 "Sample Customer List Ext" extends "Customer List"
{
actions
{
addlast(Processing)
{
action(SampleShowStatementReminder)
{
ApplicationArea = All;
Caption = 'Show Statement Reminder';
ToolTip = 'Shows a reminder to send statements to the selected customers.';
trigger OnAction()
var
ReminderNotification: Notification;
begin
RecallStatementReminder();
ReminderNotification.Message := StatementReminderMsg;
ReminderNotification.Scope := NotificationScope::LocalScope;
ReminderNotification.Send();
// Send assigned the Id; saving it lets a later action recall it.
LastReminderNotificationId := ReminderNotification.Id;
end;
}
action(SampleDismissStatementReminder)
{
ApplicationArea = All;
Caption = 'Dismiss Statement Reminder';
ToolTip = 'Removes the statement reminder.';
trigger OnAction()
begin
RecallStatementReminder();
end;
}
}
}
local procedure RecallStatementReminder()
var
ReminderNotification: Notification;
begin
if IsNullGuid(LastReminderNotificationId) then
exit;
ReminderNotification.Id := LastReminderNotificationId;
if ReminderNotification.Recall() then;
Clear(LastReminderNotificationId);
end;
var
LastReminderNotificationId: Guid;
StatementReminderMsg: Label 'Remember to send statements to the selected customers.';
}