Table extension 99000820 Mfg. BOM Buffer, source in 29
Source29
src/Layers/W1/BaseApp/Manufacturing/Inventory/BOM/MfgBOMBuffer.TableExt.al371 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.BOM;
using Microsoft.Foundation.UOM;
using Microsoft.Inventory.Costing;
using Microsoft.Inventory.Item;
using Microsoft.Manufacturing.Capacity;
using Microsoft.Manufacturing.Document;
using Microsoft.Manufacturing.MachineCenter;
using Microsoft.Manufacturing.ProductionBOM;
using Microsoft.Manufacturing.Routing;
using Microsoft.Manufacturing.WorkCenter;
tableextension 99000820 "Mfg. BOM Buffer" extends "BOM Buffer"
{
fields
{
modify("No.")
{
TableRelation =
if (Type = const("Machine Center")) "Machine Center"
else
if (Type = const("Work Center")) "Work Center";
}
field(15; "Routing No."; Code[20])
{
Caption = 'Routing No.';
DataClassification = SystemMetadata;
TableRelation = "Routing Header";
}
field(16; "Production BOM No."; Code[20])
{
Caption = 'Production BOM No.';
DataClassification = SystemMetadata;
TableRelation = "Production BOM Header";
}
}
var
#pragma warning disable AA0074
#pragma warning disable AA0470
Text003: Label 'Routing %1 has not been certified.';
Text004: Label 'Production BOM %1 has not been certified.';
#pragma warning restore AA0470
#pragma warning restore AA0074
procedure TransferFromProdComp(var EntryNo: Integer; ProdBOMLine: Record "Production BOM Line"; NewIndentation: Integer; ParentQtyPer: Decimal; ParentScrapQtyPer: Decimal; ParentScrapPct: Decimal; NeedByDate: Date; ParentLocationCode: Code[10]; ParentItem: Record Item; BOMQtyPerUOM: Decimal)
var
BOMItem: Record Item;
OriginalItem: Record Item;
MfgCostCalcMgt: Codeunit "Mfg. Cost Calculation Mgt.";
UOMMgt: Codeunit "Unit of Measure Management";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeTransferFromProdComp(EntryNo, ProdBOMLine, NewIndentation, ParentQtyPer, ParentScrapQtyPer, ParentScrapPct, NeedByDate, ParentLocationCode, ParentItem, BOMQtyPerUOM, IsHandled);
if not IsHandled then begin
Init();
EntryNo += 1;
"Entry No." := EntryNo;
Type := Type::Item;
OriginalItem.Get(ParentItem."No."); // to assign "Routing No."
BOMItem.Get(ProdBOMLine."No.");
InitFromItem(BOMItem);
if ParentItem."Lot Size" = 0 then
ParentItem."Lot Size" := 1;
Description := ProdBOMLine.Description;
"Qty. per Parent" :=
MfgCostCalcMgt.CalcCompItemQtyBase(
ProdBOMLine, WorkDate(),
MfgCostCalcMgt.CalcQtyAdjdForBOMScrap(ParentItem."Lot Size", ParentScrapPct), OriginalItem."Routing No.", true) /
UOMMgt.GetQtyPerUnitOfMeasure(BOMItem, ProdBOMLine."Unit of Measure Code") /
BOMQtyPerUOM / ParentItem."Lot Size";
"Qty. per Top Item" := Round(ParentQtyPer * "Qty. per Parent", UOMMgt.QtyRndPrecision());
"Qty. per Parent" := Round("Qty. per Parent", UOMMgt.QtyRndPrecision());
"Scrap Qty. per Parent" := "Qty. per Parent" - (ProdBOMLine.Quantity / BOMQtyPerUOM);
"Scrap Qty. per Top Item" :=
"Qty. per Top Item" -
Round((ParentQtyPer - ParentScrapQtyPer) * ("Qty. per Parent" - "Scrap Qty. per Parent"), UOMMgt.QtyRndPrecision());
"Scrap Qty. per Parent" := Round("Scrap Qty. per Parent", UOMMgt.QtyRndPrecision());
"Qty. per BOM Line" := ProdBOMLine."Quantity per";
"Unit of Measure Code" := ProdBOMLine."Unit of Measure Code";
"Variant Code" := ProdBOMLine."Variant Code";
"Location Code" := ParentLocationCode;
"Lead-Time Offset" := ProdBOMLine."Lead-Time Offset";
"Needed by Date" := NeedByDate;
Indentation := NewIndentation;
if ProdBOMLine."Calculation Formula" = ProdBOMLine."Calculation Formula"::"Fixed Quantity" then
"Calculation Formula" := ProdBOMLine."Calculation Formula";
OnTransferFromProdCompCopyFields(Rec, ProdBOMLine, ParentItem, ParentQtyPer, ParentScrapQtyPer);
Insert(true);
end;
OnAfterTransferFromProdComp(Rec, ProdBOMLine, ParentItem, EntryNo)
end;
procedure TransferFromProdOrderLine(var EntryNo: Integer; ProdOrderLine: Record "Prod. Order Line")
var
BOMItem: Record Item;
begin
Init();
EntryNo += 1;
"Entry No." := EntryNo;
Type := Type::Item;
BOMItem.Get(ProdOrderLine."Item No.");
InitFromItem(BOMItem);
"Scrap %" := ProdOrderLine."Scrap %";
"Production BOM No." := ProdOrderLine."Production BOM No.";
"Qty. per Parent" := 1;
"Qty. per Top Item" := 1;
"Unit of Measure Code" := ProdOrderLine."Unit of Measure Code";
"Variant Code" := ProdOrderLine."Variant Code";
"Location Code" := ProdOrderLine."Location Code";
"Needed by Date" := ProdOrderLine."Due Date";
Indentation := 0;
OnTransferFromProdOrderLineCopyFields(Rec, ProdOrderLine);
Insert(true);
end;
procedure TransferFromProdOrderComp(var EntryNo: Integer; ProdOrderComp: Record "Prod. Order Component")
var
BOMItem: Record Item;
begin
Init();
EntryNo += 1;
"Entry No." := EntryNo;
Type := Type::Item;
BOMItem.Get(ProdOrderComp."Item No.");
InitFromItem(BOMItem);
"Qty. per Parent" := ProdOrderComp."Quantity per";
"Qty. per Top Item" := ProdOrderComp."Quantity per";
"Unit of Measure Code" := ProdOrderComp."Unit of Measure Code";
"Variant Code" := ProdOrderComp."Variant Code";
"Location Code" := ProdOrderComp."Location Code";
"Needed by Date" := ProdOrderComp."Due Date";
"Lead-Time Offset" := ProdOrderComp."Lead-Time Offset";
Indentation := 1;
OnTransferFromProdOrderCompCopyFields(Rec, ProdOrderComp);
Insert(true);
end;
procedure TransferFromProdRouting(var EntryNo: Integer; RoutingLine: Record "Routing Line"; NewIndentation: Integer; ParentQtyPer: Decimal; NeedByDate: Date; ParentLocationCode: Code[10])
var
MachineCenter: Record "Machine Center";
WorkCenter: Record "Work Center";
RunTimeQty: Decimal;
SetupWaitMoveTimeQty: Decimal;
begin
Init();
EntryNo += 1;
"Entry No." := EntryNo;
case RoutingLine.Type of
RoutingLine.Type::"Machine Center":
begin
MachineCenter.Get(RoutingLine."No.");
InitFromMachineCenter(MachineCenter);
end;
RoutingLine.Type::"Work Center":
begin
WorkCenter.Get(RoutingLine."No.");
InitFromWorkCenter(WorkCenter);
end;
end;
Description := RoutingLine.Description;
CalcQtyPerParentFromProdRouting(RoutingLine, RunTimeQty, SetupWaitMoveTimeQty);
"Qty. per Parent" := SetupWaitMoveTimeQty + RunTimeQty;
"Qty. per Top Item" := SetupWaitMoveTimeQty + RunTimeQty * ParentQtyPer;
"Location Code" := ParentLocationCode;
"Needed by Date" := NeedByDate;
Indentation := NewIndentation;
OnTransferFromProdRoutingCopyFields(Rec, RoutingLine);
Insert(true);
end;
procedure InitFromMachineCenter(MachineCenter: Record "Machine Center")
var
WorkCenter: Record "Work Center";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeInitFromMachineCenter(Rec, MachineCenter, IsHandled);
if IsHandled then
exit;
Type := Type::"Machine Center";
"No." := MachineCenter."No.";
Description := MachineCenter.Name;
if MachineCenter."Work Center No." <> '' then begin
WorkCenter.Get(MachineCenter."Work Center No.");
"Unit of Measure Code" := WorkCenter."Unit of Measure Code";
end;
"Replenishment System" := "Replenishment System"::Transfer;
"Is Leaf" := true;
OnAfterInitFromMachineCenter(Rec, MachineCenter);
end;
procedure InitFromWorkCenter(WorkCenter: Record "Work Center")
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeInitFromWorkCenter(Rec, WorkCenter, IsHandled);
if IsHandled then
exit;
Type := Type::"Work Center";
"No." := WorkCenter."No.";
Description := WorkCenter.Name;
"Unit of Measure Code" := WorkCenter."Unit of Measure Code";
"Replenishment System" := "Replenishment System"::Transfer;
"Is Leaf" := true;
OnAfterInitFromWorkCenter(Rec, WorkCenter);
end;
local procedure CalcQtyPerParentFromProdRouting(RoutingLine: Record "Routing Line"; var RunTimeQty: Decimal; var SetupWaitMoveTimeQty: Decimal)
var
WorkCenter: Record "Work Center";
CalendarMgt: Codeunit "Shop Calendar Management";
SetupTimeFactor: Decimal;
RunTimeFactor: Decimal;
WaitTimeFactor: Decimal;
MoveTimeFactor: Decimal;
CurrentTimeFactor: Decimal;
LotSizeFactor: Decimal;
begin
SetupTimeFactor := CalendarMgt.TimeFactor(RoutingLine."Setup Time Unit of Meas. Code");
RunTimeFactor := CalendarMgt.TimeFactor(RoutingLine."Run Time Unit of Meas. Code");
WaitTimeFactor := CalendarMgt.TimeFactor(RoutingLine."Wait Time Unit of Meas. Code");
MoveTimeFactor := CalendarMgt.TimeFactor(RoutingLine."Move Time Unit of Meas. Code");
if RoutingLine."Lot Size" = 0 then
LotSizeFactor := 1
else
LotSizeFactor := RoutingLine."Lot Size";
RunTimeQty := RoutingLine."Run Time" * RunTimeFactor / LotSizeFactor;
SetupWaitMoveTimeQty :=
(RoutingLine."Setup Time" * SetupTimeFactor + RoutingLine."Wait Time" * WaitTimeFactor +
RoutingLine."Move Time" * MoveTimeFactor) / LotSizeFactor;
if "Unit of Measure Code" = '' then begin
// select base UOM from Setup/Run/Wait/Move UOMs
CurrentTimeFactor := SetupTimeFactor;
"Unit of Measure Code" := RoutingLine."Setup Time Unit of Meas. Code";
if CurrentTimeFactor > RunTimeFactor then begin
CurrentTimeFactor := RunTimeFactor;
"Unit of Measure Code" := RoutingLine."Run Time Unit of Meas. Code";
end;
if CurrentTimeFactor > WaitTimeFactor then begin
CurrentTimeFactor := WaitTimeFactor;
"Unit of Measure Code" := RoutingLine."Wait Time Unit of Meas. Code";
end;
if CurrentTimeFactor > MoveTimeFactor then begin
CurrentTimeFactor := MoveTimeFactor;
"Unit of Measure Code" := RoutingLine."Move Time Unit of Meas. Code";
end;
end;
if not WorkCenter.Get(RoutingLine."Work Center No.") then
WorkCenter.Init();
RunTimeQty :=
Round(RunTimeQty / CalendarMgt.TimeFactor("Unit of Measure Code"), WorkCenter."Calendar Rounding Precision");
SetupWaitMoveTimeQty :=
Round(SetupWaitMoveTimeQty / CalendarMgt.TimeFactor("Unit of Measure Code"), WorkCenter."Calendar Rounding Precision");
end;
procedure IsProdBOMOk(LogWarning: Boolean; var BOMWarningLog: Record "BOM Warning Log"): Boolean
var
ProdBOMHeader: Record "Production BOM Header";
begin
if "Production BOM No." = '' then
exit(true);
ProdBOMHeader.Get("Production BOM No.");
if ProdBOMHeader.Status = ProdBOMHeader.Status::Certified then
exit(true);
if LogWarning then
BOMWarningLog.SetWarning(
StrSubstNo(Text004, ProdBOMHeader."No."), DATABASE::"Production BOM Header", CopyStr(ProdBOMHeader.GetPosition(), 1, 250));
end;
procedure IsRoutingOk(LogWarning: Boolean; var BOMWarningLog: Record "BOM Warning Log"): Boolean
var
RoutingHeader: Record "Routing Header";
begin
if "Routing No." = '' then
exit(true);
RoutingHeader.Get("Routing No.");
if RoutingHeader.Status = RoutingHeader.Status::Certified then
exit(true);
if LogWarning then
BOMWarningLog.SetWarning(
StrSubstNo(Text003, RoutingHeader."No."), DATABASE::"Routing Header", CopyStr(RoutingHeader.GetPosition(), 1, 250));
end;
[IntegrationEvent(false, false)]
local procedure OnAfterInitFromMachineCenter(var BOMBuffer: Record "BOM Buffer"; MachineCenter: Record "Machine Center");
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterInitFromWorkCenter(var BOMBuffer: Record "BOM Buffer"; WorkCenter: Record "Work Center");
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterTransferFromProdComp(var BOMBuffer: Record "BOM Buffer"; ProductionBOMLine: Record "Production BOM Line"; ParentItem: Record Item; var EntryNo: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeInitFromMachineCenter(var BOMBuffer: Record "BOM Buffer"; MachineCenter: Record "Machine Center"; var IsHandled: Boolean);
begin
end;
[IntegrationEvent(false, false)]
local procedure OnbeforeInitFromWorkCenter(var BOMBuffer: Record "BOM Buffer"; WorkCenter: Record "Work Center"; var IsHandled: Boolean);
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeTransferFromProdComp(var EntryNo: Integer; ProductionBOMLine: Record "Production BOM Line"; NewIndentation: Integer; ParentQtyPer: Decimal; ParentScrapQtyPer: Decimal; ParentScrapPct: Decimal; NeedByDate: Date; ParentLocationCode: Code[10]; ParentItem: Record Item; BOMQtyPerUOM: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferFromProdCompCopyFields(var BOMBuffer: Record "BOM Buffer"; ProductionBOMLine: Record "Production BOM Line"; ParentItem: Record Item; ParentQtyPer: Decimal; ParentScrapQtyPer: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferFromProdOrderLineCopyFields(var BOMBuffer: Record "BOM Buffer"; ProdOrderLine: Record "Prod. Order Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferFromProdOrderCompCopyFields(var BOMBuffer: Record "BOM Buffer"; ProdOrderComponent: Record "Prod. Order Component")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferFromProdRoutingCopyFields(var BOMBuffer: Record "BOM Buffer"; RoutingLine: Record "Routing Line")
begin
end;
}