Codeunit 99000809 Planning Line Management

App
Base Application
Namespace
Microsoft.Inventory.Planning
Versions
17-28

Procedures, 30Events, 49Obsolete, 22

Versions171819202122232425262728

Source29

Source in 29

src/Layers/W1/BaseApp/Inventory/Planning/PlanningLineManagement.Codeunit.al923 lines, Copyright (c) Microsoft Corporation. MIT

// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.Inventory.Planning;

using Microsoft.Foundation.UOM;
using Microsoft.Inventory;
using Microsoft.Inventory.BOM;
using Microsoft.Inventory.Item;
using Microsoft.Inventory.Location;
using Microsoft.Inventory.Requisition;
using Microsoft.Inventory.Tracking;

codeunit 99000809 "Planning Line Management"
{
#if not CLEAN28
    Permissions = TableData Microsoft.Manufacturing.Setup."Manufacturing Setup" = rm,
                  TableData Microsoft.Manufacturing.Routing."Routing Header" = r,
                  TableData Microsoft.Manufacturing.ProductionBOM."Production BOM Header" = r,
                  TableData Microsoft.Manufacturing.ProductionBOM."Production BOM Line" = r,
                  TableData Microsoft.Manufacturing.Document."Prod. Order Capacity Need" = rd,
                  TableData "Planning Component" = rimd,
                  TableData Microsoft.Manufacturing.Routing."Planning Routing Line" = rimd;
#else
    Permissions = tabledata "Planning Component" = rimd;
#endif

    trigger OnRun()
    begin
    end;

    var
        Item: Record Item;
        SKU: Record "Stockkeeping Unit";
        ReqLine: Record "Requisition Line";
        AsmBOMComp: array[50] of Record "BOM Component";
        PlanningComponent: Record "Planning Component";
        TempPlanningComponent: Record "Planning Component" temporary;
        TempPlanningErrorLog: Record "Planning Error Log" temporary;
        UOMMgt: Codeunit "Unit of Measure Management";
        GetPlanningParameters: Codeunit "Planning-Get Parameters";
        LeadTimeMgt: Codeunit "Lead-Time Management";

        LineSpacing: array[50] of Integer;
        NextPlanningCompLineNo: Integer;
        Blocked: Boolean;
        PlanningResiliency: Boolean;
#pragma warning disable AA0074
#pragma warning disable AA0470
        Text000: Label 'BOM phantom structure for %1 is higher than 50 levels.';
        Text002: Label 'There is not enough space to insert lower level Make-to-Order lines.';
        Text014: Label 'Production BOM Header No. %1 used by Item %2 has BOM levels that exceed 50.';
        Text015: Label 'There is no more space to insert another line in the worksheet.';
#pragma warning restore AA0470
#pragma warning restore AA0074

    local procedure TransferAsmBOM(ParentItemNo: Code[20]; Level: Integer; Quantity: Decimal)
    var
        ParentItem: Record Item;
        CompSKU: Record "Stockkeeping Unit";
        Item2: Record Item;
        ReqQty: Decimal;
    begin
        PlanningComponent.LockTable();

        if Level > 50 then begin
            if PlanningResiliency then begin
                Item.Get(ReqLine."No.");
                TempPlanningErrorLog.SetError(
                  StrSubstNo(Text014, ReqLine."No.", ReqLine."No."),
                  Database::Item, Item.GetPosition());
            end;
            Error(
              Text000,
              ParentItemNo);
        end;

        if NextPlanningCompLineNo = 0 then begin
            PlanningComponent.SetRange("Worksheet Template Name", ReqLine."Worksheet Template Name");
            PlanningComponent.SetRange("Worksheet Batch Name", ReqLine."Journal Batch Name");
            PlanningComponent.SetRange("Worksheet Line No.", ReqLine."Line No.");
            if PlanningComponent.Find('+') then
                NextPlanningCompLineNo := PlanningComponent."Line No.";
            PlanningComponent.Reset();
        end;

        ParentItem.Get(ParentItemNo);

        AsmBOMComp[Level].SetRange("Parent Item No.", ParentItemNo);
        if AsmBOMComp[Level].Find('-') then
            repeat
                ReqQty := Quantity * AsmBOMComp[Level]."Quantity per";
                case AsmBOMComp[Level].Type of
                    AsmBOMComp[Level].Type::Item:
                        if ReqQty <> 0 then begin
                            if not IsPlannedAsmComp(PlanningComponent, ReqLine, AsmBOMComp[Level]) then begin
                                NextPlanningCompLineNo := NextPlanningCompLineNo + 10000;

                                PlanningComponent.Reset();
                                PlanningComponent.Init();
                                PlanningComponent.BlockDynamicTracking(Blocked);
                                PlanningComponent.SetRequisitionLine(ReqLine);
                                PlanningComponent."Worksheet Template Name" := ReqLine."Worksheet Template Name";
                                PlanningComponent."Worksheet Batch Name" := ReqLine."Journal Batch Name";
                                PlanningComponent."Worksheet Line No." := ReqLine."Line No.";
                                PlanningComponent."Line No." := NextPlanningCompLineNo;
                                PlanningComponent.Validate("Item No.", AsmBOMComp[Level]."No.");
                                PlanningComponent."Variant Code" := AsmBOMComp[Level]."Variant Code";
                                PlanningComponent."Location Code" := SKU."Components at Location";
                                PlanningComponent.Description := CopyStr(AsmBOMComp[Level].Description, 1, MaxStrLen(PlanningComponent.Description));
                                PlanningComponent."Planning Line Origin" := ReqLine."Planning Line Origin";
                                PlanningComponent.Validate("Unit of Measure Code", AsmBOMComp[Level]."Unit of Measure Code");
                                PlanningComponent."Quantity per" := Quantity * AsmBOMComp[Level]."Quantity per";
                                OnTransferAsmBOMOnBeforeGetDefaultBin(PlanningComponent, AsmBOMComp[Level], ReqLine);
                                PlanningComponent.GetDefaultBin();
                                PlanningComponent.Quantity := AsmBOMComp[Level]."Quantity per";
                                PlanningComponent.Position := AsmBOMComp[Level].Position;
                                PlanningComponent."Position 2" := AsmBOMComp[Level]."Position 2";
                                PlanningComponent."Position 3" := AsmBOMComp[Level]."Position 3";
                                PlanningComponent."Lead-Time Offset" := AsmBOMComp[Level]."Lead-Time Offset";
                                OnTransferASMBOMOnAfterSetAsmBOMComp(PlanningComponent);
                                PlanningComponent.Validate("Calculation Formula", PlanningComponent."Calculation Formula"::" ");
                                GetPlanningParameters.AtSKU(
                                  CompSKU,
                                  PlanningComponent."Item No.",
                                  PlanningComponent."Variant Code",
                                  PlanningComponent."Location Code");
                                if Item2.Get(PlanningComponent."Item No.") then
                                    PlanningComponent.Critical := Item2.Critical;

                                PlanningComponent."Flushing Method" := CompSKU."Flushing Method";
                                PlanningComponent."Ref. Order Type" := ReqLine."Ref. Order Type";
                                PlanningComponent."Ref. Order Status" := ReqLine."Ref. Order Status";
                                PlanningComponent."Ref. Order No." := ReqLine."Ref. Order No.";
                                OnBeforeInsertAsmPlanningComponent(ReqLine, AsmBOMComp[Level], PlanningComponent);
                                PlanningComponent.Insert();
                            end else begin
                                PlanningComponent.Reset();
                                PlanningComponent.BlockDynamicTracking(Blocked);
                                PlanningComponent.SetRequisitionLine(ReqLine);
                                PlanningComponent.Validate(
                                  "Quantity per",
                                  PlanningComponent."Quantity per" +
                                  Quantity *
                                  AsmBOMComp[Level]."Quantity per");
                                OnTransferAsmBOMOnBeforePlanningComponentModify(PlanningComponent);
                                PlanningComponent.Modify();
                            end;

                            // A temporary list of Planning Components handled is sustained:
                            TempPlanningComponent := PlanningComponent;
                            if not TempPlanningComponent.Insert() then
                                TempPlanningComponent.Modify();
                        end;
                    AsmBOMComp[Level].Type::" ":
                        begin
                            NextPlanningCompLineNo := NextPlanningCompLineNo + 10;
                            PlanningComponent.Reset();
                            PlanningComponent.Init();
                            PlanningComponent."Worksheet Template Name" := ReqLine."Worksheet Template Name";
                            PlanningComponent."Worksheet Batch Name" := ReqLine."Journal Batch Name";
                            PlanningComponent."Worksheet Line No." := ReqLine."Line No.";
                            PlanningComponent."Line No." := NextPlanningCompLineNo;
                            PlanningComponent.Description := CopyStr(AsmBOMComp[Level].Description, 1, MaxStrLen(PlanningComponent.Description));
                            PlanningComponent.Insert();
                            // A temporary list of Planning Components handled is sustained:
                            TempPlanningComponent := PlanningComponent;
                            if not TempPlanningComponent.Insert() then
                                TempPlanningComponent.Modify();
                        end;
                end;
            until AsmBOMComp[Level].Next() = 0;
    end;

    local procedure CalculateComponents()
    var
        PlanningAssignment: Record "Planning Assignment";
    begin
        PlanningComponent.SetRange("Worksheet Template Name", ReqLine."Worksheet Template Name");
        PlanningComponent.SetRange("Worksheet Batch Name", ReqLine."Journal Batch Name");
        PlanningComponent.SetRange("Worksheet Line No.", ReqLine."Line No.");

        if PlanningComponent.Find('-') then
            repeat
                PlanningComponent.BlockDynamicTracking(Blocked);
                PlanningComponent.SetRequisitionLine(ReqLine);
                OnCalculateComponentsOnbeforePlanningComponentModify(PlanningComponent);
                PlanningComponent.Modify();
                PlanningAssignment.ChkAssignOne(PlanningComponent."Item No.", PlanningComponent."Variant Code", PlanningComponent."Location Code", PlanningComponent."Due Date");
            until PlanningComponent.Next() = 0;
    end;

#if not CLEAN27
    [Obsolete('Moved to codeunit Planning Routing Management', '27.0')]
    procedure CalculateRoutingFromActual(PlanningRtngLine: Record Microsoft.Manufacturing.Routing."Planning Routing Line"; Direction: Option Forward,Backward; CalcStartEndDate: Boolean)
    var
        PlanningRoutingManagement: Codeunit Microsoft.Manufacturing.Routing.PlanningRoutingManagement;
    begin
        PlanningRoutingManagement.CalculateRoutingFromActual(ReqLine, PlanningRtngLine, Direction, CalcStartEndDate, PlanningResiliency);
    end;
#endif

#if not CLEAN27
    [Obsolete('Moved to codeunit Planning Routing Management', '27.0')]
    procedure CalculatePlanningLineDates(var ReqLine2: Record "Requisition Line")
    var
        PlanningRoutingManagement: Codeunit Microsoft.Manufacturing.Routing.PlanningRoutingManagement;
    begin
        PlanningRoutingManagement.CalculatePlanningLineDates(ReqLine2);
    end;
#endif

    procedure Calculate(var ReqLine2: Record "Requisition Line"; Direction: Option Forward,Backward; CalcRouting: Boolean; CalcComponents: Boolean; PlanningLevel: Integer)
    var
        IsHandled: Boolean;
    begin
        IsHandled := false;
        OnBeforeCalculate(ReqLine2, Direction, CalcRouting, CalcComponents, PlanningLevel, IsHandled);
        if IsHandled then
            exit;

        ReqLine := ReqLine2;
        if ReqLine."Action Message" <> ReqLine."Action Message"::Cancel then
            ReqLine.TestField(Quantity);
        if Direction = Direction::Backward then
            ReqLine.TestField("Ending Date")
        else
            ReqLine.TestField("Starting Date");

        if CalcRouting then
            OnCalculateRouting(ReqLine, TempPlanningErrorLog, PlanningResiliency);

        if CalcComponents then begin
            PlanningComponent.SetRange("Worksheet Template Name", ReqLine."Worksheet Template Name");
            PlanningComponent.SetRange("Worksheet Batch Name", ReqLine."Journal Batch Name");
            PlanningComponent.SetRange("Worksheet Line No.", ReqLine."Line No.");
            if PlanningComponent.Find('-') then
                repeat
                    PlanningComponent.BlockDynamicTracking(Blocked);
                    PlanningComponent.Delete(true);
                until PlanningComponent.Next() = 0;
            if ReqLine."Planning Level" = 0 then
                ReqLine.DeleteMultiLevel();
            if (ReqLine."Replenishment System" = ReqLine."Replenishment System"::Assembly) or
               ((ReqLine."Replenishment System" = ReqLine."Replenishment System"::"Prod. Order") and ReqLine.IsProductionBOM())
            then begin
                Item.Get(ReqLine."No.");
                GetPlanningParameters.AtSKU(SKU, ReqLine."No.", ReqLine."Variant Code", ReqLine."Location Code");

                if ReqLine."Replenishment System" = ReqLine."Replenishment System"::Assembly then
                    TransferAsmBOM(Item."No.", 1, ReqLine."Qty. per Unit of Measure")
                else begin
                    IsHandled := false;
                    OnCalculateOnBeforeTransferBOM(ReqLine, SKU, PlanningResiliency, IsHandled);
                    if not IsHandled then
                        OnCalculateOnTransferBOM(
                            ReqLine, Item, PlanningComponent, TempPlanningErrorLog, TempPlanningComponent, SKU,
                            PlanningResiliency, NextPlanningCompLineNo, Blocked);
                end;
            end;
        end;
        Recalculate(ReqLine, Direction);
        ReqLine2 := ReqLine;
        if CalcComponents and
           (SKU."Manufacturing Policy" = SKU."Manufacturing Policy"::"Make-to-Order")
        then
            CheckMultiLevelStructure(ReqLine, CalcRouting, CalcComponents, PlanningLevel);

        OnAfterCalculate(CalcComponents, SKU, ReqLine2);
    end;

    procedure Recalculate(var ReqLine2: Record "Requisition Line"; Direction: Option Forward,Backward)
    begin
        RecalculateWithOptionalModify(ReqLine2, Direction, true);
    end;

    procedure RecalculateWithOptionalModify(var ReqLine2: Record "Requisition Line"; Direction: Option Forward,Backward; ModifyRec: Boolean)
    begin
        OnBeforeRecalculateWithOptionalModify(ReqLine2, Direction);

        ReqLine := ReqLine2;

        if ModifyRec then
            ReqLine.Modify(true);
        CalculateComponents();
        if ReqLine."Planning Level" > 0 then begin
            if Direction = Direction::Forward then
                ReqLine."Due Date" := ReqLine."Ending Date"
        end else
            if (ReqLine."Due Date" < ReqLine."Ending Date") or
               (Direction = Direction::Forward)
            then
                ReqLine."Due Date" :=
                  LeadTimeMgt.GetPlannedDueDate(
                    ReqLine."No.",
                    ReqLine."Location Code",
                    ReqLine."Variant Code",
                    ReqLine."Ending Date",
                    ReqLine."Vendor No.",
                    ReqLine."Ref. Order Type");
        ReqLine.UpdateDatetime();
        ReqLine2 := ReqLine;

        OnAfterRecalculateWithOptionalModify(ReqLine2, Direction);
    end;

    procedure CheckMultiLevelStructure(ReqLine2: Record "Requisition Line"; CalcRouting: Boolean; CalcComponents: Boolean; PlanningLevel: Integer)
    var
        ReqLine3: Record "Requisition Line";
        Item3: Record Item;
        PlanningComp: Record "Planning Component";
        TrackingSpecification: Record "Tracking Specification";
        PlngComponentReserve: Codeunit "Plng. Component-Reserve";
        PlanningLineNo: Integer;
        NoOfComponents: Integer;
        ShouldExit: Boolean;
        ThrowLineSpacingError: Boolean;
    begin
        if PlanningLevel < 0 then
            exit;

        if not Item3.Get(ReqLine2."No.") then
            exit;

        ShouldExit := Item3."Manufacturing Policy" <> Item3."Manufacturing Policy"::"Make-to-Order";
        OnCheckMultiLevelStructureOnAfterCalcShouldExitManufacturingPolicy(ReqLine2, ShouldExit, PlanningLevel, LineSpacing, PlanningResiliency, Blocked, CalcRouting, CalcComponents, TempPlanningErrorLog);
        if ShouldExit then
            exit;

        PlanningLineNo := ReqLine2."Line No.";

        PlanningComp.SetRange("Worksheet Line No.", ReqLine2."Line No.");
        PlanningComp.SetFilter("Item No.", '<>%1', '');
        PlanningComp.SetFilter("Expected Quantity", '<>0');
        PlanningComp.SetFilter("Planning Level Code", '>0');
        OnCheckMultiLevelStructureOnAfterPlanningCompSetFilters(PlanningComp, ReqLine2);
        NoOfComponents := PlanningComp.Count();
        if PlanningLevel = 0 then begin
            ReqLine3.Reset();
            ReqLine3.SetRange("Worksheet Template Name", ReqLine."Worksheet Template Name");
            ReqLine3.SetRange("Journal Batch Name", ReqLine."Journal Batch Name");
            ReqLine3 := ReqLine2;
            if ReqLine3.Find('>') then
                LineSpacing[1] := (ReqLine3."Line No." - ReqLine."Line No.") div (1 + NoOfComponents)
            else
                LineSpacing[1] := 10000;
        end else
            if (PlanningLevel > 0) and (PlanningLevel < 50) then
                LineSpacing[PlanningLevel + 1] := LineSpacing[PlanningLevel] div (1 + NoOfComponents);

        if PlanningComp.Find('-') then
            repeat
                ThrowLineSpacingError := LineSpacing[PlanningLevel + 1] = 0;
                OnCheckMultiLevelStructureOnAfterCalcThrowLineSpacingError(ReqLine2, LineSpacing, PlanningLineNo, ThrowLineSpacingError);
                if ThrowLineSpacingError then begin
                    if PlanningResiliency then
                        TempPlanningErrorLog.SetError(Text015, Database::"Requisition Line", ReqLine.GetPosition());
                    Error(Text002);
                end;
                ReqLine3.Init();
                ReqLine3.BlockDynamicTracking(Blocked);
                ReqLine3."Worksheet Template Name" := ReqLine2."Worksheet Template Name";
                ReqLine3."Journal Batch Name" := ReqLine2."Journal Batch Name";
                PlanningLineNo := PlanningLineNo + LineSpacing[PlanningLevel + 1];
                ReqLine3."Line No." := PlanningLineNo;
                ReqLine3."Ref. Order Type" := ReqLine2."Ref. Order Type";
                ReqLine3."Ref. Order Status" := ReqLine2."Ref. Order Status";
                ReqLine3."Ref. Order No." := ReqLine2."Ref. Order No.";

                ReqLine3."Planning Line Origin" := ReqLine2."Planning Line Origin";
                ReqLine3.Level := ReqLine2.Level;
                ReqLine3."Demand Type" := ReqLine2."Demand Type";
                ReqLine3."Demand Subtype" := ReqLine2."Demand Subtype";
                ReqLine3."Demand Order No." := ReqLine2."Demand Order No.";
                ReqLine3."Demand Line No." := ReqLine2."Demand Line No.";
                ReqLine3."Demand Ref. No." := ReqLine2."Demand Ref. No.";
                ReqLine3."Demand Ref. No." := ReqLine2."Demand Ref. No.";
                ReqLine3."Demand Date" := ReqLine2."Demand Date";
                ReqLine3.Status := ReqLine2.Status;
                ReqLine3."User ID" := ReqLine2."User ID";

                ReqLine3.Type := ReqLine3.Type::Item;
                ReqLine3.Validate("No.", PlanningComp."Item No.");
                ReqLine3."Action Message" := ReqLine2."Action Message";
                ReqLine3."Accept Action Message" := ReqLine2."Accept Action Message";
                ReqLine3.Description := PlanningComp.Description;
                ReqLine3."Description 2" := PlanningComp."Description 2";
                ReqLine3."Variant Code" := PlanningComp."Variant Code";
                ReqLine3."Unit of Measure Code" := PlanningComp."Unit of Measure Code";
                ReqLine3."Location Code" := PlanningComp."Location Code";
                ReqLine3."Bin Code" := PlanningComp."Bin Code";
                ReqLine3."Ending Date" := PlanningComp."Due Date";
                ReqLine3.Validate("Ending Time", PlanningComp."Due Time");
                ReqLine3."Due Date" := PlanningComp."Due Date";
                ReqLine3."Demand Date" := PlanningComp."Due Date";
                OnCheckMultiLevelStructureOnBeforeValidateQuantity(ReqLine3, PlanningComp);
                ReqLine3.Validate(Quantity, PlanningComp."Expected Quantity");
                ReqLine3.Validate("Needed Quantity", PlanningComp."Expected Quantity");
                ReqLine3.Validate("Demand Quantity", PlanningComp."Expected Quantity");
                ReqLine3."Demand Qty. Available" := 0;

                ReqLine3."Planning Level" := PlanningLevel + 1;
                ReqLine3."Related to Planning Line" := ReqLine2."Line No.";
                ReqLine3."Order Promising ID" := ReqLine2."Order Promising ID";
                ReqLine3."Order Promising Line ID" := ReqLine2."Order Promising Line ID";
                OnCheckMultiLevelStructureOnBeforeInsertPlanningLine(ReqLine3, PlanningComp);
                InsertPlanningLine(ReqLine3);
                ReqLine3.Quantity :=
                  Round(
                    ReqLine3."Quantity (Base)" /
                    ReqLine3."Qty. per Unit of Measure", UOMMgt.QtyRndPrecision());
                ReqLine3."Net Quantity (Base)" :=
                  (ReqLine3.Quantity -
                   ReqLine3."Original Quantity") *
                  ReqLine3."Qty. per Unit of Measure";
                ReqLine3.Modify();
                if PlanningComp."Location Code" = ReqLine3."Location Code" then begin
                    TrackingSpecification.InitTrackingSpecification(
                        DATABASE::"Requisition Line", 0,
                        ReqLine3."Worksheet Template Name", ReqLine3."Journal Batch Name", 0, ReqLine3."Line No.",
                        ReqLine3."Variant Code", ReqLine3."Location Code", ReqLine3."Qty. per Unit of Measure");
                    PlngComponentReserve.BindToTracking(
                        PlanningComp, TrackingSpecification, ReqLine3.Description, ReqLine3."Ending Date",
                        PlanningComp."Expected Quantity", PlanningComp."Expected Quantity (Base)");
                end;
                PlanningComp."Supplied-by Line No." := ReqLine3."Line No.";
                PlanningComp.Modify();
                OnCheckMultiLevelStructureOnBeforeReqLineModify(ReqLine3);
                ReqLine3.Modify();
                Calculate(ReqLine3, 1, CalcRouting, CalcComponents, PlanningLevel + 1);
                ReqLine3.Modify();
            until PlanningComp.Next() = 0;
    end;

    local procedure InsertPlanningLine(var ReqLine: Record "Requisition Line")
    var
        ReqLine2: Record "Requisition Line";
    begin
        ReqLine2 := ReqLine;
        ReqLine2.SetCurrentKey("Worksheet Template Name", "Journal Batch Name", Type, "No.");
        ReqLine2.SetRange("Worksheet Template Name", ReqLine."Worksheet Template Name");
        ReqLine2.SetRange("Journal Batch Name", ReqLine."Journal Batch Name");
        ReqLine2.SetRange(Type, ReqLine.Type::Item);
        ReqLine2.SetRange("No.", ReqLine."No.");
        ReqLine2.SetRange("Variant Code", ReqLine."Variant Code");
        ReqLine2.SetRange("Ref. Order Type", ReqLine."Ref. Order Type");
        ReqLine2.SetRange("Ref. Order Status", ReqLine."Ref. Order Status");
        ReqLine2.SetRange("Ref. Order No.", ReqLine."Ref. Order No.");
        ReqLine2.SetFilter("Planning Level", '>%1', 0);
        OnInsertPlanningLineOnAfterReqLine2SetFilters(ReqLine2, ReqLine);

        if ReqLine2.FindFirst() then begin
            ReqLine2.BlockDynamicTracking(Blocked);
            ReqLine2.Validate(Quantity, ReqLine2.Quantity + ReqLine.Quantity);

            if ReqLine2."Due Date" > ReqLine."Due Date" then
                ReqLine2."Due Date" := ReqLine."Due Date";

            if ReqLine2."Ending Date" > ReqLine."Ending Date" then begin
                ReqLine2."Ending Date" := ReqLine."Ending Date";
                ReqLine2."Ending Time" := ReqLine."Ending Time";
            end else
                if (ReqLine2."Ending Date" = ReqLine."Ending Date") and
                   (ReqLine2."Ending Time" > ReqLine."Ending Time")
                then
                    ReqLine2."Ending Time" := ReqLine."Ending Time";

            if ReqLine2."Planning Level" < ReqLine."Planning Level" then
                ReqLine2."Planning Level" := ReqLine."Planning Level";

            ReqLine2.Modify();
            ReqLine := ReqLine2;
        end else
            ReqLine.Insert();

        OnAfterInsertPlanningLine(ReqLine);
    end;

    procedure BlockDynamicTracking(SetBlock: Boolean)
    begin
        Blocked := SetBlock;
    end;

    procedure GetPlanningCompList(var PlanningCompList: Record "Planning Component" temporary)
    begin
        // The procedure returns a list of the Planning Components handled.
        if TempPlanningComponent.Find('-') then
            repeat
                PlanningCompList := TempPlanningComponent;
                if not PlanningCompList.Insert() then
                    PlanningCompList.Modify();
                TempPlanningComponent.Delete();
            until TempPlanningComponent.Next() = 0;
    end;

    local procedure IsPlannedAsmComp(var PlanningComp: Record "Planning Component"; ReqLine: Record "Requisition Line"; AsmBOMComp: Record "BOM Component"): Boolean
    var
        PlanningComp2: Record "Planning Component";
    begin
        PlanningComp2 := PlanningComp;

        PlanningComp.SetCurrentKey("Worksheet Template Name", "Worksheet Batch Name", "Worksheet Line No.", "Item No.");
        PlanningComp.SetRange("Worksheet Template Name", ReqLine."Worksheet Template Name");
        PlanningComp.SetRange("Worksheet Batch Name", ReqLine."Journal Batch Name");
        PlanningComp.SetRange("Worksheet Line No.", ReqLine."Line No.");
        PlanningComp.SetRange("Item No.", AsmBOMComp."No.");
        if PlanningComp.Find('-') then
            repeat
                if IsPlannedAsmCompFound(PlanningComp, AsmBOMComp) then
                    exit(true);
            until PlanningComp.Next() = 0;

        PlanningComp := PlanningComp2;
        exit(false);
    end;

    local procedure IsPlannedAsmCompFound(PlanningComp: Record "Planning Component"; AsmBOMComp: Record "BOM Component"): Boolean
    var
        IsFound: Boolean;
    begin
        IsFound :=
            (PlanningComp."Variant Code" = AsmBOMComp."Variant Code") and
            (PlanningComp.Position = AsmBOMComp.Position) and
            (PlanningComp."Position 2" = AsmBOMComp."Position 2") and
            (PlanningComp."Position 3" = AsmBOMComp."Position 3") and
            (PlanningComp."Unit of Measure Code" = AsmBOMComp."Unit of Measure Code");
        OnAfterIsPlannedAsmCompFound(PlanningComp, AsmBOMComp, IsFound);
        exit(IsFound);
    end;

    procedure SetResiliencyOn(WkshTemplName: Code[10]; JnlBatchName: Code[10]; ItemNo: Code[20])
    begin
        PlanningResiliency := true;
        TempPlanningErrorLog.SetJnlBatch(WkshTemplName, JnlBatchName, ItemNo);
    end;

    procedure GetResiliencyError(var PlanningErrorLog: Record "Planning Error Log"): Boolean
    var
        ShouldExit: Boolean;
    begin
        TempPlanningComponent.DeleteAll();
        OnGetResiliencyErrorOnRouting(PlanningErrorLog, ShouldExit);
        if ShouldExit then
            exit(true);
        exit(TempPlanningErrorLog.GetError(PlanningErrorLog));
    end;

    [IntegrationEvent(false, false)]
    local procedure OnAfterInsertPlanningLine(var RequisitionLine: Record "Requisition Line")
    begin
    end;

#if not CLEAN27
    internal procedure RunOnAfterIsPlannedCompFound(var PlanningComp: Record "Planning Component"; var ProdBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; var IsFound: Boolean; var SKU2: Record "Stockkeeping Unit")
    begin
        OnAfterIsPlannedCompFound(PlanningComp, ProdBOMLine, IsFound, SKU2);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnAfterIsPlannedCompFound(var PlanningComp: Record "Planning Component"; var ProdBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; var IsFound: Boolean; var SKU: Record "Stockkeeping Unit")
    begin
    end;
#endif

    [IntegrationEvent(false, false)]
    local procedure OnAfterIsPlannedAsmCompFound(PlanningComp: Record "Planning Component"; AsmBOMComp: Record "BOM Component"; var IsFound: Boolean)
    begin
    end;

#if not CLEAN27
    internal procedure RunOnAfterTransferBOM(RequisitionLine: Record "Requisition Line"; ProdBOMNo: Code[20]; Level: Integer; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal)
    begin
        OnAfterTransferBOM(RequisitionLine, ProdBOMNo, Level, LineQtyPerUOM, ItemQtyPerUOM);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnAfterTransferBOM(RequisitionLine: Record "Requisition Line"; ProdBOMNo: Code[20]; Level: Integer; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal)
    begin
    end;
#endif

    [IntegrationEvent(false, false)]
    local procedure OnAfterRecalculateWithOptionalModify(var RequisitionLine: Record "Requisition Line"; Direction: Option Forward,Backward)
    begin
    end;

#if not CLEAN27
    internal procedure RunOnAfterTransferRouting(var RequisitionLine: Record "Requisition Line")
    begin
        OnAfterTransferRouting(RequisitionLine);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnAfterTransferRouting(var RequisitionLine: Record "Requisition Line")
    begin
    end;
#endif

#if not CLEAN27
    internal procedure RunOnAfterTransferRtngLine(var ReqLine2: Record "Requisition Line"; var RoutingLine: Record Microsoft.Manufacturing.Routing."Routing Line"; var PlanningRoutingLine: Record Microsoft.Manufacturing.Routing."Planning Routing Line")
    begin
        OnAfterTransferRtngLine(ReqLine2, RoutingLine, PlanningRoutingLine);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnAfterTransferRtngLine(var ReqLine: Record "Requisition Line"; var RoutingLine: Record Microsoft.Manufacturing.Routing."Routing Line"; var PlanningRoutingLine: Record Microsoft.Manufacturing.Routing."Planning Routing Line")
    begin
    end;
#endif

#if not CLEAN27
    internal procedure RunOnTransferBOMOnAfterProdBOMLineSetFilters(var ProdBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; RequisitionLine: Record "Requisition Line")
    begin
        OnTransferBOMOnAfterProdBOMLineSetFilters(ProdBOMLine, RequisitionLine);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnTransferBOMOnAfterProdBOMLineSetFilters(var ProdBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; RequisitionLine: Record "Requisition Line")
    begin
    end;
#endif

#if not CLEAN27
    internal procedure RunOnTransferBOMOnBeforeGetDefaultBin(var PlanningComponent2: Record "Planning Component"; var ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; RequisitionLine: Record "Requisition Line"; var StockkeepingUnit: Record "Stockkeeping Unit")
    begin
        OnTransferBOMOnBeforeGetDefaultBin(PlanningComponent2, ProductionBOMLine, RequisitionLine, StockkeepingUnit);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnTransferBOMOnBeforeGetDefaultBin(var PlanningComponent: Record "Planning Component"; var ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; RequisitionLine: Record "Requisition Line"; var StockkeepingUnit: Record "Stockkeeping Unit")
    begin
    end;
#endif

#if not CLEAN27
    internal procedure RunOnTransferRoutingLineOnBeforeValidateDirectUnitCost(var ReqLine2: Record "Requisition Line"; var RoutingLine: Record Microsoft.Manufacturing.Routing."Routing Line"; var PlanningRoutingLine: Record Microsoft.Manufacturing.Routing."Planning Routing Line")
    begin
        OnTransferRoutingLineOnBeforeValidateDirectUnitCost(ReqLine2, RoutingLine, PlanningRoutingLine);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnTransferRoutingLineOnBeforeValidateDirectUnitCost(var ReqLine: Record "Requisition Line"; var RoutingLine: Record Microsoft.Manufacturing.Routing."Routing Line"; var PlanningRoutingLine: Record Microsoft.Manufacturing.Routing."Planning Routing Line")
    begin
    end;
#endif

#if not CLEAN27
    internal procedure RunOnTransferRoutingLineOnBeforeCalcRoutingCostPerUnit(var PlanningRoutingLine: Record Microsoft.Manufacturing.Routing."Planning Routing Line"; ReqLine2: Record "Requisition Line"; RoutingLine: Record Microsoft.Manufacturing.Routing."Routing Line")
    begin
        OnTransferRoutingLineOnBeforeCalcRoutingCostPerUnit(PlanningRoutingLine, ReqLine2, RoutingLine);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnTransferRoutingLineOnBeforeCalcRoutingCostPerUnit(var PlanningRoutingLine: Record Microsoft.Manufacturing.Routing."Planning Routing Line"; ReqLine: Record "Requisition Line"; RoutingLine: Record Microsoft.Manufacturing.Routing."Routing Line")
    begin
    end;
#endif

    [IntegrationEvent(false, false)]
    local procedure OnBeforeCalculate(var ReqLine2: Record "Requisition Line"; Direction: Option Forward,Backward; CalcRouting: Boolean; CalcComponents: Boolean; PlanningLevel: Integer; var IsHandled: Boolean)
    begin
    end;

#if not CLEAN27
    internal procedure RunOnBeforeInsertPlanningComponent(var ReqLine2: Record "Requisition Line"; var ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; var PlanningComponent2: Record "Planning Component"; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal)
    begin
        OnBeforeInsertPlanningComponent(ReqLine2, ProductionBOMLine, PlanningComponent2, LineQtyPerUOM, ItemQtyPerUOM);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnBeforeInsertPlanningComponent(var ReqLine: Record "Requisition Line"; var ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; var PlanningComponent: Record "Planning Component"; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal)
    begin
    end;
#endif

#if not CLEAN27
    internal procedure RunOnBeforeModifyPlanningComponent(var ReqLine2: Record "Requisition Line"; var ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; var PlanningComponent2: Record "Planning Component"; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal)
    begin
        OnBeforeModifyPlanningComponent(ReqLine2, ProductionBOMLine, PlanningComponent2, LineQtyPerUOM, ItemQtyPerUOM);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnBeforeModifyPlanningComponent(var ReqLine: Record "Requisition Line"; var ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; var PlanningComponent: Record "Planning Component"; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal)
    begin
    end;
#endif

    [IntegrationEvent(false, false)]
    local procedure OnBeforeInsertAsmPlanningComponent(var ReqLine: Record "Requisition Line"; var BOMComponent: Record "BOM Component"; var PlanningComponent: Record "Planning Component")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnBeforeRecalculateWithOptionalModify(var RequisitionLine: Record "Requisition Line"; Direction: Option Forward,Backward)
    begin
    end;

#if not CLEAN27
    internal procedure RunOnBeforeTransferBOM(ProdBOMNo: Code[20]; Level: Integer; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal; var RequisitionLine: Record "Requisition Line"; Blocked2: Boolean; var IsHandled: Boolean)
    begin
        OnBeforeTransferBOM(ProdBOMNo, Level, LineQtyPerUOM, ItemQtyPerUOM, RequisitionLine, Blocked2, IsHandled);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnBeforeTransferBOM(ProdBOMNo: Code[20]; Level: Integer; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal; var RequisitionLine: Record "Requisition Line"; Blocked: Boolean; var IsHandled: Boolean)
    begin
    end;
#endif

#if not CLEAN27
    internal procedure RunOnBeforeTransferRouting(var RequisitionLine: Record "Requisition Line"; PlanningResilency: Boolean; var IsHandled: Boolean)
    begin
        OnBeforeTransferRouting(RequisitionLine, PlanningResilency, IsHandled);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnBeforeTransferRouting(var RequisitionLine: Record "Requisition Line"; PlanningResilency: Boolean; var IsHandled: Boolean)
    begin
    end;
#endif

    [IntegrationEvent(false, false)]
    local procedure OnCalculateOnBeforeTransferBOM(var RequisitionLine: Record "Requisition Line"; var StockkeepingUnit: Record "Stockkeeping Unit"; PlanningResilency: Boolean; var IsHandled: Boolean)
    begin
    end;

#if not CLEAN27
    internal procedure RunOnCalculateRoutingOnAfterUpdateReqLine(var RequisitionLine: Record "Requisition Line"; Direction: Option Forward,Backward)
    begin
        OnCalculateRoutingOnAfterUpdateReqLine(RequisitionLine, Direction);
    end;

    [Obsolete('Moved to codeunit PlanningRoutingManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnCalculateRoutingOnAfterUpdateReqLine(var RequisitionLine: Record "Requisition Line"; Direction: Option Forward,Backward)
    begin
    end;
#endif

    [IntegrationEvent(false, false)]
    local procedure OnCheckMultiLevelStructureOnBeforeInsertPlanningLine(var ReqLine: Record "Requisition Line"; var PlanningComponent: Record "Planning Component")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnCheckMultiLevelStructureOnAfterPlanningCompSetFilters(var PlanningComponent: Record "Planning Component"; RequisitionLine2: Record "Requisition Line")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnCheckMultiLevelStructureOnAfterCalcThrowLineSpacingError(RequisitionLine: Record "Requisition Line"; var LineSpacing: array[50] of Integer; var PlanningLineNo: Integer; var ThrowLineSpacingError: Boolean)
    begin
    end;

#if not CLEAN27
    internal procedure RunOnTransferBOMOnBeforeTransferPlanningComponent(var RequisitionLine: Record "Requisition Line"; var ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; Blocked2: Boolean; var IsHandled: Boolean; Level: Integer)
    begin
        OnTransferBOMOnBeforeTransferPlanningComponent(RequisitionLine, ProductionBOMLine, Blocked2, IsHandled, Level);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnTransferBOMOnBeforeTransferPlanningComponent(var RequisitionLine: Record "Requisition Line"; var ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; Blocked: Boolean; var IsHandled: Boolean; Level: Integer)
    begin
    end;
#endif

#if not CLEAN27
    internal procedure RunOnTransferBOMOnBeforeTransferProductionBOM(var ReqQty: Decimal; ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal; RequisitionLine: Record "Requisition Line")
    begin
        OnTransferBOMOnBeforeTransferProductionBOM(ReqQty, ProductionBOMLine, LineQtyPerUOM, ItemQtyPerUOM, RequisitionLine);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnTransferBOMOnBeforeTransferProductionBOM(var ReqQty: Decimal; ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal; RequisitionLine: Record "Requisition Line")
    begin
    end;
#endif

#if not CLEAN27
    internal procedure RunOnTransferBOMOnBeforeUpdatePlanningComp(var ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; var UpdateCondition: Boolean; var IsHandled: Boolean)
    begin
        OnTransferBOMOnBeforeUpdatePlanningComp(ProductionBOMLine, UpdateCondition, IsHandled);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnTransferBOMOnBeforeUpdatePlanningComp(var ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; var UpdateCondition: Boolean; var IsHandled: Boolean)
    begin
    end;
#endif

#if not CLEAN27
    internal procedure RunOnTransferBOMOnAfterCalculateReqQty(var ReqQty: Decimal; ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; PlanningRoutingLine: Record Microsoft.Manufacturing.Routing."Planning Routing Line"; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal);
    begin
        OnTransferBOMOnAfterCalculateReqQty(ReqQty, ProductionBOMLine, PlanningRoutingLine, LineQtyPerUOM, ItemQtyPerUOM);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnTransferBOMOnAfterCalculateReqQty(var ReqQty: Decimal; ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; PlanningRoutingLine: Record Microsoft.Manufacturing.Routing."Planning Routing Line"; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal);
    begin
    end;
#endif

    [IntegrationEvent(false, false)]
    local procedure OnTransferAsmBOMOnBeforeGetDefaultBin(var PlanningComponent: Record "Planning Component"; var AsmBOMComponent: Record "BOM Component"; ReqLine: Record "Requisition Line")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnCheckMultiLevelStructureOnBeforeValidateQuantity(var RequisitionLine: Record "Requisition Line"; var PlanningComponent: Record "Planning Component");
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnInsertPlanningLineOnAfterReqLine2SetFilters(var ReqLine2: Record "Requisition Line"; var ReqLine: Record "Requisition Line")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnCheckMultiLevelStructureOnAfterCalcShouldExitManufacturingPolicy(var RequisitionLine: Record "Requisition Line"; var ShouldExit: Boolean; PlanningLevel: Integer; var LineSpacing: array[50] of Integer; PlanningResiliency: Boolean; Blocked: Boolean; CalcRouting: Boolean; CalcComponents: Boolean; var TempPlanningErrorLog: Record "Planning Error Log" temporary)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnAfterCalculate(var CalcComponents: Boolean; var SKU: Record "Stockkeeping Unit"; var RequisitionLine: Record "Requisition Line")
    begin
    end;

#if not CLEAN27
    internal procedure RunOnAfterSetPlanningLevelCode(var PlanningComponent2: Record "Planning Component"; var ProdBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; var SKU2: Record "Stockkeeping Unit"; var ComponentSKU: Record "Stockkeeping Unit"; var Result: Boolean)
    begin
        OnAfterSetPlanningLevelCode(PlanningComponent2, ProdBOMLine, SKU2, ComponentSKU, Result);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnAfterSetPlanningLevelCode(var PlanningComponent: Record "Planning Component"; var ProdBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; var SKU: Record "Stockkeeping Unit"; var ComponentSKU: Record "Stockkeeping Unit"; var Result: Boolean)
    begin
    end;
#endif

#if not CLEAN27
    internal procedure RunOnBeforeTransferRoutingLine(var PlanningRoutingLine: Record Microsoft.Manufacturing.Routing."Planning Routing Line"; RequisitionLine: Record "Requisition Line"; RoutingLine: Record Microsoft.Manufacturing.Routing."Routing Line"; var IsHandled: Boolean)
    begin
        OnBeforeTransferRoutingLine(PlanningRoutingLine, RequisitionLine, RoutingLine, IsHandled);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnBeforeTransferRoutingLine(var PlanningRoutingLine: Record Microsoft.Manufacturing.Routing."Planning Routing Line"; RequisitionLine: Record "Requisition Line"; RoutingLine: Record Microsoft.Manufacturing.Routing."Routing Line"; var IsHandled: Boolean)
    begin
    end;
#endif

#if not CLEAN27
    internal procedure RunOnTransferBOMOnBeforePlanningRtngLineFind(var PlanningRoutingLine: Record Microsoft.Manufacturing.Routing."Planning Routing Line"; ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; RequisitionLine: Record "Requisition Line")
    begin
        OnTransferBOMOnBeforePlanningRtngLineFind(PlanningRoutingLine, ProductionBOMLine, RequisitionLine);
    end;

    [Obsolete('Moved to codeunit MfgPlanningLineManagement', '27.0')]
    [IntegrationEvent(false, false)]
    local procedure OnTransferBOMOnBeforePlanningRtngLineFind(var PlanningRoutingLine: Record Microsoft.Manufacturing.Routing."Planning Routing Line"; ProductionBOMLine: Record Microsoft.Manufacturing.ProductionBOM."Production BOM Line"; RequisitionLine: Record "Requisition Line")
    begin
    end;
#endif

    [IntegrationEvent(false, false)]
    local procedure OnGetResiliencyErrorOnRouting(var PlanningErrorLog: Record "Planning Error Log"; var ShouldExit: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnCalculateRouting(var RequisitionLine: Record "Requisition Line"; var TempPlanningErrorLog: Record "Planning Error Log" temporary; PlanningResiliency: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnCalculateOnTransferBOM(
        var RequisitionLine: Record "Requisition Line"; Item: Record Item; var PlanningComponent: Record "Planning Component";
        var TempPlanningErrorLog: Record "Planning Error Log" temporary; var TempPlanningComponent: Record "Planning Component" temporary;
        SKU: Record "Stockkeeping Unit"; PlanningResiliency: Boolean; var NextPlanningCompLineNo: Integer; Blocked: Boolean)
    begin
    end;

    [InternalEvent(false)]
    local procedure OnTransferASMBOMOnAfterSetAsmBOMComp(var PlanningComponent: Record "Planning Component")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnCalculateComponentsOnbeforePlanningComponentModify(var PlanningComponent: Record "Planning Component")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnCheckMultiLevelStructureOnBeforeReqLineModify(var RequisitionLine: Record "Requisition Line")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnTransferAsmBOMOnBeforePlanningComponentModify(var PlanningComponent: Record "Planning Component")
    begin
    end;
}