From 2664e07997376b164e34b0cddfd0d1481034c1a8 Mon Sep 17 00:00:00 2001 From: alexei-dobriansky <77933119+alexei-dobriansky@users.noreply.github.com> Date: Fri, 3 Jul 2026 16:30:13 +0200 Subject: [PATCH] Bug 640958: Guided error for subcontracting direct transfer from whse-handling location SubcCreateTransfOrder.InsertTransferHeader unconditionally validated "Direct Transfer" := true when no in-transit route existed; the OnValidate calls VerifyNoOutboundWhseHandlingOnLocation which TestFields Require Pick/Require Shipment = false, throwing a raw error for warehouse-handling source locations. Add CheckDirectTransferAllowed that raises a guided error explaining the situation (set up an in-transit route or use Direct Transfer posting) when the source location requires a pick or shipment and posting is not Direct Transfer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Transfer/SubcCreateTransfOrder.Report.al | 18 +++++++- .../Tests/SubcLocationHandlerTest.Codeunit.al | 41 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/Apps/W1/Subcontracting/App/src/Transfer/SubcCreateTransfOrder.Report.al b/src/Apps/W1/Subcontracting/App/src/Transfer/SubcCreateTransfOrder.Report.al index 820275713a..6e67d1f259 100644 --- a/src/Apps/W1/Subcontracting/App/src/Transfer/SubcCreateTransfOrder.Report.al +++ b/src/Apps/W1/Subcontracting/App/src/Transfer/SubcCreateTransfOrder.Report.al @@ -7,6 +7,7 @@ namespace Microsoft.Manufacturing.Subcontracting; using Microsoft.Foundation.UOM; using Microsoft.Inventory.Costing; using Microsoft.Inventory.Item; +using Microsoft.Inventory.Location; using Microsoft.Inventory.Transfer; using Microsoft.Manufacturing.Document; using Microsoft.Manufacturing.WorkCenter; @@ -83,6 +84,19 @@ report 99001501 "Subc. Create Transf. Order" OrderNoDoesNotExistInProdOrderErr: Label 'Operation %1 in the subcontracting order %2 does not exist in the routing %3 of the production order %4.', Comment = '%1=Operation No., %2=Purchase Order No., %3=Routing No., %4=Production Order No.'; OrderNoIsNotSubcontractorErr: Label 'Order %1 is not a Subcontractor work.', Comment = '%1=Purchase Order No.'; WarningToSpecifyPurchOrderErr: Label 'Warning. Specify a Purchase Order No. for the Subcontractor work.'; + DirectTransferNotAllowedErr: Label 'A direct transfer cannot be created from location %1 to location %2 because location %1 requires a pick or shipment. Set up an in-transit transfer route between the two locations, or set Direct Transfer Posting to Direct Transfer in Inventory Setup.', Comment = '%1=Transfer-from location code, %2=Transfer-to location code'; + + local procedure CheckDirectTransferAllowed(TransferHeaderToCheck: Record "Transfer Header"; TransferFromLocation: Code[10]; TransferToLocation: Code[10]) + var + Location: Record Location; + begin + if TransferHeaderToCheck."Direct Transfer Posting" = TransferHeaderToCheck."Direct Transfer Posting"::"Direct Transfer" then + exit; + if not Location.Get(TransferFromLocation) then + exit; + if Location."Require Pick" or Location."Require Shipment" then + Error(DirectTransferNotAllowedErr, TransferFromLocation, TransferToLocation); + end; local procedure InsertTransferHeader(TransferFromLocation: Code[10]) var @@ -106,8 +120,10 @@ report 99001501 "Subc. Create Transf. Order" TransferHeader.Insert(true); TransferHeader.Validate("Transfer-from Code", TransferFromLocation); TransferHeader.Validate("Transfer-to Code", TransferToLocationCode); - if not TransferRoute.Get(TransferFromLocation, TransferToLocationCode) or (TransferRoute."In-Transit Code" = '') then + if not TransferRoute.Get(TransferFromLocation, TransferToLocationCode) or (TransferRoute."In-Transit Code" = '') then begin + CheckDirectTransferAllowed(TransferHeader, TransferFromLocation, TransferToLocationCode); TransferHeader.Validate("Direct Transfer", true); + end; TransferHeader."Subc. Source Type" := TransferHeader."Subc. Source Type"::Subcontracting; TransferHeader."Source ID" := "Purchase Header"."Buy-from Vendor No."; diff --git a/src/Apps/W1/Subcontracting/Test/Tests/SubcLocationHandlerTest.Codeunit.al b/src/Apps/W1/Subcontracting/Test/Tests/SubcLocationHandlerTest.Codeunit.al index c1a90353f3..2ddb7594df 100644 --- a/src/Apps/W1/Subcontracting/Test/Tests/SubcLocationHandlerTest.Codeunit.al +++ b/src/Apps/W1/Subcontracting/Test/Tests/SubcLocationHandlerTest.Codeunit.al @@ -197,6 +197,47 @@ codeunit 139981 "Subc. Location Handler Test" Assert.AreEqual(LocationSub.Code, TransferHeader."Transfer-to Code", 'Transfer-to Code should be Subcontractor Location'); end; + [Test] + procedure DirectTransferFromRequireShipmentLocationIsBlocked() + var + Item: Record Item; + LocationOrig: Record Location; + LocationSub: Record Location; + ProdOrder: Record "Production Order"; + ProdOrderComp: Record "Prod. Order Component"; + ProdOrderLine: Record "Prod. Order Line"; + ProdOrderRtngLine: Record "Prod. Order Routing Line"; + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + Vendor: Record Vendor; + CreateSubCTransfOrder: Report "Subc. Create Transf. Order"; + begin + // [SCENARIO 640958] Creating a subcontracting transfer with no in-transit route from a location that + // requires a shipment is blocked with a guided error instead of a raw TestField error. + Initialize(); + + // [GIVEN] Subcontractor and Original locations; the Original location requires a shipment; no in-transit transfer route exists. + LibraryWarehouse.CreateLocation(LocationSub); + LibraryWarehouse.CreateLocation(LocationOrig); + LocationOrig."Require Shipment" := true; + LocationOrig.Modify(true); + + // [GIVEN] Subcontracting Scenario Setup (component at the subcontractor location, original at the require-shipment location) + CreateSubcontractingSetup( + PurchaseHeader, PurchaseLine, ProdOrder, ProdOrderLine, ProdOrderComp, ProdOrderRtngLine, Vendor, + LocationSub, Item, LibraryRandom.RandInt(10), LocationSub.Code, LocationOrig.Code); + + // [WHEN] Running the Create Subcontracting Transfer Order report + Commit(); // Report requires commit + PurchaseHeader.SetRecFilter(); + CreateSubCTransfOrder.SetTableView(PurchaseHeader); + CreateSubCTransfOrder.UseRequestPage(false); + + // [THEN] A guided error is raised instead of a raw TestField error on the location + asserterror CreateSubCTransfOrder.Run(); + Assert.ExpectedError('requires a pick or shipment'); + end; + [Test] [HandlerFunctions('HandleTransferOrder')] procedure TestTransferOrderCreation_PostAndRecreate()