-
Notifications
You must be signed in to change notification settings - Fork 688
Description
Why do you need this change?
Is it possible to add additional events to Codeunit 99000774, "Calculate Routing Line"?
The relevant events are described in the code below.
A customer requires capacity to be calculated based on simulated production orders. We have implemented a solution by using the existing event to override the procedures. However, this approach requires duplicating base application code, which is not ideal—especially with regard to future changes.
Duplicating code increases maintenance effort and risk, and we would prefer not to re-test logic that already exists and is validated in the base application.
Our suggestion is to add events that make it possible to control whether the logic that excludes simulated production orders should be executed. This would allow extensions to adjust the behavior without overriding or duplicating standard code.
local procedure InitProdOrderCapNeed(ProdOrder: Record "Production Order"; var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; var ProdOrderCapNeed: Record "Prod. Order Capacity Need"; TimeType: Enum "Routing Time Type"; NeedDate: Date; StartingTime: Time; EndingTime: Time; NeedQty: Decimal)
var
ActuallyPostedTime: Decimal;
DistributedCapNeed: Decimal;
// >>>>>>>>>>
ShouldUpdateAllocatedTimeAndExpectedCapacityNeed: Boolean;
// <<<<<<<<<<
begin
OnBeforeInitProdOrderCapNeed(ProdOrder, ProdOrderRoutingLine, ProdOrderCapNeed, TimeType, NeedDate, StartingTime, EndingTime, NeedQty, LotSize);
ProdOrderCapNeed.Init();
ProdOrderCapNeed.Status := ProdOrder.Status;
ProdOrderCapNeed."Prod. Order No." := ProdOrder."No.";
ProdOrderCapNeed."Routing No." := ProdOrderRoutingLine."Routing No.";
ProdOrderCapNeed."Routing Reference No." := ProdOrderRoutingLine."Routing Reference No.";
ProdOrderCapNeed."Line No." := NextCapNeedLineNo;
ProdOrderCapNeed.Type := ProdOrderRoutingLine.Type;
ProdOrderCapNeed."No." := ProdOrderRoutingLine."No.";
ProdOrderCapNeed."Work Center No." := ProdOrderRoutingLine."Work Center No.";
ProdOrderCapNeed."Operation No." := ProdOrderRoutingLine."Operation No.";
ProdOrderCapNeed."Work Center Group Code" := ProdOrderRoutingLine."Work Center Group Code";
ProdOrderCapNeed.Date := NeedDate;
ProdOrderCapNeed."Starting Time" := StartingTime;
ProdOrderCapNeed."Ending Time" := EndingTime;
ProdOrderCapNeed."Needed Time" := NeedQty;
ProdOrderCapNeed."Needed Time (ms)" := NeedQty * CalendarMgt.TimeFactor(Workcenter."Unit of Measure Code");
ProdOrderCapNeed."Concurrent Capacities" := ConCurrCap;
ProdOrderCapNeed.Efficiency := CalendarEntry.Efficiency;
ProdOrderCapNeed."Requested Only" := false;
ProdOrderCapNeed.Active := true;
// >>>>>>>>>
//if ProdOrder.Status <> ProdOrder.Status::Simulated then begin
ShouldUpdateAllocatedTimeAndExpectedCapacityNeed := ProdOrder.Status <> ProdOrder.Status::Simulated;
OnInitProdOrderCapNeedOnBeforeUpdateAllocatedTimeAndExpectedCapacityNeed(ProdOrderCapNeed; ShouldUpdateAllocatedTimeAndExpectedCapacityNeed)
if ShouldUpdateAllocatedTimeAndExpectedCapacityNeed then begin
// <<<<<<<<<
ActuallyPostedTime := CalcActuallyPostedCapacityTime(ProdOrderRoutingLine, TimeType);
DistributedCapNeed := CalcDistributedCapacityNeedForOperation(ProdOrderRoutingLine, TimeType);
ProdOrderCapNeed."Allocated Time" := NeedQty - ActuallyPostedTime + DistributedCapNeed;
if ProdOrderCapNeed."Allocated Time" < 0 then
ProdOrderCapNeed."Allocated Time" := 0;
ProdOrderRoutingLine."Expected Capacity Need" :=
ProdOrderRoutingLine."Expected Capacity Need" + ProdOrderCapNeed."Needed Time (ms)";
end;
OnAfterInitProdOrderCapNeed(ProdOrder, ProdOrderRoutingLine, ProdOrderCapNeed, NeedQty, TimeType, ActuallyPostedTime, DistributedCapNeed);
end;
[IntegrationEvent(false, false)]
local procedure OnInitProdOrderCapNeedOnBeforeUpdateAllocatedTimeAndExpectedCapacityNeed(var ProdOrderCapacityNeed: Record "Prod. Order Capacity Need"; var ShouldUpdateAllocatedTimeAndExpectedCapacityNeed: Boolean)
begin
end;
local procedure UpdateTimesBack(var AvailTime: Decimal; var AvailCap: Decimal; var TimetoProgram: Decimal; var StartTime: Time; EndTime: Time)
var
RoundedTimetoProgram: Decimal;
IsHandled: Boolean;
// >>>>>>>>>>
ShouldUpdateAvailCap: Boolean;
// <<<<<<<<<<
begin
IsHandled := false;
OnBeforeUpdateTimesBack(CalendarEntry, ProdOrderRoutingLine, AvailTime, AvailCap, TimetoProgram, StartTime, EndTime, ConCurrCap, Workcenter, RemainNeedQty, IsHandled);
if IsHandled then
exit;
AvailTime :=
Round(AvailTime / CalendarMgt.TimeFactor(Workcenter."Unit of Measure Code") *
CalendarEntry.Efficiency / 100 * ConCurrCap, Workcenter."Calendar Rounding Precision");
TimetoProgram := Min(RemainNeedQty, AvailTime);
RoundedTimetoProgram :=
Round(TimetoProgram *
CalendarMgt.TimeFactor(Workcenter."Unit of Measure Code") *
100 / CalendarEntry.Efficiency / ConCurrCap, 1, '>');
StartTime := CalendarMgt.CalcTimeSubtract(EndTime, RoundedTimetoProgram);
RemainNeedQty := RemainNeedQty - TimetoProgram;
// >>>>>>>>>>
//if ProdOrderRoutingLine.Status <> ProdOrderRoutingLine.Status::Simulated then
ShouldUpdateAvailCap := ProdOrderRoutingLine.Status <> ProdOrderRoutingLine.Status::Simulated;
OnUpdateTimesBackOnBeforeUpdateAvailCap(ProdOrderRoutingLine, ShouldUpdateAvailCap);
if ShouldUpdateAvailCap then
// <<<<<<<<<<
AvailCap := AvailCap - RoundedTimetoProgram;
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateTimesBackOnBeforeUpdateAvailCap(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; var ShouldUpdateAvailCap: Boolean)
begin
end;
local procedure UpdateTimesForward(var AvailTime: Decimal; var AvailCap: Decimal; var TimetoProgram: Decimal; StartTime: Time; var EndTime: Time)
var
RoundedTimetoProgram: Decimal;
IsHandled: Boolean;
// >>>>>>>>>>
ShouldUpdateAvailCap: Boolean;
// <<<<<<<<<<
begin
IsHandled := false;
OnBeforeUpdateTimesForward(CalendarEntry, ProdOrderRoutingLine, AvailTime, AvailCap, TimetoProgram, StartTime, EndTime, ConCurrCap, Workcenter, RemainNeedQty, IsHandled);
if IsHandled then
exit;
AvailTime :=
Round(AvailTime / CalendarMgt.TimeFactor(Workcenter."Unit of Measure Code") *
CalendarEntry.Efficiency / 100 * ConCurrCap, Workcenter."Calendar Rounding Precision");
TimetoProgram := Min(RemainNeedQty, AvailTime);
RoundedTimetoProgram :=
Round(TimetoProgram *
CalendarMgt.TimeFactor(Workcenter."Unit of Measure Code") *
100 / CalendarEntry.Efficiency / ConCurrCap, 1, '>');
EndTime := StartTime + RoundedTimetoProgram;
RemainNeedQty := RemainNeedQty - TimetoProgram;
//if ProdOrderRoutingLine.Status <> ProdOrderRoutingLine.Status::Simulated then
ShouldUpdateAvailCap := ProdOrderRoutingLine.Status <> ProdOrderRoutingLine.Status::Simulated;
OnUpdateTimesForwardOnBeforeUpdateAvailCap(ProdOrderRoutingLine, ShouldUpdateAvailCap);
if ShouldUpdateAvailCap then
// <<<<<<<<<<
AvailCap := AvailCap - RoundedTimetoProgram;
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateTimesForwardOnBeforeUpdateAvailCap(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; var ShouldUpdateAvailCap: Boolean)
begin
end;
Describe the request
View description for reason.