Codeunit 928 Assembly Line Invt. Profile, source in 29
Source29
src/Layers/W1/BaseApp/Assembly/Document/AssemblyLineInvtProfile.Codeunit.al223 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.Assembly.Document;
using Microsoft.Inventory.Item;
using Microsoft.Inventory.Planning;
using Microsoft.Inventory.Requisition;
using Microsoft.Inventory.Tracking;
using Microsoft.Sales.Document;
codeunit 928 "Assembly Line Invt. Profile"
{
// Inventory Profile
procedure TransferInventoryProfileFromAsmLine(var InventoryProfile: Record "Inventory Profile"; var AssemblyLine: Record "Assembly Line"; var TrackingReservationEntry: Record "Reservation Entry")
var
ReservationEntry: Record "Reservation Entry";
AutoReservedQty: Decimal;
begin
AssemblyLine.TestField(Type, AssemblyLine.Type::Item);
InventoryProfile.SetSource(
Database::"Assembly Line", AssemblyLine."Document Type".AsInteger(), AssemblyLine."Document No.", AssemblyLine."Line No.", '', 0);
InventoryProfile."Ref. Order Type" := InventoryProfile."Ref. Order Type"::Assembly;
InventoryProfile."Ref. Order No." := AssemblyLine."Document No.";
InventoryProfile."Ref. Line No." := AssemblyLine."Line No.";
InventoryProfile."Item No." := AssemblyLine."No.";
InventoryProfile."Variant Code" := AssemblyLine."Variant Code";
InventoryProfile."Location Code" := AssemblyLine."Location Code";
InventoryProfile."Bin Code" := AssemblyLine."Bin Code";
AssemblyLine.CalcFields("Reserved Qty. (Base)");
AssemblyLine.SetReservationFilters(ReservationEntry);
AutoReservedQty := -InventoryProfile.TransferBindings(ReservationEntry, TrackingReservationEntry);
InventoryProfile."Untracked Quantity" := AssemblyLine."Remaining Quantity (Base)" - AssemblyLine."Reserved Qty. (Base)" + AutoReservedQty;
InventoryProfile.Quantity := AssemblyLine.Quantity;
InventoryProfile."Remaining Quantity" := AssemblyLine."Remaining Quantity";
InventoryProfile."Finished Quantity" := AssemblyLine."Consumed Quantity";
InventoryProfile."Quantity (Base)" := AssemblyLine."Quantity (Base)";
InventoryProfile."Remaining Quantity (Base)" := AssemblyLine."Remaining Quantity (Base)";
InventoryProfile."Unit of Measure Code" := AssemblyLine."Unit of Measure Code";
InventoryProfile."Qty. per Unit of Measure" := AssemblyLine."Qty. per Unit of Measure";
InventoryProfile.IsSupply := InventoryProfile."Untracked Quantity" < 0;
InventoryProfile."Due Date" := AssemblyLine."Due Date";
InventoryProfile."Planning Flexibility" := InventoryProfile."Planning Flexibility"::None;
OnAfterTransferInventoryProrileFromAssemblyLine(InventoryProfile, AssemblyLine);
end;
[IntegrationEvent(false, false)]
local procedure OnAfterTransferInventoryProrileFromAssemblyLine(var InventoryProfile: Record "Inventory Profile"; var AssemblyLine: Record "Assembly Line")
begin
end;
[EventSubscriber(ObjectType::Table, Database::"Inventory Profile", 'OnTransferToTrackingEntrySourceTypeElseCase', '', true, true)]
local procedure OnTransferToTrackingEntrySourceTypeElseCase(var InventoryProfile: Record "Inventory Profile"; var ReservationEntry: Record "Reservation Entry"; var IsHandled: Boolean)
begin
if InventoryProfile."Source Type" = Database::"Assembly Line" then begin
if InventoryProfile."Source Order Status" = 4 then begin
// Blanket Order will be marked as Surplus
ReservationEntry."Reservation Status" := ReservationEntry."Reservation Status"::Surplus;
ReservationEntry."Suppressed Action Msg." := true;
end;
ReservationEntry.SetSource(
Database::"Assembly Line", InventoryProfile."Source Order Status", InventoryProfile."Source ID", InventoryProfile."Source Ref. No.", '', 0);
IsHandled := true;
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Inventory Profile Offsetting", 'OnAfterDemandToInvProfile', '', true, true)]
local procedure OnAfterDemandToInvProfile(var InventoryProfile: Record "Inventory Profile"; var Item: Record Item; var ReservEntry: Record "Reservation Entry"; var NextLineNo: Integer)
begin
TransAssemblyLineToProfile(InventoryProfile, Item, ReservEntry, NextLineNo);
end;
local procedure TransAssemblyLineToProfile(var InventoryProfile: Record "Inventory Profile"; var Item: Record Item; var TempReservationEntry: Record "Reservation Entry" temporary; var NextLineNo: Integer)
var
AssemblyHeader: Record "Assembly Header";
AssemblyLine: Record "Assembly Line";
ReqLine: Record "Requisition Line";
RemRatio: Decimal;
begin
if AssemblyLine.FindItemToPlanLines(Item, AssemblyLine."Document Type"::Order) then
repeat
if AssemblyLine."Due Date" <> 0D then begin
ReqLine.SetRefOrderFilters(
ReqLine."Ref. Order Type"::Assembly, AssemblyLine."Document Type".AsInteger(), AssemblyLine."Document No.", 0);
ReqLine.SetOperationNoFilterToBlank();
if not ReqLine.FindFirst() then
InsertAssemblyLineToProfile(InventoryProfile, AssemblyLine, 1, TempReservationEntry, NextLineNo);
end;
until AssemblyLine.Next() = 0;
if AssemblyLine.FindItemToPlanLines(Item, AssemblyLine."Document Type"::"Blanket Order") then
repeat
if AssemblyLine."Due Date" <> 0D then begin
ReqLine.SetRefOrderFilters(
ReqLine."Ref. Order Type"::Assembly, AssemblyLine."Document Type".AsInteger(), AssemblyLine."Document No.", 0);
ReqLine.SetOperationNoFilterToBlank();
if not ReqLine.FindFirst() then begin
AssemblyHeader.Get(AssemblyLine."Document Type", AssemblyLine."Document No.");
RemRatio := (AssemblyHeader."Quantity (Base)" - CalcSalesOrderQty(AssemblyLine)) / AssemblyHeader."Quantity (Base)";
InsertAssemblyLineToProfile(InventoryProfile, AssemblyLine, RemRatio, TempReservationEntry, NextLineNo);
end;
end;
until AssemblyLine.Next() = 0;
end;
local procedure InsertAssemblyLineToProfile(var InventoryProfile: Record "Inventory Profile"; AssemblyLine: Record "Assembly Line"; RemRatio: Decimal; var TempReservationEntry: Record "Reservation Entry" temporary; var NextLineNo: Integer)
var
UOMMgt: Codeunit Microsoft.Foundation.UOM."Unit of Measure Management";
begin
InventoryProfile.Init();
NextLineNo += 1;
InventoryProfile."Line No." := NextLineNo;
TransferInventoryProfileFromAsmLine(InventoryProfile, AssemblyLine, TempReservationEntry);
if RemRatio <> 1 then begin
InventoryProfile."Untracked Quantity" := Round(InventoryProfile."Untracked Quantity" * RemRatio, UOMMgt.QtyRndPrecision());
InventoryProfile."Remaining Quantity (Base)" := InventoryProfile."Untracked Quantity";
end;
if InventoryProfile.IsSupply then
InventoryProfile.ChangeSign();
InventoryProfile.Insert();
end;
local procedure CalcSalesOrderQty(AssemblyLine: Record "Assembly Line") QtyOnSalesOrder: Decimal
var
SalesOrderLine: Record "Sales Line";
ATOLink: Record "Assemble-to-Order Link";
begin
QtyOnSalesOrder := 0;
ATOLink.Get(AssemblyLine."Document Type", AssemblyLine."Document No.");
SalesOrderLine.SetCurrentKey("Document Type", "Blanket Order No.", "Blanket Order Line No.");
SalesOrderLine.SetRange("Document Type", SalesOrderLine."Document Type"::Order);
SalesOrderLine.SetRange("Blanket Order No.", ATOLink."Document No.");
SalesOrderLine.SetRange("Blanket Order Line No.", ATOLink."Document Line No.");
if SalesOrderLine.Find('-') then
repeat
QtyOnSalesOrder += SalesOrderLine."Quantity (Base)";
until SalesOrderLine.Next() = 0;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Inventory Profile Offsetting", 'OnAfterSetDemandPriority', '', true, true)]
local procedure OnAfterSetDemandPriority(var InventoryProfile: Record "Inventory Profile")
begin
if InventoryProfile."Source Type" = Database::"Assembly Line" then
InventoryProfile."Order Priority" := 470;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Inventory Profile Offsetting", 'OnForecastConsumptionOnAfterSetPlanningSourceTypeFilter', '', true, true)]
local procedure OnForecastConsumptionOnAfterSetPlanningSourceTypeFilter(var DemandInventoryProfile: Record "Inventory Profile")
begin
DemandInventoryProfile.SetSourceTypeFilter(Database::"Assembly Line");
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Inventory Profile Offsetting", 'OnGetComponentsOnUpdateForActionMessage', '', true, true)]
local procedure OnGetComponentsOnUpdateForActionMessage(var RequisitionLine: Record "Requisition Line"; sender: Codeunit "Inventory Profile Offsetting")
var
AssemblyLine: Record "Assembly Line";
PlanningComponent: Record "Planning Component";
begin
if RequisitionLine."Action Message" <> RequisitionLine."Action Message"::New then
case RequisitionLine."Ref. Order Type" of
RequisitionLine."Ref. Order Type"::Assembly:
begin
AssemblyLine.SetRange("Document Type", AssemblyLine."Document Type"::Order);
AssemblyLine.SetRange("Document No.", RequisitionLine."Ref. Order No.");
AssemblyLine.SetRange(Type, AssemblyLine.Type::Item);
if AssemblyLine.Find('-') then
repeat
PlanningComponent.InitFromRequisitionLine(RequisitionLine);
PlanningComponent.TransferFromAsmLine(AssemblyLine);
sender.InsertPlanningComponent(PlanningComponent);
until AssemblyLine.Next() = 0;
end;
else
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Plng. Component Invt. Profile", 'OnTransferInventoryProfileFromPlamComponentByRefOrderType', '', true, true)]
local procedure OnTransferInventoryProfileFromPlamComponentByRefOrderType(var InventoryProfile: Record "Inventory Profile"; PlanningComponent: Record "Planning Component")
var
AssemblyLine: Record "Assembly Line";
ReservationEntry: Record "Reservation Entry";
ReservedQty: Decimal;
begin
case PlanningComponent."Ref. Order Type" of
PlanningComponent."Ref. Order Type"::Assembly:
if AssemblyLine.Get(
PlanningComponent."Ref. Order Status",
PlanningComponent."Ref. Order No.",
PlanningComponent."Ref. Order Line No.")
then begin
InventoryProfile."Original Quantity" := AssemblyLine.Quantity;
AssemblyLine.CalcFields("Reserved Qty. (Base)");
if AssemblyLine."Reserved Qty. (Base)" > 0 then begin
ReservedQty := AssemblyLine."Reserved Qty. (Base)";
AssemblyLine.SetReservationFilters(ReservationEntry);
InventoryProfile.CalcReservedQty(ReservationEntry, ReservedQty);
if ReservedQty > InventoryProfile."Untracked Quantity" then
InventoryProfile."Untracked Quantity" := 0
else
InventoryProfile."Untracked Quantity" := InventoryProfile."Untracked Quantity" - ReservedQty;
end;
end else begin
InventoryProfile."Primary Order Type" := Database::"Planning Component";
InventoryProfile."Primary Order Status" := PlanningComponent."Ref. Order Status".AsInteger();
InventoryProfile."Primary Order No." := PlanningComponent."Ref. Order No.";
end;
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Plng. Component Invt. Profile", 'OnTransferToTrackingEntrySourceTypeElseCaseOnSetSource', '', true, true)]
local procedure OnTransferToTrackingEntrySourceTypeElseCaseOnSetSource(var InventoryProfile: Record "Inventory Profile"; var ReservationEntry: Record "Reservation Entry"; var RequisitionLine: Record "Requisition Line")
begin
case RequisitionLine."Ref. Order Type" of
RequisitionLine."Ref. Order Type"::Assembly:
ReservationEntry.SetSource(
Database::"Assembly Line", InventoryProfile."Source Order Status", InventoryProfile."Ref. Order No.",
InventoryProfile."Source Ref. No.", '', InventoryProfile."Ref. Line No.");
end;
end;
}