From 02d760dbc19890f81cf64a4bd3fbe1c7d61d5e10 Mon Sep 17 00:00:00 2001 From: Chethan Thopaiah Date: Mon, 25 May 2026 23:30:19 +0200 Subject: [PATCH 1/2] Bug 634953: Fix factbox drilldowns for finished production orders Subc. ProdO. Factbox Mgmt. (CU 99001559) hardcoded Status::Released in all procedures that query production order data. After finishing a production order, factbox fields showed zero counts and drilldowns failed with errors. Fix: Replace SetRange(Status, ::Released) with SetFilter(Status, '>=%1', ::Released) so queries match both Released and Finished orders. ShowProductionOrder now opens the correct page based on the resolved status (Released or Finished Production Order). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../SubcProdOFactboxMgmt.Codeunit.al | 34 +++++++++---- .../Tests/SubcSubcontractingTest.Codeunit.al | 51 +++++++++++++++++++ 2 files changed, 76 insertions(+), 9 deletions(-) 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 8d5c75124c..ad53b548cb 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 @@ -15,12 +15,13 @@ using System.Reflection; codeunit 99001559 "Subc. ProdO. Factbox Mgmt." { /// - /// Opens the Released Production Order page for the production order linked to the given variant record. + /// Opens the appropriate Production Order page (Released or Finished) for the production order linked to the given variant record. /// /// A record variant of a purchase or transfer document line. procedure ShowProductionOrder(RecRelatedVariant: Variant) var ProductionOrder: Record "Production Order"; + FinishedProductionOrder: Page "Finished Production Order"; ReleasedProductionOrder: Page "Released Production Order"; OperationNo: Code[10]; ProdOrderNo: Code[20]; @@ -29,11 +30,26 @@ codeunit 99001559 "Subc. ProdO. Factbox Mgmt." begin if not SetProdOrderInformationByVariant(RecRelatedVariant, ProdOrderNo, ProdOrderLineNo, RoutingNo, OperationNo) then exit; - ProductionOrder.SetRange(Status, ProductionOrder.Status::Released); + ProductionOrder.SetFilter(Status, '>=%1', ProductionOrder.Status::Released); ProductionOrder.SetRange("No.", ProdOrderNo); - ReleasedProductionOrder.SetTableView(ProductionOrder); - ReleasedProductionOrder.Editable := false; - ReleasedProductionOrder.Run(); + if not ProductionOrder.FindFirst() then + exit; + case ProductionOrder.Status of + ProductionOrder.Status::Released: + begin + ProductionOrder.SetRange(Status, ProductionOrder.Status::Released); + ReleasedProductionOrder.SetTableView(ProductionOrder); + ReleasedProductionOrder.Editable := false; + ReleasedProductionOrder.Run(); + end; + ProductionOrder.Status::Finished: + begin + ProductionOrder.SetRange(Status, ProductionOrder.Status::Finished); + FinishedProductionOrder.SetTableView(ProductionOrder); + FinishedProductionOrder.Editable := false; + FinishedProductionOrder.Run(); + end; + end; end; /// @@ -77,9 +93,9 @@ codeunit 99001559 "Subc. ProdO. Factbox Mgmt." exit(ProdOrderRoutingLine.Count()); end; -local procedure SetFilterProductionOrderRouting(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; ProdOrderNo: Code[20]; ProdOrderLineNo: Integer; RoutingNo: Code[20]; OperationNo: Code[10]) + local procedure SetFilterProductionOrderRouting(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; ProdOrderNo: Code[20]; ProdOrderLineNo: Integer; RoutingNo: Code[20]; OperationNo: Code[10]) begin - ProdOrderRoutingLine.SetRange(Status, ProdOrderRoutingLine.Status::Released); + ProdOrderRoutingLine.SetFilter(Status, '>=%1', ProdOrderRoutingLine.Status::Released); ProdOrderRoutingLine.SetRange("Prod. Order No.", ProdOrderNo); ProdOrderRoutingLine.SetRange("Routing Reference No.", ProdOrderLineNo); ProdOrderRoutingLine.SetRange("Routing No.", RoutingNo); @@ -130,7 +146,7 @@ local procedure SetFilterProductionOrderRouting(var ProdOrderRoutingLine: Record ProdOrderRoutingLine: Record "Prod. Order Routing Line"; begin ProdOrderRoutingLine.SetLoadFields("Routing Link Code"); - ProdOrderRoutingLine.SetRange(Status, ProdOrderRoutingLine.Status::Released); + ProdOrderRoutingLine.SetFilter(Status, '>=%1', ProdOrderRoutingLine.Status::Released); ProdOrderRoutingLine.SetRange("Prod. Order No.", ProdOrderNo); ProdOrderRoutingLine.SetRange("Routing Reference No.", ProdOrderLineNo); ProdOrderRoutingLine.SetRange("Routing No.", RoutingNo); @@ -138,7 +154,7 @@ local procedure SetFilterProductionOrderRouting(var ProdOrderRoutingLine: Record if ProdOrderRoutingLine.FindFirst() then ProdOrderComponent.SetRange("Routing Link Code", ProdOrderRoutingLine."Routing Link Code"); - ProdOrderComponent.SetRange(Status, ProdOrderComponent.Status::Released); + ProdOrderComponent.SetRange(Status, ProdOrderRoutingLine.Status); ProdOrderComponent.SetRange("Prod. Order No.", ProdOrderNo); ProdOrderComponent.SetRange("Prod. Order Line No.", ProdOrderLineNo); 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 e7b3ca3118..300fd06519 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 @@ -1800,6 +1800,57 @@ codeunit 139989 "Subc. Subcontracting Test" 'CalcNoOfProductionOrderComponents should return a positive count for an Item Ledger Entry from a subcontracting receipt.'); end; + [Test] + [HandlerFunctions('ConfirmArchiveOrderHandler,HandlePurchaseOrderPage')] + procedure ProdOFactboxMgmtShowsDataAfterProdOrderFinished() + var + Item: Record Item; + ProductionOrder: Record "Production Order"; + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + SubcWorkCenter: Record "Work Center"; + SubcProdOFactboxMgmt: Codeunit "Subc. ProdO. Factbox Mgmt."; + begin + // [SCENARIO 634953] Subcontracting factbox drilldowns should work after production order is finished. + Initialize(); + + // [GIVEN] A released production order with a subcontracting routing operation and a subcontracting purchase order + Subcontracting := true; + UnitCostCalculation := UnitCostCalculation::Units; + + CreateItemWithSingleSubcontractingOperation(Item, SubcWorkCenter); + SubcontractingMgmtLibrary.UpdateVendorWithSubcontractingLocationCode(SubcWorkCenter); + SubcontractingMgmtLibrary.CreateAndRefreshProductionOrder( + ProductionOrder, "Production Order Status"::Released, ProductionOrder."Source Type"::Item, Item."No.", LibraryRandom.RandInt(10) + 5); + UpdateSubMgmtSetupWithReqWkshTemplate(); + + SubcontractingMgmtLibrary.CreateSubcontractingOrderFromProdOrderRtngPage(Item."Routing No.", SubcWorkCenter."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.", SubcWorkCenter."No."); +#pragma warning restore AA0210 + PurchaseLine.FindFirst(); + PurchaseHeader.Get(PurchaseLine."Document Type", PurchaseLine."Document No."); + EnsureGeneralPostingSetupIsValid(PurchaseLine."Gen. Bus. Posting Group", PurchaseLine."Gen. Prod. Posting Group"); + LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false); + + // [GIVEN] The production order is changed to Finished status + LibraryManufacturing.ChangeProdOrderStatus(ProductionOrder, "Production Order Status"::Finished, WorkDate(), true); + + // Re-read purchase line (the order still exists because only receipt was posted) + PurchaseLine.FindFirst(); + + // [WHEN] CalcNoOfProductionOrderRoutings / CalcNoOfProductionOrderComponents are called with the Purchase Line + // [THEN] Both return a positive count even though the production order is now Finished + Assert.IsTrue( + SubcProdOFactboxMgmt.CalcNoOfProductionOrderRoutings(PurchaseLine) > 0, + 'CalcNoOfProductionOrderRoutings should return a positive count after the production order is finished.'); + Assert.IsTrue( + SubcProdOFactboxMgmt.CalcNoOfProductionOrderComponents(PurchaseLine) > 0, + 'CalcNoOfProductionOrderComponents should return a positive count after the production order is finished.'); + end; + [Test] [HandlerFunctions('ConfirmHandler')] procedure RoutingFactboxMgmtFiltersPurchOrderQtyByRoutingReferenceNo() From 68bf60c15af7c0785a11a3775f84e8984857c234 Mon Sep 17 00:00:00 2001 From: Chethan Thopaiah Date: Tue, 26 May 2026 20:43:08 +0200 Subject: [PATCH 2/2] Fix stale routing-line status after failed FindFirst Use SetFilter(Status, '>=%1', Released) on ProdOrderComponent instead of ProdOrderRoutingLine.Status which defaults to Simulated when FindFirst fails. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../App/src/Process/Codeunits/SubcProdOFactboxMgmt.Codeunit.al | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ad53b548cb..056de67a1c 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 @@ -154,7 +154,7 @@ codeunit 99001559 "Subc. ProdO. Factbox Mgmt." if ProdOrderRoutingLine.FindFirst() then ProdOrderComponent.SetRange("Routing Link Code", ProdOrderRoutingLine."Routing Link Code"); - ProdOrderComponent.SetRange(Status, ProdOrderRoutingLine.Status); + ProdOrderComponent.SetFilter(Status, '>=%1', ProdOrderComponent.Status::Released); ProdOrderComponent.SetRange("Prod. Order No.", ProdOrderNo); ProdOrderComponent.SetRange("Prod. Order Line No.", ProdOrderLineNo); end;