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 @@ -52,18 +52,16 @@ codeunit 99001518 "Subc. Planning Line Mgmt Ext."
PlanningComponent."Component Supply Method" := ProductionBOMLine."Component Supply Method";
end;

[EventSubscriber(ObjectType::Codeunit, Codeunit::"Mfg. Planning Line Management", OnTransferBOMOnBeforeUpdatePlanningComp, '', false, false)]
local procedure IgnorePurchaseComponentsFromSubcontracting_OnTransferBOMOnBeforeUpdatePlanningComp(var ProductionBOMLine: Record "Production BOM Line"; var UpdateCondition: Boolean; var IsHandled: Boolean; var ReqQty: Decimal)
[EventSubscriber(ObjectType::Table, Database::"Planning Component", OnAfterFilterLinesWithItemToPlan, '', false, false)]
local procedure PlanningComponent_OnAfterFilterLinesWithItemToPlan(var PlanningComponent: Record "Planning Component"; var Item: Record Item)
begin
#if not CLEAN29
#pragma warning disable AL0432
if not SubcFeatureFlagHandler.IsSubcontractingEnabled() then
#pragma warning restore AL0432
exit;
#endif
// Vendor-Supplied components must still be transferred as planning components so they appear
// in the Planning Worksheet component list (required for consumption registration).
// Exclusion from planning demand is handled by ProdOrderComponent_OnAfterFilterLinesWithItemToPlan.
#endif
PlanningComponent.SetFilter("Component Supply Method", '<>%1', "Component Supply Method"::"Vendor-Supplied");
end;

[EventSubscriber(ObjectType::Table, Database::"Prod. Order Component", OnAfterFilterLinesWithItemToPlan, '', false, false)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2011,6 +2011,125 @@ codeunit 139989 "Subc. Subcontracting Test"
Assert.RecordIsEmpty(RequisitionLine);
end;

[Test]
[HandlerFunctions('MakeSupplyOrdersPageHandler')]
procedure VendorSuppliedPlanningComponentNotPlannedSeparately()
var
ComponentItem: Record Item;
Item: Record Item;
Location: Record Location;
MachineCenter: array[2] of Record "Machine Center";
ManufacturingUserTemplate: Record "Manufacturing User Template";
PlanningComponent: Record "Planning Component";
ProdOrderComponent: Record "Prod. Order Component";
ProductionBOMLine: Record "Production BOM Line";
ProductionOrder: Record "Production Order";
RequisitionLine: Record "Requisition Line";
RequisitionWkshName: Record "Requisition Wksh. Name";
WorkCenter: array[2] of Record "Work Center";
ReqWkshTemplateName: Code[10];
Direction: Option Forward,Backward;
begin
// [SCENARIO] Planning Components with Component Supply Method = Vendor-Supplied must not
// generate separate demand when CalcRegenPlan is run for the component item, because
// vendor-supplied components are purchased through the subcontracting purchase order.

// [GIVEN] Complete Setup of Manufacturing, include Work- and Machine Centers, Item
Initialize();
SubcontractingMgmtLibrary.SetupInventorySetup();

Subcontracting := true;
UnitCostCalculation := UnitCostCalculation::Units;

CreateAndCalculateNeededWorkAndMachineCenter(WorkCenter, MachineCenter);

// [GIVEN] Create Item for Production include Routing and Prod. BOM
CreateItemForProductionIncludeRoutingAndProdBOM(Item, WorkCenter, MachineCenter);

// [GIVEN] Assign Routing Link Code between subcontracting routing line and last BOM line
UpdateProdBomAndRoutingWithRoutingLink(Item, WorkCenter[2]."No.");

// [GIVEN] Set Component Supply Method = Vendor-Supplied on the linked BOM line
SubcontractingMgmtLibrary.UpdateProdBomWithComponentSupplyMethod(Item, "Component Supply Method"::"Vendor-Supplied");

// [GIVEN] Set up vendor with subcontracting location
SubcontractingMgmtLibrary.UpdateVendorWithSubcontractingLocationCode(WorkCenter[2]);

// [GIVEN] A Planning Worksheet line for the parent item is refreshed, creating Planning Components
LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location);
ReqWkshTemplateName := LibraryPlanning.SelectRequisitionTemplateName();
LibraryPlanning.CreateRequisitionWkshName(RequisitionWkshName, ReqWkshTemplateName);
LibraryPlanning.CreateRequisitionLine(RequisitionLine, ReqWkshTemplateName, RequisitionWkshName.Name);
RequisitionLine.Validate(Type, RequisitionLine.Type::Item);
RequisitionLine.Validate("No.", Item."No.");
RequisitionLine.Validate(Quantity, LibraryRandom.RandInt(10) + 5);
RequisitionLine.Validate("Location Code", Location.Code);
RequisitionLine.Validate("Ending Date", WorkDate());
RequisitionLine.Modify(true);
LibraryPlanning.RefreshPlanningLine(RequisitionLine, Direction::Backward, true, true);

// [GIVEN] The component item from the BOM with Vendor-Supplied supply method
ProductionBOMLine.SetRange("Production BOM No.", Item."Production BOM No.");
ProductionBOMLine.FindLast();
ComponentItem.Get(ProductionBOMLine."No.");

// [WHEN] Run Regenerative Plan for the component item
ComponentItem.SetRecFilter();
LibraryPlanning.CalcRegenPlanForPlanWksh(ComponentItem, CalcDate('<-1M>', WorkDate()), CalcDate('<+1M>', WorkDate()));

// [THEN] No requisition line is suggested for the Vendor-Supplied component
RequisitionLine.SetRange("No.", ComponentItem."No.");
Assert.RecordIsEmpty(RequisitionLine);

// [THEN] The Vendor-Supplied Planning Component still exists in the planning worksheet (the planning
// run must not remove it — it is needed for consumption registration in the production order)
PlanningComponent.SetRange("Item No.", ComponentItem."No.");
Assert.RecordIsNotEmpty(PlanningComponent);
PlanningComponent.FindFirst();
PlanningComponent.TestField("Component Supply Method", "Component Supply Method"::"Vendor-Supplied");

// [WHEN] Carry out the parent item's planning line to create a planned production order
if not ManufacturingUserTemplate.Get(CopyStr(UserId(), 1, 50)) then
LibraryPlanning.CreateManufUserTemplate(
ManufacturingUserTemplate, CopyStr(UserId(), 1, 50),
ManufacturingUserTemplate."Make Orders"::"All Lines",
ManufacturingUserTemplate."Create Purchase Order"::"Make Purch. Orders",
ManufacturingUserTemplate."Create Production Order"::"Firm Planned",
ManufacturingUserTemplate."Create Transfer Order"::"Make Trans. Orders");
RequisitionLine.Reset();
RequisitionLine.SetRange("Worksheet Template Name", ReqWkshTemplateName);
RequisitionLine.SetRange("Journal Batch Name", RequisitionWkshName.Name);
RequisitionLine.SetRange("No.", Item."No.");
RequisitionLine.FindFirst();
LibraryPlanning.MakeSupplyOrders(ManufacturingUserTemplate, RequisitionLine);

// [THEN] The created planned production order contains the Vendor-Supplied component
// (carrying out the planning line must not strip the component from the production order)
ProductionOrder.SetRange("Source No.", Item."No.");
ProductionOrder.SetRange(Status, "Production Order Status"::"Firm Planned");
ProductionOrder.FindFirst();
ProdOrderComponent.SetRange(Status, ProductionOrder.Status);
ProdOrderComponent.SetRange("Prod. Order No.", ProductionOrder."No.");
ProdOrderComponent.SetRange("Item No.", ComponentItem."No.");
Assert.RecordIsNotEmpty(ProdOrderComponent);
ProdOrderComponent.FindFirst();
ProdOrderComponent.TestField("Component Supply Method", "Component Supply Method"::"Vendor-Supplied");

// [WHEN] Changing the Prod. Order Component's supply method to Empty
// (Planning Components are gone after carry-out; use the Prod. Order Component)
ProdOrderComponent."Component Supply Method" := "Component Supply Method"::Empty;
ProdOrderComponent.Modify();

// [WHEN] Run Regenerative Plan again for the component item
LibraryPlanning.CalcRegenPlanForPlanWksh(ComponentItem, CalcDate('<-1M>', WorkDate()), CalcDate('<+1M>', WorkDate()));

// [THEN] Requisition line is now suggested for the component
RequisitionLine.SetRange("No.", ComponentItem."No.");
Assert.RecordIsNotEmpty(RequisitionLine);
RequisitionLine.FindFirst();
RequisitionLine.TestField("No.", ComponentItem."No.");
end;

[Test]
[HandlerFunctions('ConfirmHandler')]
procedure SubcontractingFieldsPopulatedOnIleAfterSubcontractingPurchaseReceipt()
Expand Down Expand Up @@ -3545,6 +3664,12 @@ codeunit 139989 "Subc. Subcontracting Test"
end;
end;

[ModalPageHandler]
Comment thread
SPinkow marked this conversation as resolved.
procedure MakeSupplyOrdersPageHandler(var MakeSupplyOrders: Page "Make Supply Orders"; var Response: Action)
begin
Response := ACTION::LookupOK;
end;

[ModalPageHandler]
procedure GetOrderLinesPurchaseLinesPageHandler(var PurchaseLines: TestPage "Purchase Lines")
begin
Expand Down
Loading