Skip to content

[Event Request] procedure RecreateSalesLinesHandleSupplementTypes in table 36 "Sales Header" #30335

Description

@Simon110394

Why do you need this change?

We need an event inside the procedure RecreateSalesLinesHandleSupplementTypes, in order to be able to add a custom condition before running CreateSalesLine().

Managing an IsHandled parameter is the only way to skip CreateSalesLine() (when a particular custom condition is satisfied) and execute an alternative custom implementation instead.

At the moment there are no existing extensibility points that allow partners to replace the sales line recreation logic at this specific location.

Describe the request

In procedure RecreateSalesLinesHandleSupplementTypes of table 36 "Sales Header" we need an event:

[IntegrationEvent(false, false)]
local procedure OnBeforeRecreateSalesLine(var IsHandled: Boolean; var SalesLine: Record "Sales Line"; var TempSalesLine: Record "Sales Line" temporary; var SalesHeader: Record "Sales Header")
begin
end;

Changes between **:

local procedure RecreateSalesLinesHandleSupplementTypes(var TempSalesLine: Record "Sales Line" temporary; var ExtendedTextAdded: Boolean; var TempItemChargeAssgntSales: Record "Item Charge Assignment (Sales)" temporary; var TempInteger: Record "Integer" temporary)
var
    TransferExtendedText: Codeunit "Transfer Extended Text";
    IsHandled: Boolean;
    ShouldCreateSalesLine: Boolean;
begin
    IsHandled := false;
    OnBeforeRecreateSalesLinesHandleSupplementTypes(TempSalesLine, IsHandled);
    if IsHandled then
        exit;

    ShouldCreateSalesLine := not TempSalesLine.IsExtendedText();
    OnRecreateSalesLinesHandleSupplementTypesOnAfterCalcShouldCreateSalesLine(TempSalesLine, ShouldCreateSalesLine, SalesLine);

    if ShouldCreateSalesLine then begin
        **IsHandled := false;
        OnBeforeRecreateSalesLine(IsHandled, SalesLine, TempSalesLine, Rec);
        if not IsHandled then**
            CreateSalesLine(TempSalesLine);

        ExtendedTextAdded := false;
        OnAfterRecreateSalesLine(SalesLine, TempSalesLine, Rec);

        if SalesLine.Type = SalesLine.Type::Item then
            RecreateSalesLinesFillItemChargeAssignment(SalesLine, TempSalesLine, TempItemChargeAssgntSales);

        if SalesLine.Type = SalesLine.Type::"Charge (Item)" then begin
            TempInteger.Init();
            TempInteger.Number := SalesLine."Line No.";
            TempInteger.Insert();
        end;

        OnRecreateSalesLinesHandleSupplementTypesOnAfterCreateSalesLine(Rec, SalesLine, TempSalesLine);
    end else
        if not ExtendedTextAdded then begin
            TransferExtendedText.SalesCheckIfAnyExtText(SalesLine, true);
            TransferExtendedText.InsertSalesExtText(SalesLine);
            OnAfterTransferExtendedTextForSalesLineRecreation(SalesLine, TempSalesLine);

            SalesLine.FindLast();
            ExtendedTextAdded := true;
        end;

    OnAfterRecreateSalesLinesHandleSupplementTypes(Rec);
end;

Existing alternatives reviewed

We evaluated the existing extensibility points in RecreateSalesLinesHandleSupplementTypes(), including:

OnBeforeRecreateSalesLinesHandleSupplementTypes
OnAfterRecreateSalesLine
OnRecreateSalesLinesHandleSupplementTypesOnAfterCreateSalesLine

None of these events allow partners to conditionally replace or bypass the call to:

CreateSalesLine(TempSalesLine);

OnBeforeRecreateSalesLinesHandleSupplementTypes is raised before the procedure determines whether a sales line or extended text should be recreated, making it too early for this scenario.

OnAfterRecreateSalesLine and OnRecreateSalesLinesHandleSupplementTypesOnAfterCreateSalesLine are raised after the sales line has already been created, so they cannot prevent or replace the standard creation logic.

Therefore, there is currently no extensibility point immediately before CreateSalesLine() that allows partners to execute an alternative implementation.

Why an IsHandled event is required

A regular integration event is not sufficient for this scenario.

Under specific business conditions based on extension fields, our customization must completely replace the standard CreateSalesLine() logic with a custom implementation.

If the standard code continues to execute after our custom logic, the standard CreateSalesLine() would recreate the sales line again, overwriting the values and relationships established by the custom implementation.

Therefore, the only suitable extensibility pattern is an IsHandled event that allows subscribers to skip the standard call and execute an equivalent custom implementation.

Performance considerations

RecreateSalesLinesHandleSupplementTypes() is executed only during the recreation of sales lines after changes to document header fields that require line regeneration.

The proposed change introduces only:

one event publisher;
one Boolean check.

No additional database operations or calculations are introduced by the platform change itself.

Therefore, the expected performance impact is negligible, and any additional cost depends entirely on the subscriber implementation.

Data sensitivity review

The proposed event exposes only records that are already available within the sales line recreation process:

Sales Header
Sales Line
temporary Sales Line

No personally identifiable information, credentials, secrets, or new categories of sensitive data are exposed.

Therefore, the requested change does not introduce any security or data exposure concerns.

Multi-extension interaction review

The proposed event follows the standard IsHandled extensibility pattern.

As with any IsHandled event, multiple extensions could subscribe and set IsHandled := true, causing the standard CreateSalesLine() implementation to be skipped.

Potential conflicts include multiple extensions attempting to replace the sales line recreation logic.

This risk is considered acceptable because:

the event is narrowly scoped and affects only the creation of a single sales line during the recreation process;
extensions should set IsHandled := true only when intentionally replacing the standard implementation with an equivalent custom one;
without this extensibility point, partners are forced to duplicate a larger portion of the sales line recreation logic, significantly increasing maintenance and upgrade risks.

Clarification on existing extensibility point

We evaluated the existing event raised inside CreateSalesLine():

OnBeforeCreateSalesLine(var TempSalesLine; var IsHandled; var SalesHeader; var SalesLine)

This event is not sufficient for our scenario because it is raised inside CreateSalesLine(), after the procedure has already been invoked by RecreateSalesLinesHandleSupplementTypes().

Our requirement is to decide, before entering CreateSalesLine(), whether the standard sales line recreation should execute at all.

The custom decision depends on business conditions evaluated in the context of RecreateSalesLinesHandleSupplementTypes(). When those conditions are satisfied, our extension must bypass the entire standard CreateSalesLine() call and execute an alternative implementation instead.

Using the existing event inside CreateSalesLine() would still enter the standard procedure before the replacement logic takes control. We are requesting an extensibility point at the caller level so that partners can decide whether to invoke the standard procedure or replace it entirely.

Therefore, the requested event and the existing OnBeforeCreateSalesLine() event address different extensibility scenarios and are complementary rather than overlapping.

Confirmation of full replacement behavior

We confirm that when our extension sets IsHandled := true, it intentionally takes full ownership of the sales line recreation process.

The custom implementation will safely replace all behavior that would normally be performed by CreateSalesLine(), including:

initializing the sales line;
assigning the required field values;
performing all necessary validations;
inserting or updating the sales line as appropriate;
preserving all business rules required by the customized scenario.

The extension will not rely on any part of the skipped standard implementation.

The requested event is intended exclusively for scenarios where partners deliberately replace the complete sales line creation process under specific business conditions. It is not intended for partial customization of the standard implementation.

Loop execution impact confirmation

We confirm that the proposed event is intentionally raised once for each sales line processed by RecreateSalesLinesHandleSupplementTypes() and that this execution frequency is fully acceptable for our scenario.

The sales line recreation process is not part of a high-frequency transactional workload. It is executed only when sales lines must be regenerated following specific document header changes, and therefore the number of iterations is limited to the number of lines in the affected document.

The platform change itself introduces only:

one event publisher;
one Boolean (IsHandled) check per processed sales line.

No additional database operations or calculations are introduced by the base application.

Our subscriber implementation will remain lightweight. It will evaluate a simple custom condition based on extension fields and will only execute the alternative sales line creation logic when that condition is satisfied. In all other cases, it will leave IsHandled := false, allowing the standard implementation to continue unchanged.

We therefore confirm that the execution of this IsHandled event inside the sales line recreation loop is appropriate for our scenario, and that any additional processing performed by subscribers will be limited to the specific business cases that intentionally replace the standard sales line creation logic.
Internal work item: AB#641988

Metadata

Metadata

Assignees

No one assigned

    Labels

    SCMGitHub request for SCM areaevent-requestRequest for adding an event

    Type

    Fields

    No fields configured for Task.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions