Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ codeunit 99001520 "Subc. Prod. Order Rtng. Ext."
SubcPriceManagement.GetSubcPriceList(ProdOrderRoutingLine);
end;

[EventSubscriber(ObjectType::Codeunit, Codeunit::"Prod. Order Route Management", OnCalculateOnBeforeProdOrderRtngLineLoopIteration, '', false, false)]
local procedure CheckSubcontractingOnCalculateOnBeforeProdOrderRtngLineLoopIteration(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; var ProdOrderLine: Record "Prod. Order Line"; var IsHandled: Boolean)
begin
ProdOrderRoutingLine.CheckForSubcontractingPurchaseLineTypeMismatch();
end;

local procedure HandleRoutingLinkCodeValidation(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; var xProdOrderRoutingLine: Record "Prod. Order Routing Line")
var
ProdOrderRoutingLine2: Record "Prod. Order Routing Line";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ using Microsoft.Foundation.UOM;
using Microsoft.Inventory.Item;
using Microsoft.Inventory.Journal;
using Microsoft.Inventory.Ledger;
using Microsoft.Inventory.Posting;
using Microsoft.Inventory.Tracking;
using Microsoft.Manufacturing.Capacity;
using Microsoft.Purchases.Document;
using Microsoft.Purchases.History;
Expand Down Expand Up @@ -36,11 +38,14 @@ codeunit 99001535 "Subc. Purch. Post Ext"
begin
if not SubcManagementSetup.ItemChargeToRcptSubReferenceEnabled() then
exit;
if ItemJournalLine."Item Charge No." = '' then
exit;
if not PurchRcptLine.Get(TempItemChargeAssignmentPurch."Applies-to Doc. No.", TempItemChargeAssignmentPurch."Applies-to Doc. Line No.") then
exit;
if not PurchRcptLineHasProdOrder(PurchRcptLine) then
exit;

if ItemJournalLine."Item Charge No." <> '' then
if PurchRcptLine.Get(TempItemChargeAssignmentPurch."Applies-to Doc. No.", TempItemChargeAssignmentPurch."Applies-to Doc. Line No.") then
if PurchRcptLineHasProdOrder(PurchRcptLine) then
CopySubcontractingProdOrderFieldsToItemJnlLine(ItemJournalLine, PurchRcptLine);
CopySubcontractingProdOrderFieldsToItemJnlLine(ItemJournalLine, PurchRcptLine);
end;

local procedure SetQuantityBaseOnSubcontractingServiceLine(PurchaseLine: Record "Purchase Line"; var PurchRcptLine: Record "Purch. Rcpt. Line")
Expand Down Expand Up @@ -85,4 +90,29 @@ codeunit 99001535 "Subc. Purch. Post Ext"
ItemJournalLine."Inventory Posting Group" := Item."Inventory Posting Group";
ItemJournalLine."Item Charge Sub. Assign." := true;
end;

[EventSubscriber(ObjectType::Codeunit, Codeunit::"Purch.-Post", OnPostItemJnlLineOnAfterPostItemJnlLineJobConsumption, '', false, false)]
local procedure ProcessLastOperationWarehouseTracking_OnPostItemJnlLineOnAfterPostItemJnlLineJobConsumption(var ItemJournalLine: Record "Item Journal Line"; PurchaseHeader: Record "Purchase Header"; PurchaseLine: Record "Purchase Line"; OriginalItemJnlLine: Record "Item Journal Line"; var TempReservationEntry: Record "Reservation Entry" temporary; var TrackingSpecification: Record "Tracking Specification" temporary; QtyToBeInvoiced: Decimal; QtyToBeReceived: Decimal; var PostJobConsumptionBeforePurch: Boolean; var ItemJnlPostLine: Codeunit "Item Jnl.-Post Line"; var TempWhseTrackingSpecification: Record "Tracking Specification" temporary)
begin
if PurchaseLine."Subc. Purchase Line Type" = "Subc. Purchase Line Type"::LastOperation then
CreateTempWhseSplitSpecificationForLastOperationSubcontracting(PurchaseLine, ItemJnlPostLine, TrackingSpecification, TempWhseTrackingSpecification);
end;

local procedure CreateTempWhseSplitSpecificationForLastOperationSubcontracting(PurchLine: Record "Purchase Line"; var ItemJnlPostLine: Codeunit "Item Jnl.-Post Line"; var TempHandlingSpecification: Record "Tracking Specification" temporary; var TempWhseSplitSpecification: Record "Tracking Specification" temporary)
begin
if ItemJnlPostLine.CollectTrackingSpecification(TempHandlingSpecification) then begin
TempWhseSplitSpecification.Reset();
TempWhseSplitSpecification.DeleteAll();
if TempHandlingSpecification.FindSet() then
repeat
TempWhseSplitSpecification := TempHandlingSpecification;
TempWhseSplitSpecification."Source Type" := DATABASE::"Purchase Line";
TempWhseSplitSpecification."Source Subtype" := PurchLine."Document Type".AsInteger();
TempWhseSplitSpecification."Source ID" := PurchLine."Document No.";
TempWhseSplitSpecification."Source Ref. No." := PurchLine."Line No.";
TempWhseSplitSpecification.Insert();
until TempHandlingSpecification.Next() = 0;
end;
end;

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,22 @@
// ------------------------------------------------------------------------------------------------
namespace Microsoft.Manufacturing.Subcontracting;

using Microsoft.Inventory.Item;
using Microsoft.Inventory.Tracking;
using Microsoft.Manufacturing.Document;
using Microsoft.Purchases.Document;
using Microsoft.Utilities;
using Microsoft.Warehouse.Document;

codeunit 99001534 "Subc. Purchase Line Ext"
{
var
SubcSynchronizeManagement: Codeunit "Subc. Synchronize Management";
QtyMismatchTitleLbl: Label 'Quantity Mismatch';
QtyMismatchErr: Label 'The quantity (%1) in %2 is greater than the specified quantity (%3) in %4. In order to open item tracking lines, first adjust the quantity on %2 to at least match the quantity on %4. You can adjust the quantity from %5 to %6 by using the action below.',
Comment = '%1 = PurchaseLine Outstanding Qty, %2 = Tablecaption PurchaseLine, %3 = ProdOrderLine Remaining Qty, %4 = Tablecaption ProdOrderLine, %5 = Current ProdOrderLine Qty, %6 = New PurchaseLine Qty';
NotLastOperationLineErr: Label 'Item tracking lines can only be viewed for subcontracting purchase lines which are linked to a routing line which is the last operation.';
CannotOpenProductionOrderErr: Label 'Cannot open Production Order %1.', Comment = '%1=Production Order No.';

[EventSubscriber(ObjectType::Table, Database::"Purchase Line", OnAfterDeleteEvent, '', false, false)]
local procedure OnAfterDeleteEvent(var Rec: Record "Purchase Line"; RunTrigger: Boolean)
Expand Down Expand Up @@ -81,4 +91,127 @@ codeunit 99001534 "Subc. Purchase Line Ext"
if (PurchaseLine.Type = PurchaseLine.Type::Item) and (PurchaseLine."No." <> '') and (PurchaseLine."Prod. Order No." <> '') and (PurchaseLine."Operation No." <> '') then
SubcPriceManagement.GetSubcPriceForPurchLine(PurchaseLine);
end;

[EventSubscriber(ObjectType::Table, Database::"Purchase Line", OnBeforeOpenItemTrackingLines, '', false, false)]
local procedure OpenProdOrderLineItemTrackingOnBeforeOpenItemTrackingLines(PurchaseLine: Record "Purchase Line"; var IsHandled: Boolean)
begin
OpenItemTrackingOfProdOrderLine(PurchaseLine, false);
IsHandled := true;
end;

local procedure CheckItem(PurchaseLine: Record "Purchase Line")
var
Item: Record Item;
ItemTrackingCode: Record "Item Tracking Code";
begin
PurchaseLine.TestField(Type, "Purchase Line Type"::Item);
PurchaseLine.TestField("No.");
Item.SetLoadFields("Item Tracking Code");
Item.Get(PurchaseLine."No.");
Item.TestField("Item Tracking Code");
ItemTrackingCode.Get(Item."Item Tracking Code");
end;

local procedure CheckOverDeliveryQty(PurchaseLine: Record "Purchase Line"; ProdOrderLine: Record "Prod. Order Line")
var
ShowProductionOrderActionLbl: Label 'Show Prod. Order';
AdjustQtyActionLbl: Label 'Adjust Quantity';
OpenItemTrackingAnywayActionLbl: Label 'Open anyway';
CannotInvoiceErrorInfo: ErrorInfo;
begin
if PurchaseLine.Quantity > ProdOrderLine.Quantity then begin
CannotInvoiceErrorInfo.Title := QtyMismatchTitleLbl;
CannotInvoiceErrorInfo.Message := StrSubstNo(QtyMismatchErr, PurchaseLine."Outstanding Quantity", PurchaseLine.TableCaption(), ProdOrderLine."Remaining Quantity", ProdOrderLine.TableCaption(), ProdOrderLine.Quantity, PurchaseLine.Quantity);

CannotInvoiceErrorInfo.RecordId := PurchaseLine.RecordId;
CannotInvoiceErrorInfo.AddAction(
AdjustQtyActionLbl,
Codeunit::"Subc. Purchase Line Ext",
'AdjustProdOrderLineQuantity'
);
CannotInvoiceErrorInfo.AddAction(
ShowProductionOrderActionLbl,
Codeunit::"Subc. Purchase Line Ext",
'ShowProductionOrder'
);
CannotInvoiceErrorInfo.AddAction(
OpenItemTrackingAnywayActionLbl,
Codeunit::"Subc. Purchase Line Ext",
'OpenItemTrackingWithoutAdjustment'
);
Error(CannotInvoiceErrorInfo);
end;
end;

local procedure OpenItemTrackingOfProdOrderLine(var PurchaseLine: Record "Purchase Line"; SkipOverDeliveryCheck: Boolean)
var
ProdOrderLine: Record "Prod. Order Line";
TrackingSpecification: Record "Tracking Specification";
ProdOrderLineReserve: Codeunit "Prod. Order Line-Reserve";
ItemTrackingLines: Page "Item Tracking Lines";
SecondSourceQtyArray: array[3] of Decimal;
begin
if PurchaseLine."Subc. Purchase Line Type" = "Subc. Purchase Line Type"::None then
exit;
CheckItem(PurchaseLine);
if PurchaseLine."Subc. Purchase Line Type" = "Subc. Purchase Line Type"::NotLastOperation then
Error(NotLastOperationLineErr);
if PurchaseLine."Subc. Purchase Line Type" <> "Subc. Purchase Line Type"::LastOperation then
exit;
if not PurchaseLine.IsSubcontractingLineWithLastOperation(ProdOrderLine) then
exit;

SecondSourceQtyArray[1] := Database::"Warehouse Receipt Line";
SecondSourceQtyArray[2] := PurchaseLine.CalcBaseQtyFromQuantity(PurchaseLine."Qty. to Receive", PurchaseLine.FieldCaption("Qty. Rounding Precision"), PurchaseLine.FieldCaption("Qty. to Receive"), PurchaseLine.FieldCaption("Qty. to Receive (Base)"));
SecondSourceQtyArray[3] := 0;

if not SkipOverDeliveryCheck then
CheckOverDeliveryQty(PurchaseLine, ProdOrderLine);

ProdOrderLineReserve.InitFromProdOrderLine(TrackingSpecification, ProdOrderLine);
ItemTrackingLines.SetSourceSpec(TrackingSpecification, ProdOrderLine."Due Date");
ItemTrackingLines.SetSecondSourceQuantity(SecondSourceQtyArray);
ItemTrackingLines.RunModal();
end;

internal procedure ShowProductionOrder(OverDeliveryErrorInfo: ErrorInfo)
var
ProductionOrder: Record "Production Order";
PurchaseLine: Record "Purchase Line";
PageManagement: Codeunit "Page Management";
begin
PurchaseLine.SetLoadFields("Prod. Order No.");
PurchaseLine.Get(OverDeliveryErrorInfo.RecordId);
ProductionOrder.Get("Production Order Status"::Released, PurchaseLine."Prod. Order No.");
if not PageManagement.PageRun(ProductionOrder) then
Error(CannotOpenProductionOrderErr, ProductionOrder."No.");
end;

internal procedure AdjustProdOrderLineQuantity(OverDeliveryErrorInfo: ErrorInfo)
var
PurchaseLine: Record "Purchase Line";
ProdOrderLine: Record "Prod. Order Line";
begin
PurchaseLine.SetLoadFields(Type, "No.", "Prod. Order No.", "Prod. Order Line No.", "Routing Reference No.", "Routing No.", "Operation No.", Quantity, "Qty. to Receive", "Qty. to Receive (Base)", "Qty. Rounding Precision", "Outstanding Quantity");
PurchaseLine.Get(OverDeliveryErrorInfo.RecordId);
ProdOrderLine.Get("Production Order Status"::Released, PurchaseLine."Prod. Order No.", PurchaseLine."Prod. Order Line No.");
if PurchaseLine.Quantity > ProdOrderLine.Quantity then begin
ProdOrderLine.Validate(Quantity, PurchaseLine.Quantity);
ProdOrderLine.Modify();
Commit();
end;
OpenItemTrackingOfProdOrderLine(PurchaseLine, true);
end;

internal procedure OpenItemTrackingWithoutAdjustment(OverDeliveryErrorInfo: ErrorInfo)
var
PurchaseLine: Record "Purchase Line";
ProdOrderLine: Record "Prod. Order Line";
begin
PurchaseLine.SetLoadFields(Type, "No.", "Prod. Order No.", "Prod. Order Line No.", "Routing Reference No.", "Routing No.", "Operation No.", "Qty. to Receive", "Qty. to Receive (Base)", "Qty. Rounding Precision", "Outstanding Quantity");
PurchaseLine.Get(OverDeliveryErrorInfo.RecordId);
ProdOrderLine.SetLoadFields(SystemId);
ProdOrderLine.Get("Production Order Status"::Released, PurchaseLine."Prod. Order No.", PurchaseLine."Prod. Order Line No.");
OpenItemTrackingOfProdOrderLine(PurchaseLine, true);
end;
}
Loading
Loading