Skip to content
Merged
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 @@ -13,6 +13,7 @@ using Microsoft.Inventory.Item;
using Microsoft.Inventory.Item.Catalog;
using Microsoft.Inventory.Requisition;
using Microsoft.Inventory.Tracking;
using Microsoft.Manufacturing.Capacity;
using Microsoft.Manufacturing.Document;
using Microsoft.Manufacturing.Setup;
using Microsoft.Manufacturing.WorkCenter;
Expand Down Expand Up @@ -319,6 +320,19 @@ codeunit 99001557 "Subc. Purchase Order Creator"
PageManagement.PageRun(PurchaseLine);
end;

internal procedure CreateSubcontractingOrdersForRoutingLineSelection(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"): Integer
var
NoOfCreatedPurchOrder: Integer;
begin
ProdOrderRoutingLine.SetRange(Type, "Capacity Type"::"Work Center");
Comment thread
SPinkow marked this conversation as resolved.
ShowExistingPurchaseOrdersForRoutingLines(ProdOrderRoutingLine);
if ProdOrderRoutingLine.FindSet() then
repeat
NoOfCreatedPurchOrder += CreateSubcontractingPurchaseOrderFromRoutingLine(ProdOrderRoutingLine);
until ProdOrderRoutingLine.Next() = 0;
exit(NoOfCreatedPurchOrder);
end;

local procedure CheckProdOrderComponentLines(ProdOrderRoutingLine: Record "Prod. Order Routing Line"): Boolean
var
ProdOrderComponent: Record "Prod. Order Component";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,36 +117,9 @@ pageextension 99001503 "Subc. Prod. Order Rtng." extends "Prod. Order Routing"
trigger OnAction()
var
ProdOrderRoutingLine: Record "Prod. Order Routing Line";
PurchaseLine: Record "Purchase Line";
SubcPurchaseOrderCreator: Codeunit "Subc. Purchase Order Creator";
NoOfCreatedPurchOrder: Integer;
begin
CurrPage.SetSelectionFilter(ProdOrderRoutingLine);
SubcPurchaseOrderCreator.ShowExistingPurchaseOrdersForRoutingLines(ProdOrderRoutingLine);
ProdOrderRoutingLine.FindSet();
repeat
NoOfCreatedPurchOrder += SubcPurchaseOrderCreator.CreateSubcontractingPurchaseOrderFromRoutingLine(ProdOrderRoutingLine);
until ProdOrderRoutingLine.Next() = 0;

if NoOfCreatedPurchOrder = 0 then begin
PurchaseLine.SetCurrentKey("Document Type", Type, "Prod. Order No.");
PurchaseLine.SetRange("Document Type", PurchaseLine."Document Type"::Order);
PurchaseLine.SetRange(Type, PurchaseLine.Type::Item);
PurchaseLine.SetRange("Prod. Order No.", Rec."Prod. Order No.");
PurchaseLine.SetRange("Routing No.", Rec."Routing No.");
PurchaseLine.SetRange("Routing Reference No.", Rec."Routing Reference No.");
PurchaseLine.SetRange("Operation No.", Rec."Operation No.");
if PurchaseLine.IsEmpty() then
Message(NoPurchOrderCreatedMsg, ProdOrderRoutingLine."Prod. Order No.")
end else begin
if NoOfCreatedPurchOrder = 1 then begin
SubcPurchaseOrderCreator.ClearOperationNoForCreatedPurchaseOrder();
SubcPurchaseOrderCreator.SetOperationNoForCreatedPurchaseOrder(Rec."Operation No.");
SubcPurchaseOrderCreator.ClearRoutingReferenceNoForCreatedPurchaseOrder();
SubcPurchaseOrderCreator.SetRoutingReferenceNoForCreatedPurchaseOrder(Rec."Routing Reference No.");
end;
SubcPurchaseOrderCreator.ShowCreatedPurchaseOrder(Rec."Prod. Order No.", NoOfCreatedPurchOrder);
end;
CreateSubcontractingOrders(ProdOrderRoutingLine);
end;
}
action("WIP Adjustment")
Expand Down Expand Up @@ -224,4 +197,33 @@ pageextension 99001503 "Subc. Prod. Order Rtng." extends "Prod. Order Routing"
Rec.Calcfields(Subcontracting);
TransferWIPItemEnabled := Rec.Subcontracting;
end;

internal procedure CreateSubcontractingOrders(var ProdOrderRoutingLine: Record "Prod. Order Routing Line")
var
PurchaseLine: Record "Purchase Line";
SubcPurchaseOrderCreator: Codeunit "Subc. Purchase Order Creator";
NoOfCreatedPurchOrder: Integer;
begin
NoOfCreatedPurchOrder := SubcPurchaseOrderCreator.CreateSubcontractingOrdersForRoutingLineSelection(ProdOrderRoutingLine);

if NoOfCreatedPurchOrder = 0 then begin
PurchaseLine.SetCurrentKey("Document Type", Type, "Prod. Order No.");
PurchaseLine.SetRange("Document Type", PurchaseLine."Document Type"::Order);
PurchaseLine.SetRange(Type, PurchaseLine.Type::Item);
PurchaseLine.SetRange("Prod. Order No.", Rec."Prod. Order No.");
PurchaseLine.SetRange("Routing No.", Rec."Routing No.");
PurchaseLine.SetRange("Routing Reference No.", Rec."Routing Reference No.");
PurchaseLine.SetRange("Operation No.", Rec."Operation No.");
if PurchaseLine.IsEmpty() then
Message(NoPurchOrderCreatedMsg, ProdOrderRoutingLine."Prod. Order No.")
end else begin
if NoOfCreatedPurchOrder = 1 then begin
SubcPurchaseOrderCreator.ClearOperationNoForCreatedPurchaseOrder();
SubcPurchaseOrderCreator.SetOperationNoForCreatedPurchaseOrder(Rec."Operation No.");
SubcPurchaseOrderCreator.ClearRoutingReferenceNoForCreatedPurchaseOrder();
SubcPurchaseOrderCreator.SetRoutingReferenceNoForCreatedPurchaseOrder(Rec."Routing Reference No.");
end;
SubcPurchaseOrderCreator.ShowCreatedPurchaseOrder(Rec."Prod. Order No.", NoOfCreatedPurchOrder);
end;
end;
}
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ codeunit 139983 "Subc. Management Library"
LibraryManufacturing.CreateAndRefreshProductionOrder(ProductionOrder, ProdOrderStatus, ProdOrderSourceType, SourceNo, Quantity);
end;

procedure CreateAndRefreshProductionOrder(var ProductionOrder: Record "Production Order"; ProdOrderStatus: Enum "Production Order Status"; ProdOrderSourceType: Enum "Prod. Order Source Type"; SourceNo: Code[20]; Quantity: Decimal; LocationCode: Code[20])
procedure CreateAndRefreshProductionOrder(var ProductionOrder: Record "Production Order"; ProdOrderStatus: Enum "Production Order Status"; ProdOrderSourceType: Enum "Prod. Order Source Type"; SourceNo: Code[20]; Quantity: Decimal; LocationCode: Code[10])
var
LibraryManufacturing: Codeunit "Library - Manufacturing";
begin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,91 @@ codeunit 139991 "Subc. Purch. Subcont. Test"
Assert.ExpectedError('You cannot change this routing line because transfer orders exist');
end;

[Test]
procedure WorkCenterRoutingLinesExcludedFromMultiSelectionWhenMachineCenterPresent()
var
CapacityUnitOfMeasure: Record "Capacity Unit of Measure";
Item, Item2 : Record Item;
MachineCenter: Record "Machine Center";
ProductionOrder: Record "Production Order";
ProdOrderRoutingLine: Record "Prod. Order Routing Line";
PurchaseLine: Record "Purchase Line";
RoutingHeader: Record "Routing Header";
RoutingLine: Record "Routing Line";
WorkCenter: Record "Work Center";
SubcPurchaseOrderCreator: Codeunit "Subc. Purchase Order Creator";
MachineCenterNo: Code[20];
NoOfCreatedOrders: Integer;
begin
// [SCENARIO] When CreateSubcontractingOrdersForRoutingLineSelection is called with a mixed
// selection containing both Work Center and Machine Center routing lines, only the
// Work Center lines result in a subcontracting purchase order.
// This verifies that the Work Center type filter is applied correctly when simulating
// multi-record selection (CurrPage.SetSelectionFilter cannot be used in test framework).
Initialize();

// [GIVEN] A subcontracting Work Center with a vendor
CreateAndCalculateNeededWorkCenter(WorkCenter, true);

// [GIVEN] A Machine Center belonging to the subcontracting Work Center
LibraryMfgManagement.CreateMachineCenter(MachineCenterNo, WorkCenter."No.", "Flushing Method"::"Pick + Manual".AsInteger());
MachineCenter.Get(MachineCenterNo);
LibraryManufacturing.CalculateMachCenterCalendar(MachineCenter, CalcDate('<-CY-1Y>', WorkDate()), CalcDate('<CM>', WorkDate()));

// [GIVEN] A routing with a Work Center line (Op 010) and a Machine Center line (Op 020),
// both referencing the same subcontracting Work Center
LibraryManufacturing.CreateCapacityUnitOfMeasure(CapacityUnitOfMeasure, "Capacity Unit of Measure"::Minutes);
LibraryManufacturing.CreateRoutingHeader(RoutingHeader, RoutingHeader.Type::Serial);

LibraryManufacturing.CreateRoutingLineSetup(RoutingLine, RoutingHeader, WorkCenter."No.", '010', 1, 1);
RoutingLine.Validate("Run Time Unit of Meas. Code", CapacityUnitOfMeasure.Code);
RoutingLine.Validate("Setup Time Unit of Meas. Code", CapacityUnitOfMeasure.Code);
RoutingLine.Modify(true);

RoutingLine.Type := RoutingLine.Type::"Machine Center";
LibraryManufacturing.CreateRoutingLineSetup(RoutingLine, RoutingHeader, MachineCenter."No.", '020', 1, 1);
RoutingLine.Validate("Run Time Unit of Meas. Code", CapacityUnitOfMeasure.Code);
RoutingLine.Validate("Setup Time Unit of Meas. Code", CapacityUnitOfMeasure.Code);
RoutingLine.Modify(true);

RoutingHeader.Validate(Status, RoutingHeader.Status::Certified);
RoutingHeader.Modify(true);

LibraryInventory.CreateItem(Item2);
LibraryManufacturing.CreateProductionBOM(Item2, 2);

// [GIVEN] An item with the routing and a released production order
LibraryManufacturing.CreateItemManufacturing(
Item, "Costing Method"::FIFO, LibraryRandom.RandInt(10),
"Reordering Policy"::"Lot-for-Lot", "Flushing Method"::"Pick + Manual",
RoutingHeader."No.", Item2."Production BOM No.");

SubcontractingMgmtLibrary.CreateAndRefreshProductionOrder(
ProductionOrder, "Production Order Status"::Released,
ProductionOrder."Source Type"::Item, Item."No.", LibraryRandom.RandInt(10) + 1);

LibraryMfgManagement.CreateSubcontractingReqWkshTemplateAndNameAndUpdateSetup();

// [WHEN] All routing lines (Work Center Op 010 + Machine Center Op 020) are passed to
// CreateSubcontractingOrdersForRoutingLineSelection, simulating a multi-record selection
ProdOrderRoutingLine.SetRange(Status, "Production Order Status"::Released);
ProdOrderRoutingLine.SetRange("Prod. Order No.", ProductionOrder."No.");
NoOfCreatedOrders := SubcPurchaseOrderCreator.CreateSubcontractingOrdersForRoutingLineSelection(ProdOrderRoutingLine);

// [THEN] Exactly one purchase order is created (Work Center line is filtered out)
Assert.AreEqual(1, NoOfCreatedOrders, 'Exactly one subcontracting purchase order must be created.');

// [THEN] The purchase order is linked to the Work Center operation (Op 010)
PurchaseLine.SetRange("Document Type", PurchaseLine."Document Type"::Order);
PurchaseLine.SetRange("Prod. Order No.", ProductionOrder."No.");
PurchaseLine.SetRange("Operation No.", '010');
Assert.RecordCount(PurchaseLine, 1);

// [THEN] No purchase order is created for the Machine Center operation (Op 020)
PurchaseLine.SetRange("Operation No.", '020');
Assert.RecordIsEmpty(PurchaseLine);
end;

[ModalPageHandler]
procedure ItemTrackingLinesSimpleHandler(var ItemTrackingLines: TestPage "Item Tracking Lines")
begin
Expand Down
Loading