From 5077847aaf5097d231a69e0a3259e66c5263e77f Mon Sep 17 00:00:00 2001 From: v-nehanawal Date: Mon, 10 Aug 2026 11:16:21 +0530 Subject: [PATCH] Initial Commit --- .../Activity/WhseActivityRegister.Codeunit.al | 34 ++++++++++++ .../SCMWarehouseReceiving.Codeunit.al | 52 +++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/src/Layers/W1/BaseApp/Warehouse/Activity/WhseActivityRegister.Codeunit.al b/src/Layers/W1/BaseApp/Warehouse/Activity/WhseActivityRegister.Codeunit.al index acdca6dacea..4828ce03247 100644 --- a/src/Layers/W1/BaseApp/Warehouse/Activity/WhseActivityRegister.Codeunit.al +++ b/src/Layers/W1/BaseApp/Warehouse/Activity/WhseActivityRegister.Codeunit.al @@ -1816,6 +1816,8 @@ codeunit 7307 "Whse.-Activity-Register" if Location."Bin Mandatory" then CheckBinRelatedFields(GlobalWhseActivLine); + CheckItemTrackingRequiredForPutAway(GlobalWhseActivLine); + OnAfterCheckWhseActivLine(GlobalWhseActivLine); if ((GlobalWhseActivLine."Activity Type" = GlobalWhseActivLine."Activity Type"::Pick) or @@ -1857,6 +1859,33 @@ codeunit 7307 "Whse.-Activity-Register" Cust.CheckBlockedCustOnDocs(Cust, GlobalWhseActivHeader."Source Document", false, false); end; + local procedure CheckItemTrackingRequiredForPutAway(WhseActivLine: Record "Warehouse Activity Line") + var + ItemLedgerEntry: Record "Item Ledger Entry"; + IsHandled: Boolean; + begin + IsHandled := false; + OnBeforeCheckItemTrackingRequiredForPutAway(WhseActivLine, IsHandled); + if IsHandled then + exit; + + if WhseActivLine."Activity Type" <> WhseActivLine."Activity Type"::"Put-away" then + exit; + if WhseActivLine."Serial No." = '' then + exit; + + ItemLedgerEntry.SetCurrentKey("Item No.", "Variant Code", "Location Code", "Serial No."); + ItemLedgerEntry.SetRange("Item No.", WhseActivLine."Item No."); + ItemLedgerEntry.SetRange("Variant Code", WhseActivLine."Variant Code"); + ItemLedgerEntry.SetRange("Location Code", WhseActivLine."Location Code"); + ItemLedgerEntry.SetRange("Serial No.", WhseActivLine."Serial No."); + ItemLedgerEntry.SetRange(Open, true); + ItemLedgerEntry.SetLoadFields("Lot No."); + if ItemLedgerEntry.FindLast() then + if ItemLedgerEntry."Lot No." <> '' then + WhseActivLine.TestField("Lot No.", ItemLedgerEntry."Lot No."); + end; + local procedure CheckBinRelatedFields(WhseActivLine: Record "Warehouse Activity Line") var IsHandled: Boolean; @@ -2449,6 +2478,11 @@ codeunit 7307 "Whse.-Activity-Register" begin end; + [IntegrationEvent(false, false)] + local procedure OnBeforeCheckItemTrackingRequiredForPutAway(WarehouseActivityLine: Record "Warehouse Activity Line"; var IsHandled: Boolean) + begin + end; + [IntegrationEvent(false, false)] local procedure OnBeforePostedWhseRcptLineModify(var PostedWhseReceiptLine: Record "Posted Whse. Receipt Line"; WarehouseActivityLine: Record "Warehouse Activity Line") begin diff --git a/src/Layers/W1/Tests/SCM-Warehouse/SCMWarehouseReceiving.Codeunit.al b/src/Layers/W1/Tests/SCM-Warehouse/SCMWarehouseReceiving.Codeunit.al index e83bdf59b1c..b0a55a1a254 100644 --- a/src/Layers/W1/Tests/SCM-Warehouse/SCMWarehouseReceiving.Codeunit.al +++ b/src/Layers/W1/Tests/SCM-Warehouse/SCMWarehouseReceiving.Codeunit.al @@ -4359,6 +4359,58 @@ codeunit 137152 "SCM Warehouse - Receiving" Assert.RecordCount(WarehouseEntry, ExpectedLinesCount); end; + [Test] + [HandlerFunctions('ItemTrackingPageHandler,EnterQuantityToCreatePageHandler')] + [Scope('OnPrem')] + procedure RegisterPutAwayWithBlankLotForSerialAndLotItemIsBlocked() + var + Item: Record Item; + PurchaseHeader: Record "Purchase Header"; + WarehouseReceiptLine: Record "Warehouse Receipt Line"; + WarehouseActivityLine: Record "Warehouse Activity Line"; + LotNo: Variant; + Quantity: Decimal; + ItemTrackingMode: Option "Assign Lot No.","Assign Lot And Serial","Assign Serial No.","Select Entries","Assign Multiple Lot No"; + begin + // [FEATURE] [Item Tracking] [Put-away] + // [SCENARIO 642316] Registering a Put-away for a serial- and lot-tracked item must fail when the Lot No. is cleared on a line, + // because the item ledger entry being put away carries that Lot No. and the warehouse entry must match it, + // otherwise Item Ledger Entries and Warehouse Bin Content become permanently mismatched. + + // [GIVEN] Item with both serial and lot tracking. + Initialize(); + Quantity := LibraryRandom.RandInt(10); + CreateItemWithItemTrackingCode(Item, true, true, LibraryUtility.GetGlobalNoSeriesCode(), LibraryUtility.GetGlobalNoSeriesCode()); // Taking True for Serial and Lot. + + // [GIVEN] Warehouse receipt from a purchase order is posted with serial and lot assigned, creating a Put-away activity. + CreateWarehouseReceiptFromPurchaseOrder(PurchaseHeader, LocationWhite.Code, Item."No.", Quantity, Item."Base Unit of Measure"); + FindWarehouseReceiptLine( + WarehouseReceiptLine, WarehouseReceiptLine."Source Document"::"Purchase Order", PurchaseHeader."No.", LocationWhite.Code); + LibraryVariableStorage.Enqueue(ItemTrackingMode::"Assign Lot And Serial"); // Enqueue for ItemTrackingPageHandler. + WarehouseReceiptLine.OpenItemTrackingLines(); + PostWarehouseReceiptFromPurchaseOrder(PurchaseHeader."No.", LocationWhite.Code); + LibraryVariableStorage.Dequeue(LotNo); // Drain the Lot No. enqueued by ItemTrackingPageHandler. + + // [GIVEN] The required Lot No. is cleared on a Put-away line, simulating a user leaving it blank. + FindWarehouseActivityLine( + WarehouseActivityLine, WarehouseActivityLine."Source Document"::"Purchase Order", PurchaseHeader."No.", + WarehouseActivityLine."Activity Type"::"Put-away"); + WarehouseActivityLine.SetRange("Action Type", WarehouseActivityLine."Action Type"::Place); + WarehouseActivityLine.FindFirst(); + WarehouseActivityLine.Validate("Lot No.", ''); + WarehouseActivityLine.Modify(true); + + // [WHEN] Registering the Put-away activity. + asserterror RegisterWarehouseActivity( + WarehouseActivityLine, WarehouseActivityLine."Source Document"::"Purchase Order", PurchaseHeader."No.", + WarehouseActivityLine."Activity Type"::"Put-away"); + + // [THEN] Registration is blocked because the line's Lot No. must equal the posted item ledger entry's Lot No., + // preventing the ledger/bin content mismatch. + Assert.ExpectedTestFieldError(WarehouseActivityLine.FieldCaption("Lot No."), Format(LotNo)); + LibraryVariableStorage.AssertEmpty(); + end; + local procedure Initialize() var LibraryERMCountryData: Codeunit "Library - ERM Country Data";