Skip to content

[W1] [Tables] [Sales Line] + [Purchase Line] Add OnBeforeEnsurePositiveLineNo event to allow controlled opt-out (BC 27.3 regression) [MultiObjects] #29662

@pri-kise

Description

@pri-kise

Why do you need this change?

Objects / code locations

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    SCMGitHub request for SCM areaextensibility-enhancementNew feature or request related to extensibilityships-in-future-updateFix ships in a future update

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions