From c4a45d009c5b9c89b835a12a6aee74b58ffb8c8d Mon Sep 17 00:00:00 2001 From: Chethan Thopaiah Date: Wed, 13 May 2026 16:32:29 +0200 Subject: [PATCH 1/3] [Subcontracting] Bug 634720: Production Routing factbox count must match drill-down operation filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aligned CalcNoOfProductionOrderRoutings in codeunit "Subc. ProdO. Factbox Mgmt." with ShowProductionOrderRouting by adding the missing "Routing No." and "Operation No." filters. Previously, the factbox count returned all routing operations of the production order line (e.g. 4), while the drill-down filtered to the single linked operation (always 1) — so the count and drill-down were inconsistent. Both Subc. Purchase Line Factbox and Subc. Transfer Line Factbox benefit from this single-point fix. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../SubcProdOFactboxMgmt.Codeunit.al | 2 + .../Tests/SubcSubcontractingTest.Codeunit.al | 48 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcProdOFactboxMgmt.Codeunit.al b/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcProdOFactboxMgmt.Codeunit.al index 3a23e750f4..e8f9440f25 100644 --- a/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcProdOFactboxMgmt.Codeunit.al +++ b/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcProdOFactboxMgmt.Codeunit.al @@ -80,6 +80,8 @@ codeunit 99001559 "Subc. ProdO. Factbox Mgmt." ProdOrderRoutingLine.SetRange(Status, ProdOrderRoutingLine.Status::Released); ProdOrderRoutingLine.SetRange("Prod. Order No.", ProdOrderNo); ProdOrderRoutingLine.SetRange("Routing Reference No.", ProdOrderLineNo); + ProdOrderRoutingLine.SetRange("Routing No.", RoutingNo); + ProdOrderRoutingLine.SetRange("Operation No.", OperationNo); exit(ProdOrderRoutingLine.Count()); end; diff --git a/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al b/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al index 996db4160b..3c7b077605 100644 --- a/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al +++ b/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al @@ -2028,6 +2028,54 @@ codeunit 139989 "Subc. Subcontracting Test" 'CalcNoOfProductionOrderComponents should return a positive count for an Item Ledger Entry from a subcontracting receipt.'); end; + [Test] + [HandlerFunctions('DoNotConfirmShowCreatedPurchOrderForSubcontracting')] + procedure CalcNoOfProductionOrderRoutingsReturnsOneForSubcontractingPurchaseLine() + var + Item: Record Item; + MachineCenter: array[2] of Record "Machine Center"; + ProdOrderRoutingLine: Record "Prod. Order Routing Line"; + ProductionOrder: Record "Production Order"; + PurchaseLine: Record "Purchase Line"; + WorkCenter: array[2] of Record "Work Center"; + SubcProdOFactboxMgmt: Codeunit "Subc. ProdO. Factbox Mgmt."; + begin + // [SCENARIO 634720] CalcNoOfProductionOrderRoutings must filter by Routing No. and Operation No. so the factbox count matches the drill-down (which is always a single routing line for a subcontracting purchase line). + + // [GIVEN] Manufacturing setup with a routing of multiple operations where only the second work center is subcontracting + Initialize(); + Subcontracting := true; + UnitCostCalculation := UnitCostCalculation::Units; + + CreateAndCalculateNeededWorkAndMachineCenter(WorkCenter, MachineCenter); + CreateItemForProductionIncludeRoutingAndProdBOM(Item, WorkCenter, MachineCenter); + + // [GIVEN] A Released Production Order whose routing has more than one operation + CreateAndRefreshProductionOrder( + ProductionOrder, "Production Order Status"::Released, ProductionOrder."Source Type"::Item, Item."No.", LibraryRandom.RandInt(10) + 5); + + ProdOrderRoutingLine.SetRange(Status, ProdOrderRoutingLine.Status::Released); + ProdOrderRoutingLine.SetRange("Prod. Order No.", ProductionOrder."No."); + Assert.IsTrue(ProdOrderRoutingLine.Count() > 1, 'Test precondition: routing must have more than one operation to detect the bug.'); + + UpdateSubMgmtSetupWithReqWkshTemplate(); + + // [GIVEN] A Subcontracting Purchase Order created from the routing line of the subcontracting work center + CreateSubcontractingOrderFromProdOrderRtngPage(Item."Routing No.", WorkCenter[2]."No."); + PurchaseLine.SetRange("Document Type", PurchaseLine."Document Type"::Order); + PurchaseLine.SetRange("Prod. Order No.", ProductionOrder."No."); +#pragma warning disable AA0210 + PurchaseLine.SetRange("Work Center No.", WorkCenter[2]."No."); +#pragma warning restore AA0210 + PurchaseLine.FindFirst(); + + // [WHEN] CalcNoOfProductionOrderRoutings is called with the purchase line + // [THEN] It returns 1, matching the single routing line shown by the drill-down (not the total operations of the prod order line) + Assert.AreEqual( + 1, SubcProdOFactboxMgmt.CalcNoOfProductionOrderRoutings(PurchaseLine), + 'CalcNoOfProductionOrderRoutings must equal the number of routing lines opened by the drill-down (exactly one for a subcontracting purchase line).'); + end; + [Test] [HandlerFunctions('DoNotConfirmShowCreatedPurchOrderForSubcontracting')] procedure Description2CopiedFromProdOrderComponentToPurchaseLine() From 96d4c36dc7d70ce8200c5b4a6f6c15fe6b75c68e Mon Sep 17 00:00:00 2001 From: Chethan Thopaiah Date: Wed, 13 May 2026 22:34:13 +0200 Subject: [PATCH 2/3] fix for merge --- .../Test/src/Codeunits/Tests/SubcPurchSubcontTest.Codeunit.al | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcPurchSubcontTest.Codeunit.al b/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcPurchSubcontTest.Codeunit.al index 271412ea4b..24884d92f5 100644 --- a/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcPurchSubcontTest.Codeunit.al +++ b/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcPurchSubcontTest.Codeunit.al @@ -472,7 +472,7 @@ codeunit 139991 "Subc. Purch. Subcont. Test" ProductionOrder."Source Type"::Item, FinishedItem."No.", Qty, HomeLocation.Code); // [GIVEN] Requisition worksheet template for subcontracting - LibraryMfgManagement.CreateLaborReqWkshTemplateAndNameAndUpdateSetup(); + LibraryMfgManagement.CreateSubcontractingReqWkshTemplateAndNameAndUpdateSetup(); // [WHEN] Create subcontracting purchase order from Prod. Order Routing ProdOrderRtngLine.SetRange("Routing No.", RoutingHeader."No."); From 67adc81f9e68cff7e2ed3da6d7ce857941df081d Mon Sep 17 00:00:00 2001 From: Chethan Thopaiah <41570277+ChethanT@users.noreply.github.com> Date: Fri, 15 May 2026 14:17:08 +0200 Subject: [PATCH 3/3] test fix --- .../src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al b/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al index be80775fdf..df4fb7a651 100644 --- a/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al +++ b/src/Apps/W1/Subcontracting/Test/src/Codeunits/Tests/SubcSubcontractingTest.Codeunit.al @@ -2268,7 +2268,7 @@ codeunit 139989 "Subc. Subcontracting Test" CreateItemForProductionIncludeRoutingAndProdBOM(Item, WorkCenter, MachineCenter); // [GIVEN] A Released Production Order whose routing has more than one operation - CreateAndRefreshProductionOrder( + SubcontractingMgmtLibrary.CreateAndRefreshProductionOrder( ProductionOrder, "Production Order Status"::Released, ProductionOrder."Source Type"::Item, Item."No.", LibraryRandom.RandInt(10) + 5); ProdOrderRoutingLine.SetRange(Status, ProdOrderRoutingLine.Status::Released); @@ -2278,7 +2278,7 @@ codeunit 139989 "Subc. Subcontracting Test" UpdateSubMgmtSetupWithReqWkshTemplate(); // [GIVEN] A Subcontracting Purchase Order created from the routing line of the subcontracting work center - CreateSubcontractingOrderFromProdOrderRtngPage(Item."Routing No.", WorkCenter[2]."No."); + SubcontractingMgmtLibrary.CreateSubcontractingOrderFromProdOrderRtngPage(Item."Routing No.", WorkCenter[2]."No."); PurchaseLine.SetRange("Document Type", PurchaseLine."Document Type"::Order); PurchaseLine.SetRange("Prod. Order No.", ProductionOrder."No."); #pragma warning disable AA0210