Codeunit 99000773 Calculate Prod. Order
- App
- Base Application
- Namespace
- Microsoft.Manufacturing.Document
- Versions
- 17-28
Procedures, 16Events, 65Obsolete, 1
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/Manufacturing/Document/CalculateProdOrder.Codeunit.al1307 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.Manufacturing.Document;
using Microsoft.Foundation.UOM;
using Microsoft.Inventory;
using Microsoft.Inventory.Costing;
using Microsoft.Inventory.Item;
using Microsoft.Inventory.Ledger;
using Microsoft.Inventory.Location;
using Microsoft.Inventory.Planning;
using Microsoft.Inventory.Requisition;
using Microsoft.Manufacturing.Capacity;
using Microsoft.Manufacturing.MachineCenter;
using Microsoft.Manufacturing.ProductionBOM;
using Microsoft.Manufacturing.Routing;
using Microsoft.Manufacturing.Setup;
using Microsoft.Manufacturing.WorkCenter;
codeunit 99000773 "Calculate Prod. Order"
{
Permissions = TableData Item = r,
TableData "Prod. Order Line" = rimd,
TableData "Prod. Order Component" = rimd,
TableData "Manufacturing Setup" = r,
TableData "Production BOM Line" = rimd,
TableData "Production BOM Comment Line" = rimd,
TableData "Production Order" = rimd,
TableData "Prod. Order Comp. Cmt Line" = rimd;
trigger OnRun()
begin
end;
var
Item: Record Item;
Location: Record Location;
SKU: Record "Stockkeeping Unit";
ProdOrder: Record "Production Order";
ProdOrderLine: Record "Prod. Order Line";
ProdOrderComp: Record "Prod. Order Component";
ProdOrderRoutingLine2: Record "Prod. Order Routing Line";
ProdBOMLine: array[99] of Record "Production BOM Line";
ProdLineItem: Record Item;
UOMMgt: Codeunit "Unit of Measure Management";
MfgCostCalcMgt: Codeunit "Mfg. Cost Calculation Mgt.";
VersionMgt: Codeunit VersionManagement;
ProdOrderRouteMgt: Codeunit "Prod. Order Route Management";
GetPlanningParameters: Codeunit "Planning-Get Parameters";
LeadTimeMgt: Codeunit "Lead-Time Management";
CalendarMgt: Codeunit "Shop Calendar Management";
ProdOrderWarehouseMgt: Codeunit "Prod. Order Warehouse Mgt.";
NextProdOrderCompLineNo: Integer;
Blocked: Boolean;
ProdOrderModify: Boolean;
#pragma warning disable AA0074
#pragma warning disable AA0470
Text000: Label 'BOM phantom structure for %1 is higher than 50 levels.';
Text001: Label '%1 %2 %3 can not be calculated, if at least one %4 has been posted.';
#pragma warning restore AA0470
#pragma warning restore AA0074
OperationCannotFollowErr: Label 'Operation No. %1 cannot follow another operation in the routing of this Prod. Order Line.', Comment = '%1 = Operation No.';
OperationCannotPrecedeErr: Label 'Operation No. %1 cannot precede another operation in the routing of this Prod. Order Line.', Comment = '%1 = Operation No.';
local procedure TransferRouting()
var
RoutingHeader: Record "Routing Header";
RoutingLine: Record "Routing Line";
ProdOrderRoutingLine: Record "Prod. Order Routing Line";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeTransferRouting(ProdOrder, ProdOrderLine, IsHandled);
if IsHandled then
exit;
if ProdOrderLine."Routing No." = '' then
exit;
RoutingHeader.Get(ProdOrderLine."Routing No.");
ProdOrderRoutingLine.SetRange(Status, ProdOrderLine.Status);
ProdOrderRoutingLine.SetRange("Prod. Order No.", ProdOrderLine."Prod. Order No.");
ProdOrderRoutingLine.SetRange("Routing Reference No.", ProdOrderLine."Routing Reference No.");
ProdOrderRoutingLine.SetRange("Routing No.", ProdOrderLine."Routing No.");
if not ProdOrderRoutingLine.IsEmpty() then
exit;
RoutingLine.SetRange("Routing No.", ProdOrderLine."Routing No.");
RoutingLine.SetRange("Version Code", ProdOrderLine."Routing Version Code");
if RoutingLine.Find('-') then
repeat
ProcessRoutingLine(RoutingLine, ProdOrderRoutingLine);
until RoutingLine.Next() = 0;
OnAfterTransferRouting(ProdOrderLine);
end;
local procedure ProcessRoutingLine(var RoutingLine: Record "Routing Line"; var ProdOrderRoutingLine: Record "Prod. Order Routing Line")
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeProcessRoutingLine(RoutingLine, ProdOrderRoutingLine, ProdOrderLine, ProdOrder, IsHandled);
if IsHandled then
exit;
RoutingLine.TestField(Recalculate, false);
InitProdOrderRoutingLine(ProdOrderRoutingLine, RoutingLine);
TransferTaskInfo(ProdOrderRoutingLine, ProdOrderLine."Routing Version Code");
end;
procedure InitProdOrderRoutingLine(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; RoutingLine: Record "Routing Line")
var
WorkCenter: Record "Work Center";
MachineCenter: Record "Machine Center";
begin
ProdOrderRoutingLine.Init();
ProdOrderRoutingLine.Status := ProdOrderLine.Status;
ProdOrderRoutingLine."Prod. Order No." := ProdOrderLine."Prod. Order No.";
ProdOrderRoutingLine."Routing Reference No." := ProdOrderLine."Routing Reference No.";
ProdOrderRoutingLine."Routing No." := ProdOrderLine."Routing No.";
ProdOrderRoutingLine.CopyFromRoutingLine(RoutingLine);
case ProdOrderRoutingLine.Type of
ProdOrderRoutingLine.Type::"Work Center":
begin
WorkCenter.Get(RoutingLine."Work Center No.");
ProdOrderRoutingLine."Flushing Method" := WorkCenter."Flushing Method";
end;
ProdOrderRoutingLine.Type::"Machine Center":
begin
MachineCenter.Get(ProdOrderRoutingLine."No.");
ProdOrderRoutingLine."Flushing Method" := MachineCenter."Flushing Method";
end;
end;
OnTransferRoutingOnBeforeCalcRoutingCostPerUnit(ProdOrderRoutingLine, ProdOrderLine, RoutingLine);
MfgCostCalcMgt.CalcRoutingCostPerUnit(
ProdOrderRoutingLine.Type, ProdOrderRoutingLine."No.",
ProdOrderRoutingLine."Direct Unit Cost", ProdOrderRoutingLine."Indirect Cost %", ProdOrderRoutingLine."Overhead Rate",
ProdOrderRoutingLine."Unit Cost per", ProdOrderRoutingLine."Unit Cost Calculation");
OnTransferRoutingOnbeforeValidateDirectUnitCost(ProdOrderRoutingLine, ProdOrderLine, RoutingLine);
ProdOrderRoutingLine.Validate("Direct Unit Cost");
ProdOrderRoutingLine."Starting Time" := ProdOrderLine."Starting Time";
ProdOrderRoutingLine."Starting Date" := ProdOrderLine."Starting Date";
ProdOrderRoutingLine."Ending Time" := ProdOrderLine."Ending Time";
ProdOrderRoutingLine."Ending Date" := ProdOrderLine."Ending Date";
ProdOrderRoutingLine.UpdateDatetime();
OnAfterTransferRoutingLine(ProdOrderLine, RoutingLine, ProdOrderRoutingLine);
ProdOrderRoutingLine.Insert();
OnAfterInsertProdRoutingLine(ProdOrderRoutingLine, ProdOrderLine);
end;
procedure TransferTaskInfo(var FromProdOrderRoutingLine: Record "Prod. Order Routing Line"; VersionCode: Code[20])
begin
CopyRoutingTools(FromProdOrderRoutingLine, VersionCode);
CopyRoutingPersonnel(FromProdOrderRoutingLine, VersionCode);
CopyRoutingQualityMeasures(FromProdOrderRoutingLine, VersionCode);
CopyRoutingComments(FromProdOrderRoutingLine, VersionCode);
OnAfterTransferTaskInfo(FromProdOrderRoutingLine, VersionCode);
end;
procedure TransferBOM(ProdBOMNo: Code[20]; Level: Integer; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal): Boolean
var
BOMHeader: Record "Production BOM Header";
ProductionBOMVersion: Record "Production BOM Version";
ReqQty: Decimal;
ErrorOccured: Boolean;
VersionCode: Code[20];
IsHandled: Boolean;
SkipTransfer: Boolean;
begin
IsHandled := false;
OnBeforeTransferBOM(ProdOrder, ProdOrderLine, ProdBOMNo, Level, LineQtyPerUOM, ItemQtyPerUOM, Blocked, ErrorOccured, IsHandled);
if IsHandled then
exit(not ErrorOccured);
if ProdBOMNo = '' then
exit;
ProdOrderComp.LockTable();
if Level > 50 then
Error(
Text000,
ProdBOMNo);
BOMHeader.Get(ProdBOMNo);
if Level > 1 then
VersionCode := VersionMgt.GetBOMVersion(ProdBOMNo, ProdOrderLine."Starting Date", true)
else
VersionCode := ProdOrderLine."Production BOM Version Code";
if VersionCode <> '' then begin
ProductionBOMVersion.Get(ProdBOMNo, VersionCode);
ProductionBOMVersion.TestField(Status, ProductionBOMVersion.Status::Certified);
end else
BOMHeader.TestField(Status, BOMHeader.Status::Certified);
ProdBOMLine[Level].SetRange("Production BOM No.", ProdBOMNo);
ProdBOMLine[Level].SetRange("Version Code", VersionCode);
ProdBOMLine[Level].SetFilter("Starting Date", '%1|..%2', 0D, ProdOrderLine."Starting Date");
ProdBOMLine[Level].SetFilter("Ending Date", '%1|%2..', 0D, ProdOrderLine."Starting Date");
OnTransferBOMOnAfterSetFiltersProdBOMLine(ProdBOMLine[Level], ProdOrderLine);
if ProdBOMLine[Level].Find('-') then
repeat
IsHandled := false;
OnBeforeTransferBOMComponent(ProdOrder, ProdOrderLine, ProdBOMLine[Level], ErrorOccured, IsHandled, Level);
if not IsHandled then begin
if ProdBOMLine[Level]."Routing Link Code" <> '' then begin
IsHandled := false;
OnBeforeFindProdOrderRoutingLine(ProdOrderLine, ProdBOMLine[Level], IsHandled, ReqQty);
if not IsHandled then begin
ProdOrderRoutingLine2.SetRange(Status, ProdOrderLine.Status);
ProdOrderRoutingLine2.SetRange("Prod. Order No.", ProdOrderLine."Prod. Order No.");
ProdOrderRoutingLine2.SetRange("Routing Link Code", ProdBOMLine[Level]."Routing Link Code");
ProdOrderRoutingLine2.FindFirst();
ReqQty :=
ProdBOMLine[Level].Quantity * (1 + ProdBOMLine[Level]."Scrap %" / 100) *
(1 + ProdOrderRoutingLine2."Scrap Factor % (Accumulated)") * LineQtyPerUOM / ItemQtyPerUOM +
ProdOrderRoutingLine2."Fixed Scrap Qty. (Accum.)";
end;
end else
ReqQty :=
ProdBOMLine[Level].Quantity * (1 + ProdBOMLine[Level]."Scrap %" / 100) * LineQtyPerUOM / ItemQtyPerUOM;
OnTransferBOMOnAfterCalcReqQty(
ProdBOMLine[Level], ProdOrderRoutingLine2, ProdOrderLine, ReqQty, LineQtyPerUOM, ItemQtyPerUOM);
case ProdBOMLine[Level].Type of
ProdBOMLine[Level].Type::Item:
begin
SkipTransfer := false;
OnTransferBOMOnBeforeProcessItem(ProdBOMLine[Level], ReqQty, SkipTransfer);
if not SkipTransfer then
TransferBOMProcessItem(Level, LineQtyPerUOM, ItemQtyPerUOM, ErrorOccured);
end;
ProdBOMLine[Level].Type::"Production BOM":
begin
OnTransferBOMOnBeforeProcessProdBOM(ProdBOMLine[Level], LineQtyPerUOM, ItemQtyPerUOM, ReqQty, ProdOrderLine);
IsHandled := false;
OnTransferBOMOnBeforeTransferNestedProdBOM(ProdBOMLine[Level], LineQtyPerUOM, ItemQtyPerUOM, ReqQty, ProdOrderLine, IsHandled);
if not IsHandled then
TransferBOM(ProdBOMLine[Level]."No.", Level + 1, ReqQty, 1);
ProdBOMLine[Level].SetRange("Production BOM No.", ProdBOMNo);
if Level > 1 then
ProdBOMLine[Level].SetRange("Version Code", VersionMgt.GetBOMVersion(ProdBOMNo, ProdOrderLine."Starting Date", true))
else
ProdBOMLine[Level].SetRange("Version Code", ProdOrderLine."Production BOM Version Code");
ProdBOMLine[Level].SetFilter("Starting Date", '%1|..%2', 0D, ProdOrderLine."Starting Date");
ProdBOMLine[Level].SetFilter("Ending Date", '%1|%2..', 0D, ProdOrderLine."Starting Date");
OnTransferBOMOnAfterProcessProdBOM(ProdBOMLine[Level], LineQtyPerUOM, ItemQtyPerUOM, ReqQty, ProdOrderLine);
end;
end;
end;
until ProdBOMLine[Level].Next() = 0;
OnAfterTransferBOM(ProdOrder, ProdOrderLine, ProdBOMNo, Level, LineQtyPerUOM, ItemQtyPerUOM, Blocked, ErrorOccured);
exit(not ErrorOccured);
end;
local procedure TransferBOMProcessItem(Level: Integer; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal; var ErrorOccured: Boolean)
var
Item2: Record Item;
ComponentSKU: Record "Stockkeeping Unit";
IsHandled: Boolean;
QtyRoundPrecision: Decimal;
begin
ProdOrderComp.Reset();
ProdOrderComp.SetCurrentKey(Status, "Prod. Order No.", "Prod. Order Line No.", "Item No.");
ProdOrderComp.SetRange(Status, ProdOrderLine.Status);
ProdOrderComp.SetRange("Prod. Order No.", ProdOrderLine."Prod. Order No.");
ProdOrderComp.SetRange("Prod. Order Line No.", ProdOrderLine."Line No.");
ProdOrderComp.SetFilterFromProdBOMLine(ProdBOMLine[Level]);
OnAfterProdOrderCompFilter(ProdOrderComp, ProdBOMLine[Level]);
if not ProdOrderComp.FindFirst() then begin
ProdOrderComp.Reset();
ProdOrderComp.SetRange(Status, ProdOrderLine.Status);
ProdOrderComp.SetRange("Prod. Order No.", ProdOrderLine."Prod. Order No.");
ProdOrderComp.SetRange("Prod. Order Line No.", ProdOrderLine."Line No.");
if ProdOrderComp.FindLast() then
NextProdOrderCompLineNo := ProdOrderComp."Line No." + 10000
else
NextProdOrderCompLineNo := 10000;
ProdOrderComp.Init();
ProdOrderComp.SetIgnoreErrors();
ProdOrderComp.BlockDynamicTracking(Blocked);
ProdOrderComp.Status := ProdOrderLine.Status;
ProdOrderComp."Prod. Order No." := ProdOrderLine."Prod. Order No.";
ProdOrderComp."Prod. Order Line No." := ProdOrderLine."Line No.";
ProdOrderComp."Line No." := NextProdOrderCompLineNo;
ProdOrderComp.Validate("Item No.", ProdBOMLine[Level]."No.");
ProdOrderComp."Variant Code" := ProdBOMLine[Level]."Variant Code";
ProdOrderComp."Location Code" := SKU."Components at Location";
ProdOrderComp."Bin Code" := GetDefaultBin();
ProdOrderComp.Description := ProdBOMLine[Level].Description;
ProdOrderComp."Description 2" := ProdBOMLine[Level]."Description 2";
ProdOrderComp.Validate("Unit of Measure Code", ProdBOMLine[Level]."Unit of Measure Code");
if (ProdOrderComp."Item No." <> '') and Item2.Get(ProdOrderComp."Item No.") then
QtyRoundPrecision := UOMMgt.GetQtyRoundingPrecision(Item2, ProdBOMLine[Level]."Unit of Measure Code");
CheckingRoundingPrecision(Item2, ProdLineItem, QtyRoundPrecision, Level);
if (QtyRoundPrecision <> 0) and (QtyRoundPrecision < 1) then
ProdOrderComp."Quantity per" := Round(ProdBOMLine[Level]."Quantity per" * LineQtyPerUOM / ItemQtyPerUOM, UOMMgt.QtyRndPrecision())
else
ProdOrderComp."Quantity per" := ProdBOMLine[Level]."Quantity per" * LineQtyPerUOM / ItemQtyPerUOM;
ProdOrderComp.Length := ProdBOMLine[Level].Length;
ProdOrderComp.Width := ProdBOMLine[Level].Width;
ProdOrderComp.Weight := ProdBOMLine[Level].Weight;
ProdOrderComp.Depth := ProdBOMLine[Level].Depth;
ProdOrderComp.Position := ProdBOMLine[Level].Position;
ProdOrderComp."Position 2" := ProdBOMLine[Level]."Position 2";
ProdOrderComp."Position 3" := ProdBOMLine[Level]."Position 3";
ProdOrderComp."Lead-Time Offset" := ProdBOMLine[Level]."Lead-Time Offset";
ProdOrderComp.Validate("Routing Link Code", ProdBOMLine[Level]."Routing Link Code");
ProdOrderComp.Validate("Scrap %", ProdBOMLine[Level]."Scrap %");
ProdOrderComp.Validate("Calculation Formula", ProdBOMLine[Level]."Calculation Formula");
OnTransferBOMProcessItemOnBeforeGetPlanningParameters(ProdOrderComp, ProdBOMLine[Level], SKU);
GetPlanningParameters.AtSKU(
ComponentSKU, ProdOrderComp."Item No.", ProdOrderComp."Variant Code", ProdOrderComp."Location Code");
OnTransferBOMProcessItemOnAfterGetPlanningParameters(ProdOrderLine, ComponentSKU);
IsHandled := false;
OnTransferBOMProcessItemOnBeforeSetFlushingMethod(ProdOrderLine, ComponentSKU, ProdOrderComp, ProdBOMLine[Level], IsHandled);
if not IsHandled then
ProdOrderComp."Flushing Method" := ComponentSKU."Flushing Method";
if SetPlanningLevelCode(ProdOrderComp, ProdBOMLine[Level], SKU, ComponentSKU) then begin
if ProdOrderComp."Quantity per" = 0 then
exit;
ProdOrderComp."Planning Level Code" := ProdOrderLine."Planning Level Code" + 1;
Item2.Get(ProdOrderComp."Item No.");
ProdOrderComp."Item Low-Level Code" := Item2."Low-Level Code";
end;
ProdOrderComp.GetDefaultBin();
OnAfterTransferBOMComponent(ProdOrderLine, ProdBOMLine[Level], ProdOrderComp, LineQtyPerUOM, ItemQtyPerUOM);
ProdOrderComp.Insert(true);
OnAfterProdOrderCompInsert(ProdOrderComp, ProdBOMLine[Level]);
end else begin
ProdOrderComp.SetIgnoreErrors();
ProdOrderComp.SetCurrentKey(Status, "Prod. Order No."); // Reset key
ProdOrderComp.BlockDynamicTracking(Blocked);
ProdOrderComp.Validate(
"Quantity per",
ProdOrderComp."Quantity per" + ProdBOMLine[Level]."Quantity per" * LineQtyPerUOM / ItemQtyPerUOM);
ProdOrderComp.Validate("Routing Link Code", ProdBOMLine[Level]."Routing Link Code");
OnBeforeProdOrderCompModify(ProdOrderComp, ProdBOMLine[Level], LineQtyPerUOM, ItemQtyPerUOM);
ProdOrderComp.Modify();
end;
if ProdOrderComp.HasErrorOccured() then
ErrorOccured := true;
ProdOrderComp.AutoReserve();
CopyProdBOMComments(ProdBOMLine[Level]);
end;
local procedure SetPlanningLevelCode(var ProdOrderComponent: Record "Prod. Order Component"; var ProductionBOMLine: Record "Production BOM Line"; var SKU: Record "Stockkeeping Unit"; var ComponentSKU: Record "Stockkeeping Unit") Result: Boolean
begin
Result :=
(SKU."Manufacturing Policy" = SKU."Manufacturing Policy"::"Make-to-Order") and
(ComponentSKU."Manufacturing Policy" = ComponentSKU."Manufacturing Policy"::"Make-to-Order") and
(ComponentSKU."Replenishment System" = ComponentSKU."Replenishment System"::"Prod. Order");
OnAfterSetPlanningLevelCode(ProdOrderComponent, ProductionBOMLine, SKU, ComponentSKU, Result);
end;
procedure CalculateComponents()
var
ProdOrderComp: Record "Prod. Order Component";
IsHandled: Boolean;
begin
ProdOrderComp.SetRange(Status, ProdOrderLine.Status);
ProdOrderComp.SetRange("Prod. Order No.", ProdOrderLine."Prod. Order No.");
ProdOrderComp.SetRange("Prod. Order Line No.", ProdOrderLine."Line No.");
if ProdOrderComp.Find('-') then begin
repeat
ProdOrderComp.BlockDynamicTracking(Blocked);
IsHandled := false;
OnCalculateComponentsOnBeforeUpdateRoutingLinkCode(ProdOrderComp, ProdOrderLine, IsHandled);
if not IsHandled then begin
ProdOrderComp.Validate("Routing Link Code");
ProdOrderComp.Modify();
ProdOrderComp.AutoReserve();
end;
until ProdOrderComp.Next() = 0;
OnAfterCalculateComponents(ProdOrderLine);
end;
end;
procedure CalculateRoutingFromActual(ProdOrderRoutingLine: Record "Prod. Order Routing Line"; Direction: Option Forward,Backward; CalcStartEndDate: Boolean)
var
CalculateRoutingLine: Codeunit "Calculate Routing Line";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCalculateRoutingFromActual(ProdOrderRoutingLine, Direction, CalcStartEndDate, IsHandled);
if IsHandled then
exit;
if ProdOrderRouteMgt.NeedsCalculation(
ProdOrderRoutingLine.Status,
ProdOrderRoutingLine."Prod. Order No.",
ProdOrderRoutingLine."Routing Reference No.",
ProdOrderRoutingLine."Routing No.")
then begin
ProdOrderLine.SetRange(Status, ProdOrderRoutingLine.Status);
ProdOrderLine.SetRange("Prod. Order No.", ProdOrderRoutingLine."Prod. Order No.");
ProdOrderLine.SetRange("Routing Reference No.", ProdOrderRoutingLine."Routing Reference No.");
ProdOrderLine.SetRange("Routing No.", ProdOrderRoutingLine."Routing No.");
ProdOrderLine.FindFirst();
ProdOrderRouteMgt.Calculate(ProdOrderLine);
ProdOrderRoutingLine.Get(
ProdOrderRoutingLine.Status,
ProdOrderRoutingLine."Prod. Order No.",
ProdOrderRoutingLine."Routing Reference No.",
ProdOrderRoutingLine."Routing No.",
ProdOrderRoutingLine."Operation No.");
end;
if Direction = Direction::Forward then
ProdOrderRoutingLine.SetCurrentKey(Status, "Prod. Order No.", "Routing Reference No.",
"Routing No.", "Sequence No. (Forward)")
else
ProdOrderRoutingLine.SetCurrentKey(Status, "Prod. Order No.", "Routing Reference No.",
"Routing No.", "Sequence No. (Backward)");
ProdOrderRoutingLine.SetRange(Status, ProdOrderRoutingLine.Status);
ProdOrderRoutingLine.SetRange("Prod. Order No.", ProdOrderRoutingLine."Prod. Order No.");
ProdOrderRoutingLine.SetRange("Routing Reference No.", ProdOrderRoutingLine."Routing Reference No.");
ProdOrderRoutingLine.SetRange("Routing No.", ProdOrderRoutingLine."Routing No.");
ProdOrderRoutingLine.SetFilter("Routing Status", '<>%1', ProdOrderRoutingLine."Routing Status"::Finished);
OnCalculateRoutingFromActualOnAfterSetProdOrderRoutingLineFilters(ProdOrderRoutingLine);
repeat
OnCalculateRoutingFromActualOnBeforeCalcStartEndDate(ProdOrderRoutingLine, CalcStartEndDate);
if CalcStartEndDate and not ProdOrderRoutingLine."Schedule Manually" then
if ((Direction = Direction::Forward) and (ProdOrderRoutingLine."Previous Operation No." <> '')) or
((Direction = Direction::Backward) and (ProdOrderRoutingLine."Next Operation No." <> ''))
then begin
ProdOrderRoutingLine."Starting Time" := 0T;
ProdOrderRoutingLine."Starting Date" := 0D;
ProdOrderRoutingLine."Ending Time" := 235959T;
ProdOrderRoutingLine."Ending Date" := CalendarMgt.GetMaxDate();
end;
Clear(CalculateRoutingLine);
CalculateRoutingLine.CalculateRoutingLine(ProdOrderRoutingLine, Direction, CalcStartEndDate);
OnCalculateRoutingFromActualOnAfterCalculateRoutingLine(ProdOrderRoutingLine);
CalcStartEndDate := true;
until ProdOrderRoutingLine.Next() = 0;
end;
local procedure CalculateRouting(Direction: Option Forward,Backward; LetDueDateDecrease: Boolean)
var
ProdOrderRoutingLine: Record "Prod. Order Routing Line";
IsHandled: Boolean;
begin
if ProdOrderRouteMgt.NeedsCalculation(
ProdOrderLine.Status,
ProdOrderLine."Prod. Order No.",
ProdOrderLine."Routing Reference No.",
ProdOrderLine."Routing No.")
then
ProdOrderRouteMgt.Calculate(ProdOrderLine);
if Direction = Direction::Forward then
ProdOrderRoutingLine.SetCurrentKey(Status, "Prod. Order No.", "Routing Reference No.", "Routing No.",
"Sequence No. (Forward)")
else
ProdOrderRoutingLine.SetCurrentKey(Status, "Prod. Order No.", "Routing Reference No.", "Routing No.",
"Sequence No. (Backward)");
ProdOrderRoutingLine.SetRange(Status, ProdOrderLine.Status);
ProdOrderRoutingLine.SetRange("Prod. Order No.", ProdOrderLine."Prod. Order No.");
ProdOrderRoutingLine.SetRange("Routing Reference No.", ProdOrderLine."Routing Reference No.");
ProdOrderRoutingLine.SetRange("Routing No.", ProdOrderLine."Routing No.");
ProdOrderRoutingLine.SetFilter("Routing Status", '<>%1', ProdOrderRoutingLine."Routing Status"::Finished);
if not ProdOrderRoutingLine.FindFirst() then begin
OnCalculateRoutingOnBeforeSetLeadTime(ProdOrderLine);
CalculateLeadTime(ProdOrderLine, Direction, LetDueDateDecrease);
exit;
end;
IsHandled := false;
OnCalculateRoutingOnBeforeUpdateProdOrderRoutingLineDates(ProdOrderRoutingLine, ProdOrderLine, IsHandled);
if IsHandled then
exit;
if Direction = Direction::Forward then begin
ProdOrderRoutingLine."Starting Date" := ProdOrderLine."Starting Date";
ProdOrderRoutingLine."Starting Time" := ProdOrderLine."Starting Time";
end else begin
ProdOrderRoutingLine."Ending Date" := ProdOrderLine."Ending Date";
ProdOrderRoutingLine."Ending Time" := ProdOrderLine."Ending Time";
end;
ProdOrderRoutingLine.UpdateDatetime();
CalculateRoutingFromActual(ProdOrderRoutingLine, Direction, false);
CalculateProdOrderDates(ProdOrderLine, LetDueDateDecrease);
end;
procedure CalculateProdOrderDates(var ProdOrderLine: Record "Prod. Order Line"; LetDueDateDecrease: Boolean)
var
ProdOrderRoutingLine: Record "Prod. Order Routing Line";
NewDueDate: Date;
IsHandled: Boolean;
begin
OnBeforeCalculateProdOrderDates(ProdOrderLine);
ProdOrder.Get(ProdOrderLine.Status, ProdOrderLine."Prod. Order No.");
ProdOrderRoutingLine.SetRange(Status, ProdOrderLine.Status);
ProdOrderRoutingLine.SetRange("Prod. Order No.", ProdOrderLine."Prod. Order No.");
ProdOrderRoutingLine.SetRange("Routing No.", ProdOrderLine."Routing No.");
if ProdOrder."Source Type" <> ProdOrder."Source Type"::Family then
ProdOrderRoutingLine.SetRange("Routing Reference No.", ProdOrderLine."Line No.")
else
ProdOrderRoutingLine.SetRange("Routing Reference No.", 0);
ProdOrderRoutingLine.SetFilter("Routing Status", '<>%1', ProdOrderRoutingLine."Routing Status"::Finished);
ProdOrderRoutingLine.SetFilter("Next Operation No.", '%1', '');
OnCalculateProdOrderDatesOnAfterSetFilters(ProdOrderRoutingLine, ProdOrder, ProdOrderLine);
if ProdOrderRoutingLine.FindFirst() then begin
ProdOrderLine."Ending Date" := ProdOrderRoutingLine."Ending Date";
ProdOrderLine."Ending Time" := ProdOrderRoutingLine."Ending Time";
end;
ProdOrderRoutingLine.SetRange("Next Operation No.");
ProdOrderRoutingLine.SetFilter("Previous Operation No.", '%1', '');
if ProdOrderRoutingLine.FindFirst() then begin
ProdOrderLine."Starting Date" := ProdOrderRoutingLine."Starting Date";
ProdOrderLine."Starting Time" := ProdOrderRoutingLine."Starting Time";
end;
LeadTimeMgt.SetManualScheduling(ProdOrderLine."Manual Scheduling");
IsHandled := false;
OnCalculateProdOrderDatesOnSetBeforeDueDate(ProdOrderLine, IsHandled);
if not IsHandled then begin
if ProdOrderLine."Planning Level Code" = 0 then
NewDueDate :=
LeadTimeMgt.GetPlannedDueDate(
ProdOrderLine."Item No.", ProdOrderLine."Location Code", ProdOrderLine."Variant Code",
ProdOrderLine."Ending Date", '', "Requisition Ref. Order Type"::"Prod. Order")
else
NewDueDate := ProdOrderLine."Ending Date";
if LetDueDateDecrease or (NewDueDate > ProdOrderLine."Due Date") then
if ProdOrderLine.ConfirmUpdateDueDateAndEndingDate(ProdOrderLine.FieldCaption("Due Date"), NewDueDate) then
ProdOrderLine."Due Date" := NewDueDate;
end;
OnCalculateProdOrderDatesOnBeforeUpdateDatetime(ProdOrderLine, NewDueDate, LetDueDateDecrease);
ProdOrderLine.UpdateDatetime();
ProdOrderLine.Modify();
OnBeforeUpdateProdOrderDates(ProdOrder, ProdOrderLine, ProdOrderModify);
if not ProdOrderModify then begin
ProdOrder.Validate("Manual Scheduling", ProdOrderLine."Manual Scheduling");
ProdOrder.AdjustStartEndingDate();
ProdOrder.Modify();
end;
end;
procedure Calculate(ProdOrderLine2: Record "Prod. Order Line"; Direction: Option Forward,Backward; CalcRouting: Boolean; CalcComponents: Boolean; DeleteRelations: Boolean; LetDueDateDecrease: Boolean): Boolean
var
CapLedgEntry: Record "Capacity Ledger Entry";
ItemLedgEntry: Record "Item Ledger Entry";
ProdOrderRoutingLine3: Record "Prod. Order Routing Line";
ProdOrderRoutingLine4: Record "Prod. Order Routing Line";
RoutingHeader: Record "Routing Header";
ProdOrderRoutingLine: Record "Prod. Order Routing Line";
ErrorOccured: Boolean;
IsHandled: Boolean;
ShouldCheckIfEntriesExist: Boolean;
SkipCalcComponents: Boolean;
begin
ProdOrderLine := ProdOrderLine2;
IsHandled := false;
OnBeforeCalculate(ItemLedgEntry, CapLedgEntry, Direction, CalcRouting, CalcComponents, DeleteRelations, LetDueDateDecrease, IsHandled, ProdOrderLine, ErrorOccured);
if IsHandled then
exit(not ErrorOccured);
ShouldCheckIfEntriesExist := ProdOrderLine.Status = ProdOrderLine.Status::Released;
OnCalculateOnAfterCalcShouldCheckIfEntriesExist(ProdOrderLine, CalcRouting, ShouldCheckIfEntriesExist);
if ShouldCheckIfEntriesExist then begin
ItemLedgEntry.SetCurrentKey("Order Type", "Order No.");
ItemLedgEntry.SetRange("Order Type", ItemLedgEntry."Order Type"::Production);
ItemLedgEntry.SetRange("Order No.", ProdOrderLine."Prod. Order No.");
OnCalculateOnAfterItemLedgEntrySetFilters(ProdOrderLine, ItemLedgEntry);
if not ItemLedgEntry.IsEmpty() then
Error(
Text001,
ProdOrderLine.Status, ProdOrderLine.TableCaption(), ProdOrderLine."Prod. Order No.",
ItemLedgEntry.TableCaption());
CapLedgEntry.SetCurrentKey("Order Type", "Order No.");
CapLedgEntry.SetRange("Order Type", CapLedgEntry."Order Type"::Production);
CapLedgEntry.SetRange("Order No.", ProdOrderLine."Prod. Order No.");
OnCalculateOnAfterCapLedgEntrySetFilters(ProdOrderLine, CapLedgEntry);
if not CapLedgEntry.IsEmpty() then
Error(
Text001,
ProdOrderLine.Status, ProdOrderLine.TableCaption(), ProdOrderLine."Prod. Order No.",
CapLedgEntry.TableCaption());
end;
CheckProdOrderLineQuantity(ProdOrderLine);
if Direction = Direction::Backward then
ProdOrderLine.TestField("Ending Date")
else
ProdOrderLine.TestField("Starting Date");
if DeleteRelations then
ProdOrderLine.DeleteRelations();
if CalcRouting then begin
TransferRouting();
if not CalcComponents then begin // components will not be calculated later- update bin code
ProdOrderRoutingLine.SetRange(Status, ProdOrderLine.Status);
ProdOrderRoutingLine.SetRange("Prod. Order No.", ProdOrderLine."Prod. Order No.");
ProdOrderRoutingLine.SetRange("Routing Reference No.", ProdOrderLine."Routing Reference No.");
ProdOrderRoutingLine.SetRange("Routing No.", ProdOrderLine."Routing No.");
if not ProdOrderRouteMgt.UpdateComponentsBin(ProdOrderRoutingLine, true) then
ErrorOccured := true;
end;
end else
if RoutingHeader.Get(ProdOrderLine2."Routing No.") or (ProdOrderLine2."Routing No." = '') then
if RoutingHeader.Type <> RoutingHeader.Type::Parallel then begin
ProdOrderRoutingLine3.SetRange(Status, ProdOrderLine2.Status);
ProdOrderRoutingLine3.SetRange("Prod. Order No.", ProdOrderLine2."Prod. Order No.");
ProdOrderRoutingLine3.SetRange("Routing Reference No.", ProdOrderLine2."Routing Reference No.");
ProdOrderRoutingLine3.SetRange("Routing No.", ProdOrderLine2."Routing No.");
ProdOrderRoutingLine3.SetFilter("Routing Status", '<>%1', ProdOrderRoutingLine3."Routing Status"::Finished);
ProdOrderRoutingLine4.CopyFilters(ProdOrderRoutingLine3);
if ProdOrderRoutingLine3.Find('-') then
repeat
if ProdOrderRoutingLine3."Next Operation No." <> '' then begin
ProdOrderRoutingLine4.SetRange("Operation No.", ProdOrderRoutingLine3."Next Operation No.");
if ProdOrderRoutingLine4.IsEmpty() then begin
IsHandled := false;
OnCalculateOnBeforeCheckNextOperation(ProdOrder, ProdOrderLine2, ProdOrderRoutingLine3, IsHandled);
if not IsHandled then
Error(OperationCannotFollowErr, ProdOrderRoutingLine3."Next Operation No.");
end;
end;
if ProdOrderRoutingLine3."Previous Operation No." <> '' then begin
ProdOrderRoutingLine4.SetRange("Operation No.", ProdOrderRoutingLine3."Previous Operation No.");
if ProdOrderRoutingLine4.IsEmpty() then begin
IsHandled := false;
OnCalculateOnBeforeCheckPrevOperation(ProdOrder, ProdOrderLine2, ProdOrderRoutingLine3, IsHandled);
if not IsHandled then
Error(OperationCannotPrecedeErr, ProdOrderRoutingLine3."Previous Operation No.");
end;
end;
until ProdOrderRoutingLine3.Next() = 0;
end;
SkipCalcComponents := false;
OnCalculateOnBeforeCalcComponents(ProdOrderLine, CalcComponents, SkipCalcComponents);
if CalcComponents and not SkipCalcComponents then
if ProdOrderLine."Production BOM No." <> '' then begin
Item.Get(ProdOrderLine."Item No.");
GetPlanningParameters.AtSKU(
SKU,
ProdOrderLine."Item No.",
ProdOrderLine."Variant Code",
ProdOrderLine."Location Code");
OnCalculateOnAfterGetpLanningParameterAtSKUCalcComponents(ProdOrderLine, SKU);
CalculateLeadTime(ProdOrderLine, Direction, LetDueDateDecrease);
CalculateRouting(Direction, LetDueDateDecrease);
if not TransferBOM(
ProdOrderLine."Production BOM No.",
1,
ProdOrderLine."Qty. per Unit of Measure",
UOMMgt.GetQtyPerUnitOfMeasure(
Item,
VersionMgt.GetBOMUnitOfMeasure(
ProdOrderLine."Production BOM No.",
ProdOrderLine."Production BOM Version Code")))
then
ErrorOccured := true;
end;
Recalculate(ProdOrderLine, Direction, LetDueDateDecrease, CalcRouting, CalcComponents);
OnAfterCalculate(ProdOrderLine, ErrorOccured);
exit(not ErrorOccured);
end;
local procedure CopyProdBOMComments(ProdBOMLine: Record "Production BOM Line")
var
ProdBOMCommentLine: Record "Production BOM Comment Line";
ProdOrderCompCmtLine: Record "Prod. Order Comp. Cmt Line";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCopyProdBOMComments(ProdBOMCommentLine, ProdBOMLine, IsHandled);
if IsHandled then
exit;
ProdBOMCommentLine.SetRange("Production BOM No.", ProdBOMLine."Production BOM No.");
ProdBOMCommentLine.SetRange("BOM Line No.", ProdBOMLine."Line No.");
ProdBOMCommentLine.SetRange("Version Code", ProdBOMLine."Version Code");
if ProdBOMCommentLine.FindSet() then
repeat
ProdOrderCompCmtLine.CopyFromProdBOMComponent(ProdBOMCommentLine, ProdOrderComp);
if not ProdOrderCompCmtLine.Insert() then
ProdOrderCompCmtLine.Modify();
until ProdBOMCommentLine.Next() = 0;
end;
local procedure CopyRoutingComments(ProdOrderRoutingLine: Record "Prod. Order Routing Line"; VersionCode: Code[20])
var
RoutingCommentLine: Record "Routing Comment Line";
ProdOrderRtngCommentLine: Record "Prod. Order Rtng Comment Line";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCopyRoutingComments(RoutingCommentLine, ProdOrderRoutingLine, VersionCode, IsHandled);
if IsHandled then
exit;
RoutingCommentLine.SetRange("Routing No.", ProdOrderRoutingLine."Routing No.");
RoutingCommentLine.SetRange("Operation No.", ProdOrderRoutingLine."Operation No.");
RoutingCommentLine.SetRange("Version Code", VersionCode);
if RoutingCommentLine.Find('-') then
repeat
ProdOrderRtngCommentLine.TransferFields(RoutingCommentLine);
ProdOrderRtngCommentLine.Status := ProdOrderRoutingLine.Status;
ProdOrderRtngCommentLine."Prod. Order No." := ProdOrderRoutingLine."Prod. Order No.";
ProdOrderRtngCommentLine."Routing Reference No." := ProdOrderRoutingLine."Routing Reference No.";
ProdOrderRtngCommentLine.Insert();
until RoutingCommentLine.Next() = 0;
end;
local procedure CopyRoutingPersonnel(ProdOrderRoutingLine: Record "Prod. Order Routing Line"; VersionCode: Code[20])
var
RoutingPersonnel: Record "Routing Personnel";
ProdOrderRoutingPersonnel: Record "Prod. Order Routing Personnel";
begin
RoutingPersonnel.SetRange("Routing No.", ProdOrderRoutingLine."Routing No.");
RoutingPersonnel.SetRange("Operation No.", ProdOrderRoutingLine."Operation No.");
RoutingPersonnel.SetRange("Version Code", VersionCode);
if RoutingPersonnel.Find('-') then
repeat
ProdOrderRoutingPersonnel.TransferFields(RoutingPersonnel);
ProdOrderRoutingPersonnel.Status := ProdOrderRoutingLine.Status;
ProdOrderRoutingPersonnel."Prod. Order No." := ProdOrderRoutingLine."Prod. Order No.";
ProdOrderRoutingPersonnel."Routing Reference No." := ProdOrderRoutingLine."Routing Reference No.";
ProdOrderRoutingPersonnel.Insert();
until RoutingPersonnel.Next() = 0;
end;
local procedure CopyRoutingQualityMeasures(ProdOrderRoutingLine: Record "Prod. Order Routing Line"; VersionCode: Code[20])
var
RoutingQualityMeasure: Record "Routing Quality Measure";
ProdOrderRtngQltyMeas: Record "Prod. Order Rtng Qlty Meas.";
begin
RoutingQualityMeasure.SetRange("Routing No.", ProdOrderRoutingLine."Routing No.");
RoutingQualityMeasure.SetRange("Operation No.", ProdOrderRoutingLine."Operation No.");
RoutingQualityMeasure.SetRange("Version Code", VersionCode);
if RoutingQualityMeasure.Find('-') then
repeat
ProdOrderRtngQltyMeas.TransferFields(RoutingQualityMeasure);
ProdOrderRtngQltyMeas.Status := ProdOrderRoutingLine.Status;
ProdOrderRtngQltyMeas."Prod. Order No." := ProdOrderRoutingLine."Prod. Order No.";
ProdOrderRtngQltyMeas."Routing Reference No." := ProdOrderRoutingLine."Routing Reference No.";
ProdOrderRtngQltyMeas.Insert();
until RoutingQualityMeasure.Next() = 0;
end;
local procedure CopyRoutingTools(ProdOrderRoutingLine: Record "Prod. Order Routing Line"; VersionCode: Code[20])
var
RoutingTool: Record "Routing Tool";
ProdOrderRoutingTool: Record "Prod. Order Routing Tool";
begin
RoutingTool.SetRange("Routing No.", ProdOrderRoutingLine."Routing No.");
RoutingTool.SetRange("Operation No.", ProdOrderRoutingLine."Operation No.");
RoutingTool.SetRange("Version Code", VersionCode);
OnCopyRoutingToolsOnAfterRoutingToolSetFilters(RoutingTool, ProdOrderRoutingLine, VersionCode);
if RoutingTool.Find('-') then
repeat
ProdOrderRoutingTool.TransferFields(RoutingTool);
ProdOrderRoutingTool.Status := ProdOrderRoutingLine.Status;
ProdOrderRoutingTool."Prod. Order No." := ProdOrderRoutingLine."Prod. Order No.";
ProdOrderRoutingTool."Routing Reference No." := ProdOrderRoutingLine."Routing Reference No.";
ProdOrderRoutingTool.Insert();
until RoutingTool.Next() = 0;
end;
local procedure Recalculate(var ProdOrderLine: Record "Prod. Order Line"; Direction: Option; LetDueDateDecrease: Boolean; CalcRouting: Boolean; CalcComponents: Boolean)
begin
OnBeforeRecalculate(ProdOrderLine, CalcRouting, CalcComponents);
Recalculate(ProdOrderLine, Direction, LetDueDateDecrease);
OnAfterRecalculate(ProdOrderLine, CalcRouting, CalcComponents);
end;
procedure Recalculate(var ProdOrderLine2: Record "Prod. Order Line"; Direction: Option Forward,Backward; LetDueDateDecrease: Boolean)
var
IsHandled: Boolean;
begin
ProdOrderLine := ProdOrderLine2;
ProdOrderLine.BlockDynamicTracking(Blocked);
IsHandled := false;
OnRecalculateOnBeforeCalculateRouting(ProdOrderLine, IsHandled);
if not IsHandled then
CalculateRouting(Direction, LetDueDateDecrease);
CalculateComponents();
ProdOrderLine2 := ProdOrderLine;
OnAfterRecalculateProcedure(ProdOrderLine2);
end;
procedure BlockDynamicTracking(SetBlock: Boolean)
begin
Blocked := SetBlock;
end;
procedure SetParameter(NewProdOrderModify: Boolean)
begin
ProdOrderModify := NewProdOrderModify;
end;
local procedure GetDefaultBin() BinCode: Code[20]
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeGetDefaultBin(ProdOrderComp, Location, Item, ProdOrderWarehouseMgt, BinCode, IsHandled);
if IsHandled then
exit;
if ProdOrderComp."Location Code" <> '' then begin
if Location.Code <> ProdOrderComp."Location Code" then
Location.Get(ProdOrderComp."Location Code");
if Location."Bin Mandatory" and (not Location."Directed Put-away and Pick") then
ProdOrderWarehouseMgt.GetDefaultBin(ProdOrderComp."Item No.", ProdOrderComp."Variant Code", ProdOrderComp."Location Code", BinCode);
end;
end;
procedure SetProdOrderLineBinCodeFromRoute(var ProdOrderLine: Record "Prod. Order Line"; ParentLocationCode: Code[10]; RoutingNo: Code[20])
var
RouteBinCode: Code[20];
begin
RouteBinCode :=
ProdOrderWarehouseMgt.GetLastOperationFromBinCode(
RoutingNo,
ProdOrderLine."Routing Version Code",
ProdOrderLine."Location Code",
false,
"Flushing Method"::Manual);
SetProdOrderLineBinCode(ProdOrderLine, RouteBinCode, ParentLocationCode);
end;
procedure SetProdOrderLineBinCodeFromProdRtngLines(var ProdOrderLine: Record "Prod. Order Line")
var
ProdOrderRoutingLineBinCode: Code[20];
begin
if ProdOrderLine."Planning Level Code" > 0 then
exit;
ProdOrderRoutingLineBinCode :=
ProdOrderWarehouseMgt.GetProdRoutingLastOperationFromBinCode(
ProdOrderLine.Status, ProdOrderLine."Prod. Order No.", ProdOrderLine."Line No.",
ProdOrderLine."Routing No.", ProdOrderLine."Location Code");
SetProdOrderLineBinCode(ProdOrderLine, ProdOrderRoutingLineBinCode, ProdOrderLine."Location Code");
end;
procedure SetProdOrderLineBinCodeFromPlanningRtngLines(var ProdOrderLine: Record "Prod. Order Line"; ReqLine: Record "Requisition Line")
var
PlanningLinesBinCode: Code[20];
begin
if ProdOrderLine."Planning Level Code" > 0 then
exit;
PlanningLinesBinCode :=
ProdOrderWarehouseMgt.GetPlanningRtngLastOperationFromBinCode(
ReqLine."Worksheet Template Name",
ReqLine."Journal Batch Name",
ReqLine."Line No.",
ReqLine."Location Code");
SetProdOrderLineBinCode(ProdOrderLine, PlanningLinesBinCode, ReqLine."Location Code");
end;
local procedure SetProdOrderLineBinCode(var ProdOrderLine: Record "Prod. Order Line"; ParentBinCode: Code[20]; ParentLocationCode: Code[10])
var
Location: Record Location;
FromProdBinCode: Code[20];
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeSetProdOrderLineBinCode(ProdOrderLine, ParentBinCode, ParentLocationCode, IsHandled);
if IsHandled then
exit;
ProdOrder.Get(ProdOrderLine.Status, ProdOrderLine."Prod. Order No.");
if (ProdOrder."Location Code" = ProdOrderLine."Location Code") and (ProdOrder."Bin Code" <> '') then begin
ProdOrderLine.Validate("Bin Code", ProdOrder."Bin Code");
exit;
end;
if ParentBinCode <> '' then
ProdOrderLine.Validate("Bin Code", ParentBinCode)
else
if ProdOrderLine."Bin Code" = '' then begin
if Location.Get(ParentLocationCode) then
FromProdBinCode := Location."From-Production Bin Code";
if FromProdBinCode <> '' then
ProdOrderLine.Validate("Bin Code", FromProdBinCode)
else
if Location."Bin Mandatory" and not Location."Directed Put-away and Pick" then
if ProdOrderWarehouseMgt.GetDefaultBin(ProdOrderLine."Item No.", ProdOrderLine."Variant Code", Location.Code, FromProdBinCode) then
ProdOrderLine.Validate("Bin Code", FromProdBinCode);
end;
end;
procedure FindAndSetProdOrderLineBinCodeFromProdRoutingLines(ProdOrderStatus: Enum "Production Order Status"; ProdOrderNo: Code[20]; ProdOrderLineNo: Integer)
begin
if ProdOrderLine.Get(ProdOrderStatus, ProdOrderNo, ProdOrderLineNo) then begin
SetProdOrderLineBinCodeFromProdRtngLines(ProdOrderLine);
ProdOrderLine.Modify();
end;
end;
procedure AssignProdOrderLineBinCodeFromProdRtngLineMachineCenter(var ProdOrderRoutingLine: Record "Prod. Order Routing Line")
var
MachineCenter: Record "Machine Center";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeAssignProdOrderLineBinCodeFromProdRtngLineMachineCenter(ProdOrderRoutingLine, MachineCenter, IsHandled);
if IsHandled then
exit;
MachineCenter.SetRange("Work Center No.", ProdOrderRoutingLine."Work Center No.");
if PAGE.RunModal(PAGE::"Machine Center List", MachineCenter) = ACTION::LookupOK then
if (ProdOrderRoutingLine."No." <> MachineCenter."No.") or
(ProdOrderRoutingLine.Type = ProdOrderRoutingLine.Type::"Work Center")
then begin
ProdOrderRoutingLine.Type := ProdOrderRoutingLine.Type::"Machine Center";
ProdOrderRoutingLine.Validate("No.", MachineCenter."No.");
FindAndSetProdOrderLineBinCodeFromProdRoutingLines(
ProdOrderRoutingLine.Status, ProdOrderRoutingLine."Prod. Order No.", ProdOrderRoutingLine."Routing Reference No.");
end;
end;
[IntegrationEvent(false, false)]
local procedure OnAfterCalculate(ProdOrderLine: Record "Prod. Order Line"; var ErrorOccured: Boolean)
begin
end;
local procedure CalculateLeadTime(ProdOrderLine2: Record "Prod. Order Line"; Direction: Option Forward,Backward; LetDueDateDecrease: Boolean)
var
LeadTime: Code[20];
begin
ProdOrderLine := ProdOrderLine2;
LeadTimeMgt.SetManualScheduling(ProdOrderLine2."Manual Scheduling");
LeadTime :=
LeadTimeMgt.ManufacturingLeadTime(
ProdOrderLine."Item No.", ProdOrderLine."Location Code", ProdOrderLine."Variant Code");
if Direction = Direction::Forward then
// Ending Date calculated forward from Starting Date
ProdOrderLine."Ending Date" :=
LeadTimeMgt.GetPlannedEndingDate(
ProdOrderLine."Item No.", ProdOrderLine."Location Code", ProdOrderLine."Variant Code", '',
LeadTime, "Requisition Ref. Order Type"::"Prod. Order", ProdOrderLine."Starting Date")
else
// Starting Date calculated backward from Ending Date
ProdOrderLine."Starting Date" :=
LeadTimeMgt.GetPlannedStartingDate(
ProdOrderLine."Item No.", ProdOrderLine."Location Code", ProdOrderLine."Variant Code", '',
LeadTime, "Requisition Ref. Order Type"::"Prod. Order", ProdOrderLine."Ending Date");
CalculateProdOrderDates(ProdOrderLine, LetDueDateDecrease);
ProdOrderLine2 := ProdOrderLine;
end;
local procedure CheckProdOrderLineQuantity(var ProdOrderLineToCheck: Record "Prod. Order Line")
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCheckProdOrderLineQuantity(ProdOrderLineToCheck, IsHandled);
if not IsHandled then
ProdOrderLineToCheck.TestField(Quantity);
end;
local procedure CheckingRoundingPrecision(ChildItem: Record Item; ProdLineItem: Record Item; var QtyRoundPrecision: Decimal; Level: Integer)
begin
if (ChildItem."Rounding Precision" = 0) or (QtyRoundPrecision = 0) then
exit;
if (not ProdLineItem.Get(ProdOrderLine."Item No.")) or (ProdLineItem."Replenishment System" <> ProdLineItem."Replenishment System"::"Prod. Order") then
exit;
if (ChildItem."Base Unit of Measure" <> ProdBOMLine[Level]."Unit of Measure Code") then
exit;
QtyRoundPrecision := ChildItem."Rounding Precision";
ProdOrderComp."Qty. Rounding Precision" := ChildItem."Rounding Precision";
ProdOrderComp."Qty. Rounding Precision (Base)" := ChildItem."Rounding Precision";
end;
[IntegrationEvent(false, false)]
local procedure OnAfterInsertProdRoutingLine(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; ProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterTransferBOM(ProdOrder: Record "Production Order"; ProdOrderLine: Record "Prod. Order Line"; ProdBOMNo: Code[20]; Level: Integer; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal; Blocked: Boolean; var ErrorOccured: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterTransferTaskInfo(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; VersionCode: Code[20])
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterTransferRouting(var ProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterTransferRoutingLine(var ProdOrderLine: Record "Prod. Order Line"; var RoutingLine: Record "Routing Line"; var ProdOrderRoutingLine: Record "Prod. Order Routing Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterTransferBOMComponent(var ProdOrderLine: Record "Prod. Order Line"; var ProductionBOMLine: Record "Production BOM Line"; var ProdOrderComponent: Record "Prod. Order Component"; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterProdOrderCompFilter(var ProdOrderComp: Record "Prod. Order Component"; ProdBOMLine: Record "Production BOM Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterProdOrderCompInsert(var ProdOrderComponent: Record "Prod. Order Component"; ProductionBOMLine: Record "Production BOM Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeAssignProdOrderLineBinCodeFromProdRtngLineMachineCenter(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; var MachineCenter: Record "Machine Center"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCalculate(var ItemLedgerEntry: Record "Item Ledger Entry"; var CapacityLedgerEntry: Record "Capacity Ledger Entry"; Direction: Option Forward,Backward; CalcRouting: Boolean; CalcComponents: Boolean; var DeleteRelations: Boolean; LetDueDateDecrease: Boolean; var IsHandled: Boolean; var ProdOrderLine: Record "Prod. Order Line"; var ErrorOccured: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCalculateRoutingFromActual(ProdOrderRoutingLine: Record "Prod. Order Routing Line"; Direction: Option; CalcStartEndDate: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCalculateProdOrderDates(var ProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCopyProdBOMComments(var ProductionBOMCommentLine: Record "Production BOM Comment Line"; var ProductionBOMLine: Record "Production BOM Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeProdOrderCompModify(var ProdOrderComp: Record "Prod. Order Component"; var ProdBOMLine: Record "Production BOM Line"; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeSetProdOrderLineBinCode(var ProdOrderLine: Record "Prod. Order Line"; ParentBinCode: Code[20]; ParentLocationCode: Code[10]; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeTransferBOM(var ProdOrder: Record "Production Order"; var ProdOrderLine: Record "Prod. Order Line"; ProdBOMNo: Code[20]; Level: Integer; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal; Blocked: Boolean; var ErrorOccured: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeTransferBOMComponent(ProdOrder: Record "Production Order"; ProdOrderLine: Record "Prod. Order Line"; var ProdBOMLine: Record "Production BOM Line"; var ErrorOccured: Boolean; var IsHandled: Boolean; Level: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeTransferRouting(var ProdOrder: Record "Production Order"; var ProdOrderLine: Record "Prod. Order Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateProdOrderDates(var ProductionOrder: Record "Production Order"; var ProdOrderLine: Record "Prod. Order Line"; var ProdOrderModify: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateOnAfterGetpLanningParameterAtSKUCalcComponents(var ProdOrderLine: Record "Prod. Order Line"; var SKU: Record "Stockkeeping Unit")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateOnAfterCalcShouldCheckIfEntriesExist(var ProdOrderLine: Record "Prod. Order Line"; var CalcRouting: Boolean; var ShouldCheckIfEntriesExist: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateOnAfterItemLedgEntrySetFilters(ProdOrderLine: Record "Prod. Order Line"; var ItemLedgerEntry: Record "Item Ledger Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateOnBeforeCheckNextOperation(ProdOrder: Record "Production Order"; ProdOrderLine2: Record "Prod. Order Line"; var ProdOrderRoutingLine3: Record "Prod. Order Routing Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateOnBeforeCheckPrevOperation(ProdOrder: Record "Production Order"; ProdOrderLine2: Record "Prod. Order Line"; var ProdOrderRoutingLine3: Record "Prod. Order Routing Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateComponentsOnBeforeUpdateRoutingLinkCode(var ProdOrderComp: Record "Prod. Order Component"; ProdOrderLine: Record "Prod. Order Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateProdOrderDatesOnAfterSetFilters(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; ProductionOrder: Record "Production Order"; ProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateProdOrderDatesOnSetBeforeDueDate(var ProdOrderLine: Record "Prod. Order Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateProdOrderDatesOnBeforeUpdateDatetime(var ProdOrderLine: Record "Prod. Order Line"; NewDueDate: Date; LetDueDateDecreate: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateRoutingFromActualOnAfterSetProdOrderRoutingLineFilters(var ProdOrderRoutingLine: Record "Prod. Order Routing Line");
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateRoutingFromActualOnBeforeCalcStartEndDate(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; var CalcStartEndDate: Boolean);
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCopyRoutingToolsOnAfterRoutingToolSetFilters(var RoutingTool: Record "Routing Tool"; ProdOrderRoutingLine: Record "Prod. Order Routing Line"; VersionCode: Code[20])
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferBOMOnAfterCalcReqQty(ProductionBOMLine: Record "Production BOM Line"; ProdOrderRoutingLine: Record "Prod. Order Routing Line"; ProdOrderLine: Record "Prod. Order Line"; var ReqQty: Decimal; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferBOMOnAfterSetFiltersProdBOMLine(var ProdBOMLine: Record "Production BOM Line"; ProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferBOMOnBeforeProcessItem(ProdBOMLine: Record "Production BOM Line"; ReqQty: Decimal; var SkipTransfer: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferBOMOnBeforeProcessProdBOM(ProdBOMLine: Record "Production BOM Line"; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal; var ReqQty: Decimal; var ProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferBOMOnAfterProcessProdBOM(var ProductionBOMLine: Record "Production BOM Line"; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal; var ReqQty: Decimal; ProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferBOMOnBeforeTransferNestedProdBOM(ProductionBOMLine: Record "Production BOM Line"; LineQtyPerUOM: Decimal; ItemQtyPerUOM: Decimal; var ReqQty: Decimal; var ProdOrderLine: Record "Prod. Order Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferBOMProcessItemOnAfterGetPlanningParameters(var ProdOrderLine: Record "Prod. Order Line"; var ComponentSKU: Record "Stockkeeping Unit")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferBOMProcessItemOnBeforeGetPlanningParameters(var ProdOrderComponent: Record "Prod. Order Component"; ProductionBOMLine: Record "Production BOM Line"; StockkeepingUnit: Record "Stockkeeping Unit")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferRoutingOnbeforeValidateDirectUnitCost(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; ProdOrderLine: Record "Prod. Order Line"; RoutingLine: Record "Routing Line")
begin
end;
[IntegrationEvent(false, false)]
procedure OnTransferRoutingOnBeforeCalcRoutingCostPerUnit(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; ProdOrderLine: Record "Prod. Order Line"; RoutingLine: Record "Routing Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateRoutingOnBeforeSetLeadTime(var ProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterCalculateComponents(ProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeRecalculate(var ProdOrderLine: Record "Prod. Order Line"; CalcRouting: Boolean; CalcComponents: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterRecalculate(var ProdOrderLine: Record "Prod. Order Line"; CalcRouting: Boolean; CalcComponents: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterRecalculateProcedure(var ProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
procedure OnRecalculateOnBeforeCalculateRouting(var ProdOrderLine: Record "Prod. Order Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferBOMProcessItemOnBeforeSetFlushingMethod(var ProdOrderLine: Record "Prod. Order Line"; var ComponentSKU: Record "Stockkeeping Unit"; var ProdOrderComp: Record "Prod. Order Component"; ProdBOMLine: Record "Production BOM Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterSetPlanningLevelCode(var ProdOrderComponent: Record "Prod. Order Component"; var ProductionBOMLine: Record "Production BOM Line"; var SKU: Record "Stockkeeping Unit"; var ComponentSKU: Record "Stockkeeping Unit"; var Result: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeProcessRoutingLine(var RoutingLine: Record "Routing Line"; var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; ProdOrderLine: Record "Prod. Order Line"; ProductionOrder: Record "Production Order"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCopyRoutingComments(var RoutingCommentLine: Record "Routing Comment Line"; ProdOrderRoutingLine: Record "Prod. Order Routing Line"; VersionCode: Code[20]; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateRoutingOnBeforeUpdateProdOrderRoutingLineDates(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; var ProdOrderLine: Record "Prod. Order Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCheckProdOrderLineQuantity(ProdOrderLine: Record "Prod. Order Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateOnBeforeCalcComponents(ProdOrderLine: Record "Prod. Order Line"; CalcComponents: Boolean; var SkipCalcComponents: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateOnAfterCapLedgEntrySetFilters(var ProdOrderLine: Record "Prod. Order Line"; var CapacityLedgerEntry: Record "Capacity Ledger Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeGetDefaultBin(var ProdOrderComponent: Record "Prod. Order Component"; var Location: Record Location; var Item: Record Item; var ProdOrderWarehouseMgt: Codeunit "Prod. Order Warehouse Mgt."; var BinCode: Code[20]; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeFindProdOrderRoutingLine(var ProdOrderLine: Record "Prod. Order Line"; var ProductionBOMLine: Record "Production BOM Line"; var IsHandled: Boolean; var ReqQty: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateRoutingFromActualOnAfterCalculateRoutingLine(var ProdOrderRoutingLine: Record "Prod. Order Routing Line")
begin
end;
}