Skip to content

[Event Request] codeunit 99000787 "Create Prod. Order Lines" #30337

Description

@Simon110394

Why do you need this change?

We need a new event in the CreateProdOrderLine procedure to allow partners to completely replace the standard processing of the Source Type = Item branch under specific business conditions.

Our customization needs to:

execute an alternative production order line creation process;
determine the value of the ErrorOccured parameter according to custom logic;
prevent the standard item-line creation from executing afterwards.

The existing event

OnCreateProdOrderLineOnBeforeInitProdOrderLine(var InsertNew: Boolean)

is useful for influencing the standard flow, but it is intentionally not designed to replace it.

It does not provide:

an IsHandled parameter to bypass the standard processing;
access to the ErrorOccured parameter returned by CreateProdOrderLine().

As a result, there is currently no extensibility point that allows an extension to safely replace the complete Source Type = Item implementation.

Describe the request

In procedure CreateProdOrderLine of codeunit 99000787 "Create Prod. Order Lines" we request a new integration event:

[IntegrationEvent(false, false)]
local procedure OnBeforeCreateProdOrderLineItem(
    var IsHandled: Boolean;
    var ErrorOccured: Boolean;
    ProdOrder: Record "Production Order")
begin
end;

Changes between **:

local procedure CreateProdOrderLine(ProdOrder: Record "Production Order"; VariantCode: Code[10]; var ErrorOccured: Boolean)
    var
        SalesHeader: Record "Sales Header";
		**IsHandled: Boolean;**
    begin
        DeleteLinesForProductionOrder(ProdOrder);

        NextProdOrderLineNo := 10000;

        InsertNew := false;

        case ProdOrder."Source Type" of
            ProdOrder."Source Type"::Item:
                begin
                    OnCreateProdOrderLineOnBeforeInitProdOrderLine(InsertNew);

                     **IsHandled := false;
                      OnBeforeCreateProdOrderLineItem(
                                      IsHandled,
                                     ErrorOccured,
                                     ProdOrder);

                                 if not IsHandled then begin**
						InitProdOrderLine(ProdOrder."Source No.", VariantCode, ProdOrder."Location Code");
						ProdOrderLine.Description := ProdOrder.Description;
						ProdOrderLine."Description 2" := ProdOrder."Description 2";
						ProdOrderLine.Validate(Quantity, ProdOrder.Quantity);
						ProdOrderLine.UpdateDatetime();
						if SalesLineIsSet then
							CopyDimFromSalesLine(SalesLine, ProdOrderLine);
						OnBeforeProdOrderLineInsert(ProdOrderLine, ProdOrder, SalesLineIsSet, SalesLine);
						ProdOrderLine.Insert();
						if ProdOrderLine.HasErrorOccured() then
							ErrorOccured := true;
					**end;**		

                    OnAfterProdOrderLineInsert(ProdOrder, ProdOrderLine, NextProdOrderLineNo);
                end;
            ProdOrder."Source Type"::Family:
                if not CopyFromFamily() then
                    ErrorOccured := true;
            ProdOrder."Source Type"::"Sales Header":
                begin
                    InsertNew := true;
                    if ProdOrder.Status <> ProdOrder.Status::Simulated then
                        SalesHeader.Get(SalesHeader."Document Type"::Order, ProdOrder."Source No.")
                    else
                        SalesHeader.Get(SalesHeader."Document Type"::Quote, ProdOrder."Source No.");
                    if not CopyFromSalesOrder(SalesHeader) then
                        ErrorOccured := true;
                end;
        end;

        OnAfterCreateProdOrderLine(ProdOrder, VariantCode, ErrorOccured);
    end;

Existing extensibility options reviewed

We evaluated the existing extensibility points:

OnCreateProdOrderLineOnBeforeInitProdOrderLine
OnBeforeProdOrderLineInsert
OnAfterProdOrderLineInsert
OnAfterCreateProdOrderLine

None of these events allows an extension to replace the complete implementation of the Source Type = Item branch.

Specifically:

OnCreateProdOrderLineOnBeforeInitProdOrderLine cannot prevent the subsequent standard processing;
OnBeforeProdOrderLineInsert is raised after the production order line has already been initialized;
OnAfterProdOrderLineInsert is raised after the line has already been created;
OnAfterCreateProdOrderLine is raised after the entire process has completed.

Therefore, none of the existing events allows partners to execute an alternative implementation while preventing the standard one.

