Codeunit 99000776 Mfg. InventoryAdjmtEntryOrder, source in 29
Source29
src/Layers/W1/BaseApp/Manufacturing/Inventory/Costing/MfgInventoryAdjmtEntryOrder.Codeunit.al229 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.Costing;
using Microsoft.Inventory.Item;
using Microsoft.Inventory.Journal;
using Microsoft.Inventory.Ledger;
using Microsoft.Inventory.Location;
using Microsoft.Inventory.Reports;
using Microsoft.Manufacturing.Document;
codeunit 99000776 "Mfg. InventoryAdjmtEntryOrder"
{
var
MfgCostCalcMgt: Codeunit "Mfg. Cost Calculation Mgt.";
#if not CLEAN27
CalcInventoryAdjmtOrder: Codeunit "Calc. Inventory Adjmt. - Order";
#endif
#pragma warning disable AA0074
#pragma warning disable AA0470
Text009: Label 'This %1 Order has not been adjusted.';
#pragma warning restore AA0470
#pragma warning restore AA0074
[EventSubscriber(ObjectType::Table, Database::"Inventory Adjmt. Entry (Order)", 'OnAfterRoundAmounts', '', true, false)]
local procedure OnAfterRoundAmounts(var InventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; RndPrecLCY: Decimal; RndPrecACY: Decimal; ShareOfTotalCost: Decimal; RndResLCY: Decimal; RndResACY: Decimal)
begin
if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then begin
InventoryAdjmtEntryOrder."Direct Cost Non-Inventory" :=
InventoryAdjmtEntryOrder.RoundCost(InventoryAdjmtEntryOrder."Direct Cost Non-Inventory", ShareOfTotalCost, RndResLCY, RndPrecLCY);
InventoryAdjmtEntryOrder."Single-Lvl Mat. Non-Invt. Cost" :=
InventoryAdjmtEntryOrder.RoundCost(InventoryAdjmtEntryOrder."Single-Lvl Mat. Non-Invt. Cost", ShareOfTotalCost, RndResLCY, RndPrecLCY);
InventoryAdjmtEntryOrder."Direct Cost Non-Inv. (ACY)" :=
InventoryAdjmtEntryOrder.RoundCost(InventoryAdjmtEntryOrder."Direct Cost Non-Inv. (ACY)", ShareOfTotalCost, RndResACY, RndPrecACY);
InventoryAdjmtEntryOrder."Single-Lvl Mat.NonInvCost(ACY)" :=
InventoryAdjmtEntryOrder.RoundCost(InventoryAdjmtEntryOrder."Single-Lvl Mat.NonInvCost(ACY)", ShareOfTotalCost, RndResACY, RndPrecACY);
end;
end;
[EventSubscriber(ObjectType::Table, Database::"Inventory Adjmt. Entry (Order)", 'OnGetSingleLevelCostsOnAfterCopyCostsLCY', '', true, false)]
local procedure OnGetInsgleLevelCostsOnAfterCopyCostsLCY(var InventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; Item: Record Item)
begin
if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then
InventoryAdjmtEntryOrder."Single-Lvl Mat. Non-Invt. Cost" := Item."Single-Lvl Mat. Non-Invt. Cost";
end;
[EventSubscriber(ObjectType::Table, Database::"Inventory Adjmt. Entry (Order)", 'OnGetSingleLevelCostsOnAfterCopyCostsACY', '', true, false)]
local procedure OnGetInsgleLevelCostsOnAfterCopyCostsACY(var InventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; Item: Record Item; CurrExchRate: Decimal)
begin
if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then
InventoryAdjmtEntryOrder."Single-Lvl Mat.NonInvCost(ACY)" := InventoryAdjmtEntryOrder."Single-Lvl Mat. Non-Invt. Cost" * CurrExchRate;
end;
[EventSubscriber(ObjectType::Table, Database::"Inventory Adjmt. Entry (Order)", 'OnUpdatedFromSKUOnAfterCopyCostFromSKU', '', true, false)]
local procedure OnUpdatedFromSKUOnAfterCopyCostFromSKU(var InventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; StockkeepingUnit: Record "Stockkeeping Unit")
begin
if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then
InventoryAdjmtEntryOrder."Single-Lvl Mat. Non-Invt. Cost" := StockkeepingUnit."Single-Lvl Mat. Non-Invt. Cost";
end;
[EventSubscriber(ObjectType::Table, Database::"Inventory Adjmt. Entry (Order)", 'OnAfterCalcUnitCost', '', true, false)]
local procedure OnAfterCalcUnitCost(var InventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)")
begin
if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then
InventoryAdjmtEntryOrder."Unit Cost" += InventoryAdjmtEntryOrder."Direct Cost Non-Inventory";
end;
[EventSubscriber(ObjectType::Table, Database::"Inventory Adjmt. Entry (Order)", 'OnAfterCalcDiff', '', true, false)]
local procedure OnAfterCalcDiff(var InvtAdjmtEntryOrderRec: Record "Inventory Adjmt. Entry (Order)"; var InvtAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; OnlyCostShares: Boolean)
begin
if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then begin
if not OnlyCostShares then begin
InvtAdjmtEntryOrderRec."Direct Cost Non-Inventory" := InvtAdjmtEntryOrder."Direct Cost Non-Inventory" - InvtAdjmtEntryOrderRec."Direct Cost Non-Inventory";
InvtAdjmtEntryOrderRec."Direct Cost Non-Inv. (ACY)" := InvtAdjmtEntryOrder."Direct Cost Non-Inv. (ACY)" - InvtAdjmtEntryOrderRec."Direct Cost Non-Inv. (ACY)";
end;
InvtAdjmtEntryOrderRec."Single-Lvl Mat. Non-Invt. Cost" := InvtAdjmtEntryOrder."Single-Lvl Mat. Non-Invt. Cost" - InvtAdjmtEntryOrderRec."Single-Lvl Mat. Non-Invt. Cost";
InvtAdjmtEntryOrderRec."Single-Lvl Mat.NonInvCost(ACY)" := InvtAdjmtEntryOrder."Single-Lvl Mat.NonInvCost(ACY)" - InvtAdjmtEntryOrderRec."Single-Lvl Mat.NonInvCost(ACY)";
end;
end;
[EventSubscriber(ObjectType::Table, Database::"Inventory Adjmt. Entry (Order)", 'OnAddDirectCostNonInv', '', true, false)]
local procedure OnAddDirectCostNonInv(var InventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; CostAmtLCY: Decimal; CostAmtACY: Decimal)
begin
if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then begin
InventoryAdjmtEntryOrder."Direct Cost Non-Inventory" += CostAmtLCY;
InventoryAdjmtEntryOrder."Direct Cost Non-Inv. (ACY)" += CostAmtACY;
end;
end;
[EventSubscriber(ObjectType::Table, Database::"Inventory Adjmt. Entry (Order)", 'OnAddSingleLvlNonInvMaterialCost', '', true, false)]
local procedure OnAddSingleLvlNonInvMaterialCost(var InventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; CostAmtLCY: Decimal; CostAmtACY: Decimal)
begin
if MfgCostCalcMgt.CanIncNonInvCostIntoProductionItem() then begin
InventoryAdjmtEntryOrder."Single-Lvl Mat. Non-Invt. Cost" += CostAmtLCY;
InventoryAdjmtEntryOrder."Single-Lvl Mat.NonInvCost(ACY)" += CostAmtACY;
end;
end;
[EventSubscriber(ObjectType::Table, Database::"Inventory Adjmt. Entry (Order)", 'OnFindProdOrderLine', '', true, false)]
local procedure OnFindProdOrderLine(var InventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; var Item: Record Item; var StockkeepingUnit: Record "Stockkeeping Unit"; var Found: Boolean)
var
ProdOrderLine: Record "Prod. Order Line";
begin
Found := true;
ProdOrderLine.SetLoadFields("Prod. Order No.", "Line No.", "Location Code", "Item No.", "Variant Code");
ProdOrderLine.SetRange("Prod. Order No.", InventoryAdjmtEntryOrder."Order No.");
ProdOrderLine.SetRange("Line No.", InventoryAdjmtEntryOrder."Order Line No.");
if not ProdOrderLine.FindFirst() then
Found := false;
if not StockkeepingUnit.Get(ProdOrderLine."Location Code", Item."No.", ProdOrderLine."Variant Code") then
Found := false;
end;
[EventSubscriber(ObjectType::Report, Report::"Close Inventory Period - Test", 'OnStoreOrderInErrorBuffer', '', true, false)]
local procedure OnStoreOrderInErrorBuffer(InventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; sender: Report "Close Inventory Period - Test")
var
ProductionOrder: Record "Production Order";
RecRef: RecordRef;
Bookmark: Text[250];
begin
case InventoryAdjmtEntryOrder."Order Type" of
InventoryAdjmtEntryOrder."Order Type"::Production:
begin
ProductionOrder.Get(ProductionOrder.Status::Finished, InventoryAdjmtEntryOrder."Order No.");
RecRef.GetTable(ProductionOrder);
Bookmark := Format(RecRef.RecordId, 0, 10);
sender.StoreItemInErrorBuffer(
InventoryAdjmtEntryOrder."Item No.", DATABASE::"Inventory Adjmt. Entry (Order)",
StrSubstNo(Text009, InventoryAdjmtEntryOrder."Order Type"), Bookmark, InventoryAdjmtEntryOrder."Order No.",
PAGE::"Finished Production Order");
end;
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Calc. Inventory Adjmt. - Order", 'OnCalcActualCapacityCostsInternal', '', true, false)]
local procedure OnCalcActualCapacityCostsInternal(var InvtAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)")
begin
CalcActualCapacityCosts(InvtAdjmtEntryOrder);
end;
local procedure CalcActualCapacityCosts(var InvtAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)")
var
CapLedgEntry: Record Microsoft.Manufacturing.Capacity."Capacity Ledger Entry";
ShareOfTotalCapCost: Decimal;
IsHandled: Boolean;
begin
ShareOfTotalCapCost := CalcShareOfCapCost(InvtAdjmtEntryOrder);
CapLedgEntry.SetCurrentKey("Order Type", "Order No.", "Order Line No.", "Routing No.", "Routing Reference No.");
CapLedgEntry.SetRange("Order Type", InvtAdjmtEntryOrder."Order Type");
CapLedgEntry.SetRange("Order No.", InvtAdjmtEntryOrder."Order No.");
CapLedgEntry.SetRange("Routing No.", InvtAdjmtEntryOrder."Routing No.");
CapLedgEntry.SetRange("Routing Reference No.", InvtAdjmtEntryOrder."Routing Reference No.");
CapLedgEntry.SetRange("Item No.", InvtAdjmtEntryOrder."Item No.");
IsHandled := false;
OnCalcActualCapacityCostsOnAfterSetFilters(CapLedgEntry, InvtAdjmtEntryOrder, IsHandled, ShareOfTotalCapCost);
#if not CLEAN27
CalcInventoryAdjmtOrder.RunOnCalcActualCapacityCostsOnAfterSetFilters(CapLedgEntry, InvtAdjmtEntryOrder, IsHandled, ShareOfTotalCapCost);
#endif
if not IsHandled then
if CapLedgEntry.Find('-') then
repeat
CapLedgEntry.CalcFields("Direct Cost", "Direct Cost (ACY)", "Overhead Cost", "Overhead Cost (ACY)");
if CapLedgEntry.Subcontracting then
InvtAdjmtEntryOrder.AddSingleLvlSubcontrdCost(CapLedgEntry."Direct Cost" * ShareOfTotalCapCost, CapLedgEntry."Direct Cost (ACY)" *
ShareOfTotalCapCost)
else
InvtAdjmtEntryOrder.AddSingleLvlCapacityCost(
CapLedgEntry."Direct Cost" * ShareOfTotalCapCost, CapLedgEntry."Direct Cost (ACY)" * ShareOfTotalCapCost);
InvtAdjmtEntryOrder.AddSingleLvlCapOvhdCost(
CapLedgEntry."Overhead Cost" * ShareOfTotalCapCost, CapLedgEntry."Overhead Cost (ACY)" * ShareOfTotalCapCost);
until CapLedgEntry.Next() = 0;
end;
local procedure CalcShareOfCapCost(InvtAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)") ShareOfCapCost: Decimal
var
CapLedgEntry: Record Microsoft.Manufacturing.Capacity."Capacity Ledger Entry";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCalcShareOfCapCost(InvtAdjmtEntryOrder, ShareOfCapCost, IsHandled);
#if not CLEAN27
CalcInventoryAdjmtOrder.RunOnBeforeCalcShareOfCapCost(InvtAdjmtEntryOrder, ShareOfCapCost, IsHandled);
#endif
if IsHandled then
exit(ShareOfCapCost);
if InvtAdjmtEntryOrder."Order Type" = InvtAdjmtEntryOrder."Order Type"::Assembly then
exit(1);
CapLedgEntry.SetCurrentKey("Order Type", "Order No.");
CapLedgEntry.SetRange("Order Type", InvtAdjmtEntryOrder."Order Type");
CapLedgEntry.SetRange("Order No.", InvtAdjmtEntryOrder."Order No.");
CapLedgEntry.SetRange("Order Line No.", InvtAdjmtEntryOrder."Order Line No.");
CapLedgEntry.SetRange("Routing No.", InvtAdjmtEntryOrder."Routing No.");
CapLedgEntry.SetRange("Routing Reference No.", InvtAdjmtEntryOrder."Routing Reference No.");
CapLedgEntry.SetRange("Item No.", InvtAdjmtEntryOrder."Item No.");
CapLedgEntry.CalcSums(CapLedgEntry."Output Quantity");
ShareOfCapCost := CapLedgEntry."Output Quantity";
if InvtAdjmtEntryOrder."Order Type" = InvtAdjmtEntryOrder."Order Type"::Production then
CapLedgEntry.SetRange("Order Line No.");
CapLedgEntry.CalcSums(CapLedgEntry."Output Quantity");
if CapLedgEntry."Output Quantity" <> 0 then
ShareOfCapCost := ShareOfCapCost / CapLedgEntry."Output Quantity"
else
ShareOfCapCost := 1;
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCalcShareOfCapCost(var InvtAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; var ShareOfCapCost: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalcActualCapacityCostsOnAfterSetFilters(var CapLedgEntry: Record Microsoft.Manufacturing.Capacity."Capacity Ledger Entry"; var InventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; var IsHandled: Boolean; ShareOfTotalCapCost: Decimal)
begin
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Inventory Adjustment", 'OnAfterInitAdjmtJnlLine', '', true, false)]
local procedure OnAfterInitAdjmtJnlLine(var ItemJnlLine: Record "Item Journal Line"; OrigValueEntry: Record "Value Entry"; EntryType: Enum "Cost Entry Type"; VarianceType: Enum "Cost Variance Type"; InvoicedQty: Decimal)
begin
if OrigValueEntry."Item Ledger Entry Type" = OrigValueEntry."Item Ledger Entry Type"::Output then
ItemJnlLine."Output Quantity (Base)" := ItemJnlLine."Quantity (Base)";
end;
}