-
Notifications
You must be signed in to change notification settings - Fork 688
Description
Why do you need this change?
Objects / code locations
- Table Sales Line procedure
EnsurePositiveLineNo()
https://github.com/StefanMaron/MSDyn365BC.Code.History/blob/w1-27/BaseApp/Source/Base%20Application/Sales/Document/SalesLine.Table.al - Table Purchase Line procedure
EnsurePositiveLineNo()
https://github.com/StefanMaron/MSDyn365BC.Code.History/blob/w1-27/BaseApp/Source/Base%20Application/Purchases/Document/PurchaseLine.Table.al
Business scenario / justification
Our extension creates additional document lines that are logically attached to a normal line (child/attached lines). To guarantee correct ordering and to avoid collisions with existing positive line numbers, they are currently created with a negative Line No..
Starting with Business Central 27.3 (cumulative update), validation was introduced/strengthened via EnsurePositiveLineNo() such that negative line numbers are no longer accepted in this flow. This change causes a breaking/regression behavior for existing solutions that previously worked and rely on negative line numbers for this attachment pattern.
We plan to change the design, but replacing this approach requires a major refactor (line numbering strategy, ordering, upgrade/migration considerations, and testing across many document scenarios). This cannot be implemented fast enough to mitigate the immediate impact of 27.3.
What we are requesting (extensibility change)
Add an event publisher at the beginning of EnsurePositiveLineNo() in both tables to allow controlled opt-out of the new validation:
- Proposed event pattern: OnBefore with
IsHandled - Behavior: If
IsHandled = true,EnsurePositiveLineNo()exits without enforcing the positive line no. requirement.
Example signature (illustrative):
OnBeforeEnsurePositiveLineNo(var SalesLine: Record "Sales Line"; var IsHandled: Boolean)OnBeforeEnsurePositiveLineNo(var PurchaseLine: Record "Purchase Line"; var IsHandled: Boolean)
Risk mitigation / why this won't become a generic override
We understand the concerns around the IsHandled pattern and would use this in a strictly controlled way:
- We would only bypass the logic for lines created/managed by our extension (verified via our own markers/fields and controlled entry points).
- We would only use it for the specific negative line-number scenario needed for the attached-line pattern.
- We would implement the subscriber using manual event binding only, so the behavior is explicitly enabled and scoped by configuration and cannot accidentally apply in other customer environments.
Alternative solutions (acceptable options to avoid IsHandled)
If an IsHandled event is not desired, an alternative extensibility approach that would also solve the issue:
- Introduce a new global variable to skip the validation logic (default
false) plus a dedicated setter procedure on the table, so extensions can opt in in a controlled way; or - Provide a purpose-driven extensibility concept that supports ÔÇ£attached/linked linesÔÇØ without requiring negative line numbering.
Describe the request
Option A Add IsHandled event in EnsurePositiveLineNo()
local procedure EnsurePositiveLineNo()
var
SalesLine: Record "Sales Line";
MaxLineNo: Integer;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeEnsurePositiveLineNo(Rec, IsHandled);
if IsHandled then
exit;
if "Line No." < 0 then begin
SalesLine.SetRange("Document Type", "Document Type");
SalesLine.SetRange("Document No.", "Document No.");
if SalesLine.FindLast() then
MaxLineNo := SalesLine."Line No.";
"Line No." := MaxLineNo + 10000;
end;
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeEnsurePositiveLineNo(var SalesLine: Record "Sales Line"; var IsHandled: Boolean)
begin
end; local procedure EnsurePositiveLineNo()
var
PurchaseLine: Record "Purchase Line";
MaxLineNo: Integer;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeEnsurePositiveLineNo(Rec, IsHandled);
if IsHandled then
exit;
if "Line No." < 0 then begin
PurchaseLine.SetRange("Document Type", "Document Type");
PurchaseLine.SetRange("Document No.", "Document No.");
if PurchaseLine.FindLast() then
MaxLineNo := PurchaseLine."Line No.";
"Line No." := MaxLineNo + 10000;
end;
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeEnsurePositiveLineNo(var PurchaseLine: Record "Purchase Line"; var IsHandled: Boolean)
begin
end;Option B: Global variable + setter procedure (skip flag)
var
SkipEnsurePositiveLineNo: Boolean;
procedure SetSkipEnsurePositiveLineNo(Skip: Boolean)
begin
SkipEnsurePositiveLineNo := Skip;
end;
local procedure EnsurePositiveLineNo()
var
SalesLine: Record "Sales Line";
MaxLineNo: Integer;
begin
if SkipEnsurePositiveLineNo then
exit;
if "Line No." < 0 then begin
SalesLine.SetRange("Document Type", "Document Type");
SalesLine.SetRange("Document No.", "Document No.");
if SalesLine.FindLast() then
MaxLineNo := SalesLine."Line No.";
"Line No." := MaxLineNo + 10000;
end;
end; var
SkipEnsurePositiveLineNo: Boolean;
procedure SetSkipEnsurePositiveLineNo(Skip: Boolean)
begin
SkipEnsurePositiveLineNo := Skip;
end;
local procedure EnsurePositiveLineNo()
var
PurchaseLine: Record "Purchase Line";
MaxLineNo: Integer;
begin
if SkipEnsurePositiveLineNo then
exit;
if "Line No." < 0 then begin
PurchaseLine.SetRange("Document Type", "Document Type");
PurchaseLine.SetRange("Document No.", "Document No.");
if PurchaseLine.FindLast() then
MaxLineNo := PurchaseLine."Line No.";
"Line No." := MaxLineNo + 10000;
end;
end;(Disclaimer: AI Helped to write this request, since my english isn't this good)
Internal work item: AB#620458