Why IsHandled is required

A regular integration event would not satisfy this scenario.

Under specific business conditions, our extension needs to completely replace the standard Source Type = Item implementation.

If the standard code continues executing after our custom logic:

the production order line would be initialized and inserted twice;
the value assigned to ErrorOccured by the custom implementation could be overwritten by the standard logic.

For this reason, an IsHandled pattern is required so that subscribers can intentionally replace the standard implementation.

Why ErrorOccured is required

The subscriber must be able to set the ErrorOccured parameter because it represents the outcome of the production order line creation.

When replacing the standard implementation, the extension performs its own validations and line creation and must be able to report whether the custom process succeeded or failed.

Without exposing ErrorOccured, the custom implementation cannot correctly communicate its result back to CreateProdOrderLine().

Performance assessment

CreateProdOrderLine is executed only during creation or regeneration of production orders.

The proposed event is raised only for the Source Type = Item scenario and introduces only:

one event invocation;
one Boolean check.

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

Therefore, the expected performance impact is negligible.

Data sensitivity assessment

The event exposes only:

ProdOrder
IsHandled
ErrorOccured

These values are already available within the standard execution context and do not expose any new categories of sensitive information.

Multi-extension interaction

This event intentionally follows the standard IsHandled extensibility pattern used throughout Business Central.

If multiple extensions subscribe and set IsHandled := true, only one extension should take ownership of replacing the standard implementation.

Similarly, multiple subscribers may assign different values to ErrorOccured, with the last subscriber determining the final result.

This behavior is consistent with existing IsHandled events in the base application and is acceptable because only extensions intentionally replacing the standard Source Type = Item processing should set IsHandled := true.

IsHandled bypass confirmation

We confirm that setting IsHandled := true is intended to completely bypass the standard Source Type = Item implementation.

This includes skipping the entire standard processing performed in that branch, including:

initialization of the production order line (InitProdOrderLine);
assignment of the standard field values;
quantity validation;
copying dimensions from the sales line when applicable;
execution of OnBeforeProdOrderLineInsert;
insertion of the production order line;
propagation of ErrorOccured through ProdOrderLine.HasErrorOccured().

This behavior is intentional and required for our customization.

Replacement scope

When our extension sets IsHandled := true, it takes full ownership of the item-line creation process.

The custom implementation will perform all business logic required for the specific scenario, including:

creating and initializing the production order line when appropriate;
executing any required validations;
inserting the production order line when required;
determining and assigning the final value of ErrorOccured.

In other words, the extension completely replaces the skipped standard implementation and does not rely on any of the logic that has been bypassed.

The requested event is therefore intended only for scenarios where an extension deliberately replaces the complete Source Type = Item processing, rather than partially modifying the standard behavior.

Refactoring acceptance

We confirm that we fully accept refactoring the current Source Type = Item implementation into a dedicated local procedure if this better aligns with the extensibility guidelines for the base application.

Our request is not tied to the current inline implementation. The proposed event can be raised immediately before an extracted helper procedure containing the existing standard item-line creation logic.

For example, the implementation could be refactored as follows:

case ProdOrder."Source Type" of
    ProdOrder."Source Type"::Item:
        begin
            OnCreateProdOrderLineOnBeforeInitProdOrderLine(InsertNew);

            IsHandled := false;
            OnBeforeCreateProdOrderLineItem(
                IsHandled,
                ErrorOccured,
                ProdOrder);

            if not IsHandled then
                CreateProdOrderLineFromItem(
                    ProdOrder,
                    VariantCode,
                    ErrorOccured);

            OnAfterProdOrderLineInsert(ProdOrder, ProdOrderLine, NextProdOrderLineNo);
        end;

where CreateProdOrderLineFromItem(...) contains the current standard implementation that performs:

InitProdOrderLine();
initialization of the production order line fields;
quantity validation;
dimension copying;
OnBeforeProdOrderLineInsert;
record insertion;
propagation of ErrorOccured through ProdOrderLine.HasErrorOccured().

This refactoring does not change the intent of the request.

Our requirement is simply to have an extensibility point immediately before the standard Source Type = Item implementation, regardless of whether that implementation remains inline or is extracted into a dedicated local procedure.

When IsHandled := true, the subscriber intentionally takes full ownership of the item-line creation process and safely replaces all behavior contained in the extracted helper procedure.
Internal work item: AB#641918

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