From da58d243942225230ac51ed2266668d924f8c3bc Mon Sep 17 00:00:00 2001 From: Chethan Thopaiah <41570277+ChethanT@users.noreply.github.com> Date: Fri, 15 May 2026 16:57:27 +0200 Subject: [PATCH] Fix: Transfer Order Reopen not persisting from factbox drill-down (Bug 634267) ShowTransferOrdersAndReturnOrder passed a MarkedOnly-filtered record to PageManagement.PageRun/PageRunList. When the Transfer Order page opened bound to this marked record, actions like Reopen that modify Rec directly wrote to the marked record set rather than the real database, so changes were silently lost when the page closed. The fix uses a separate TransferHeaderToOpen record variable: - Single record: Get() fetches the real DB record before PageRun. - Multiple records: SelectionFilterManagement builds a No. filter applied to a clean record before PageRunList. Added test FactboxDrilldownTransferOrderReopenPersists that releases a transfer order, opens it via ShowTransferOrdersAndReturnOrder, performs Reopen in the page handler, and asserts the status persists as Open. AB#634267 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../SubcPurchFactboxMgmt.Codeunit.al | 14 +++- .../Tests/SubcSubcontractingTest.Codeunit.al | 83 +++++++++++++++++++ 2 files changed, 94 insertions(+), 3 deletions(-) diff --git a/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcPurchFactboxMgmt.Codeunit.al b/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcPurchFactboxMgmt.Codeunit.al index c21c0e3454..d1f0fd8b8c 100644 --- a/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcPurchFactboxMgmt.Codeunit.al +++ b/src/Apps/W1/Subcontracting/App/src/Process/Codeunits/SubcPurchFactboxMgmt.Codeunit.al @@ -12,6 +12,7 @@ using Microsoft.Purchases.Document; using Microsoft.Purchases.History; using Microsoft.Utilities; using System.Reflection; +using System.Text; codeunit 99001560 "Subc. Purch. Factbox Mgmt." { @@ -229,9 +230,11 @@ codeunit 99001560 "Subc. Purch. Factbox Mgmt." ProductionOrder: Record "Production Order"; PurchaseLine: Record "Purchase Line"; TransferHeader: Record "Transfer Header"; + TransferHeaderToOpen: Record "Transfer Header"; TransferLine: Record "Transfer Line"; DataTypeManagement: Codeunit "Data Type Management"; PageManagement: Codeunit "Page Management"; + SelectionFilterMgt: Codeunit SelectionFilterManagement; RecRef: RecordRef; NoOfTransferHeaders: Integer; begin @@ -305,10 +308,15 @@ codeunit 99001560 "Subc. Purch. Factbox Mgmt." NoOfTransferHeaders = 0: Message(NoTransferExistsMsg); NoOfTransferHeaders = 1: - if TransferHeader.FindFirst() then - PageManagement.PageRun(TransferHeader); + if TransferHeader.FindFirst() then begin + TransferHeaderToOpen.Get(TransferHeader."No."); + PageManagement.PageRun(TransferHeaderToOpen); + end; NoOfTransferHeaders > 1: - PageManagement.PageRunList(TransferHeader); + begin + TransferHeaderToOpen.SetFilter("No.", SelectionFilterMgt.GetSelectionFilterForTransferHeader(TransferHeader)); + PageManagement.PageRunList(TransferHeaderToOpen); + end; end; end; 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 ebed58e81c..f4aad41b07 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 @@ -2073,6 +2073,82 @@ codeunit 139989 "Subc. Subcontracting Test" 'GetPurchOrderQtyFromRoutingLine must filter by Routing Reference No., not by Prod. Order Line No.'); end; + [Test] + [HandlerFunctions('DoNotConfirmShowCreatedPurchOrderForSubcontracting,HandleTransferOrderReopen')] + procedure FactboxDrilldownTransferOrderReopenPersists() + var + Item: Record Item; + MachineCenter: array[2] of Record "Machine Center"; + ProdOrderRoutingLine: Record "Prod. Order Routing Line"; + ProductionOrder: Record "Production Order"; + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + TransferHeader: Record "Transfer Header"; + WorkCenter: array[2] of Record "Work Center"; + ProductionLocation: Record Location; + SubcPurchFactboxMgmt: Codeunit "Subc. Purch. Factbox Mgmt."; + ReleaseTransferDocument: Codeunit "Release Transfer Document"; + PurchaseHeaderPage: TestPage "Purchase Order"; + ReleasedProdOrderRtng: TestPage "Prod. Order Routing"; + begin + // [SCENARIO] Bug 634267 - Reopen Transfer Order does not persist when opened from Subcontracting Details Factbox. + // ShowTransferOrdersAndReturnOrder must open the page on a real database record, so actions like + // Reopen that modify Rec directly persist after the page closes. + + // [GIVEN] Subcontracting setup with transfer components and a released transfer order + Initialize(); + SubcontractingMgmtLibrary.UpdateManufacturingSetupWithSubcontractingLocation(); + SubcontractingMgmtLibrary.SetupInventorySetup(); + Subcontracting := true; + UnitCostCalculation := UnitCostCalculation::Units; + + CreateAndCalculateNeededWorkAndMachineCenter(WorkCenter, MachineCenter); + CreateItemForProductionIncludeRoutingAndProdBOM(Item, WorkCenter, MachineCenter); + UpdateProdBomAndRoutingWithRoutingLink(Item, WorkCenter[2]."No."); + SubcontractingMgmtLibrary.UpdateProdBomWithSubcontractingType(Item, "Subcontracting Type"::Transfer); + UpdateVendorWithSubcontractingLocationCode(WorkCenter[2]); + + LibraryWarehouse.CreateLocationWithInventoryPostingSetup(ProductionLocation); + SubcontractingMgmtLibrary.CreateAndRefreshProductionOrder( + ProductionOrder, "Production Order Status"::Released, ProductionOrder."Source Type"::Item, Item."No.", LibraryRandom.RandInt(10) + 5); + UpdateSubMgmtSetupWithReqWkshTemplate(); + SetAllProdOrderTransferComponentLocations(ProductionOrder."No.", ProductionLocation.Code); + SubcontractingMgmtLibrary.CreateTransferRoute(WorkCenter[2], ProductionOrder); + + ProdOrderRoutingLine.SetRange("Prod. Order No.", ProductionOrder."No."); + ProdOrderRoutingLine.SetRange("Work Center No.", WorkCenter[2]."No."); + ProdOrderRoutingLine.FindFirst(); + ReleasedProdOrderRtng.OpenView(); + ReleasedProdOrderRtng.GoToRecord(ProdOrderRoutingLine); + ReleasedProdOrderRtng.CreateSubcontracting.Invoke(); + ReleasedProdOrderRtng.Close(); + + PurchaseLine.SetRange("Document Type", PurchaseLine."Document Type"::Order); + PurchaseLine.SetRange("Prod. Order No.", ProductionOrder."No."); + PurchaseLine.FindFirst(); + PurchaseHeader.Get(PurchaseLine."Document Type", PurchaseLine."Document No."); + + PurchaseHeaderPage.OpenView(); + PurchaseHeaderPage.GoToRecord(PurchaseHeader); + PurchaseHeaderPage.CreateTransfOrdToSubcontractor.Invoke(); + PurchaseHeaderPage.Close(); + + TransferHeader.SetRange("Subcontr. Purch. Order No.", PurchaseHeader."No."); + TransferHeader.FindFirst(); + ReleaseTransferDocument.Release(TransferHeader); + Assert.AreEqual(TransferHeader.Status::Released, TransferHeader.Status, 'Transfer order should be Released before the test.'); + + // [WHEN] Opening the transfer order from the factbox drill-down and performing Reopen + // The page handler HandleTransferOrderReopen will reopen the transfer order + PurchaseLine.FindFirst(); + SubcPurchFactboxMgmt.ShowTransferOrdersAndReturnOrder(PurchaseLine, true, false); + + // [THEN] The transfer order status must be Open after closing the page + TransferHeader.Get(TransferHeader."No."); + Assert.AreEqual(TransferHeader.Status::Open, TransferHeader.Status, + 'Transfer order status should be Open after Reopen from factbox drill-down. Before the fix, the Reopen modified a marked record and the change was lost.'); + end; + [Test] [HandlerFunctions('DoNotConfirmShowCreatedPurchOrderForSubcontracting')] procedure Description2CopiedFromProdOrderComponentToPurchaseLine() @@ -2579,6 +2655,13 @@ codeunit 139989 "Subc. Subcontracting Test" TransfOrderPage.OK().Invoke(); end; + [PageHandler] + procedure HandleTransferOrderReopen(var TransfOrderPage: TestPage "Transfer Order") + begin + TransfOrderPage."Reo&pen".Invoke(); + TransfOrderPage.OK().Invoke(); + end; + [ConfirmHandler] procedure ConfirmYesShowSubcontractingPurchOrders(Question: Text[1024]; var Reply: Boolean) begin