Report 7391 Whse. Get Bin Content, source in 29

Source29

src/Layers/W1/BaseApp/Warehouse/Structure/WhseGetBinContent.Report.al676 lines, Copyright (c) Microsoft Corporation. MIT

// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.Warehouse.Structure;

using Microsoft.Foundation.Enums;
using Microsoft.Foundation.UOM;
using Microsoft.Inventory.Journal;
using Microsoft.Inventory.Ledger;
using Microsoft.Inventory.Location;
using Microsoft.Inventory.Tracking;
using Microsoft.Inventory.Transfer;
using Microsoft.Warehouse.InternalDocument;
using Microsoft.Warehouse.Ledger;
using Microsoft.Warehouse.Worksheet;

report 7391 "Whse. Get Bin Content"
{
    Caption = 'Whse. Get Bin Content';
    ProcessingOnly = true;

    dataset
    {
        dataitem("Bin Content"; "Bin Content")
        {
            RequestFilterFields = "Location Code", "Zone Code", "Bin Code", "Item No.", "Variant Code", "Unit of Measure Code";

            trigger OnAfterGetRecord()
            var
                DummyItemTrackingSetup: Record "Item Tracking Setup";
                ShouldSkipReportForQty: Boolean;
            begin
                if GuiAllowed() then
                    ProgressWindow.Update(1, CreateBinContentProgressWindowText("Bin Content"));

                if BinType.Code <> "Bin Type Code" then
                    BinType.Get("Bin Type Code");
                if BinType.Receive and not "Cross-Dock Bin" then
                    CurrReport.Skip();

                QtyToEmptyBase := GetQtyToEmptyBase(DummyItemTrackingSetup);
                ShouldSkipReportForQty := QtyToEmptyBase <= 0;
                OnBinContenOnAfterGetRecordOnAfterCalcShouldSkipReportForQty("Bin Content", ShouldSkipReportForQty, DestinationType2, WhseWorksheetLine, WhseInternalPutawayLine, ItemJournalLine, TransferLine, InternalMovementLine, PostingDate, DocNo);
                if ShouldSkipReportForQty then
                    CurrReport.Skip();

                case DestinationType2 of
                    DestinationType2::MovementWorksheet:
                        InsertWhseWorksheetLine("Bin Content");
                    DestinationType2::WhseInternalPutawayHeader:
                        InsertWhseInternalPutawayLine("Bin Content");
                    DestinationType2::ItemJournalLine:
                        InsertItemJournalLine("Bin Content");
                    DestinationType2::TransferHeader:
                        begin
                            TransferHeader.TestField("Transfer-from Code", "Location Code");
                            InsertTransferLine("Bin Content");
                        end;
                    DestinationType2::InternalMovementHeader:
                        InsertIntMovementLine("Bin Content");
                    else
                        OnBinContentOnAfterGetRecordOnDestinationTypeElseCase(QtyToEmptyBase, "Bin Content", DestinationType2);
                end;

                GetItemTracking("Bin Content");
            end;

            trigger OnPostDataItem()
            begin
                if GuiAllowed() then
                    ProgressWindow.Close();
                OnAfterBinContentOnPostDataItem(ItemJournalLine, TransferHeader, InternalMovementHeader, DestinationType2.AsInteger());
            end;

            trigger OnPreDataItem()
            begin
                if not ReportInitialized then
                    Error(Text001);

                Location.Init();

                if GuiAllowed() then
                    ProgressWindow.Open(ProgressWindowLbl);
            end;
        }
    }

    requestpage
    {

        layout
        {
            area(content)
            {
                group(Options)
                {
                    Caption = 'Options';
                    field(PostingDate; PostingDate)
                    {
                        ApplicationArea = Warehouse;
                        Caption = 'Posting Date';
                        Editable = PostingDateEditable;
                        ToolTip = 'Specifies the posting date that will appear on the journal lines generated by the report.';
                    }
                    field(DocNo; DocNo)
                    {
                        ApplicationArea = Warehouse;
                        Caption = 'Document No.';
                        Editable = DocNoEditable;
                        ToolTip = 'Specifies the document number that will appear on the journal lines generated by the report.';
                    }
                }
            }
        }

        trigger OnInit()
        begin
            DocNoEditable := true;
            PostingDateEditable := true;
        end;

        trigger OnOpenPage()
        begin
            case DestinationType2 of
                DestinationType2::ItemJournalLine:
                    begin
                        PostingDateEditable := true;
                        DocNoEditable := true;
                    end;
                else begin
                    PostingDateEditable := false;
                    DocNoEditable := false;
                end;
            end;
        end;
    }

    var
        TransferHeader: Record "Transfer Header";
        BinType: Record "Bin Type";
        Location: Record Location;
        InternalMovementHeader: Record "Internal Movement Header";
        ItemJournalBatch: Record "Item Journal Batch";
        ItemJournalTemplate: Record "Item Journal Template";
        UOMMgt: Codeunit "Unit of Measure Management";
        ProgressWindow: Dialog;
#pragma warning disable AA0074
        Text001: Label 'Report must be initialized.';
#pragma warning restore AA0074
        DirectedWhseLocationErr: Label 'You cannot use %1 %2 because it is set up with %3.\Adjustments to this location must therefore be made in a Warehouse Item Journal.', Comment = '%1: Location Table Caption, %2: Location Code, %3: Location Field Caption';
        ProgressWindowLbl: Label 'Processing...\\#1##################################\\#2##################################\', Comment = '%1 = Item/Bin information, %2 = Item Tracking information';

    protected var
        InternalMovementLine: Record "Internal Movement Line";
        ItemJournalLine: Record "Item Journal Line";
        TransferLine: Record "Transfer Line";
        WhseWorksheetLine: Record "Whse. Worksheet Line";
        WhseInternalPutawayLine: Record "Whse. Internal Put-away Line";
        DestinationType2: Enum "Warehouse Destination Type 2";
        QtyToEmptyBase: Decimal;
        ReportInitialized: Boolean;
        PostingDate: Date;
        DocNo: Code[20];
        PostingDateEditable: Boolean;
        DocNoEditable: Boolean;

    procedure SetParameters(WhseWorksheetLine2: Record "Whse. Worksheet Line"; WhseInternalPutawayHeader2: Record "Whse. Internal Put-away Header"; DestinationType: Enum "Warehouse Destination Type 2")
    begin
        DestinationType2 := DestinationType;
        case DestinationType2 of
            DestinationType2::MovementWorksheet:
                begin
                    WhseWorksheetLine := WhseWorksheetLine2;
                    WhseWorksheetLine.SetCurrentKey("Worksheet Template Name", Name, "Location Code", "Line No.");
                    WhseWorksheetLine.SetRange("Worksheet Template Name", WhseWorksheetLine."Worksheet Template Name");
                    WhseWorksheetLine.SetRange(Name, WhseWorksheetLine.Name);
                    WhseWorksheetLine.SetRange("Location Code", WhseWorksheetLine."Location Code");
                    if WhseWorksheetLine.FindLast() then;
                end;
            DestinationType2::WhseInternalPutawayHeader:
                begin
                    WhseInternalPutawayLine."No." := WhseInternalPutawayHeader2."No.";
                    WhseInternalPutawayLine.SetRange("No.", WhseInternalPutawayLine."No.");
                    if WhseInternalPutawayLine.FindLast() then;
                end;
        end;
        ReportInitialized := true;
    end;

    procedure InitializeItemJournalLine(ItemJournalLine2: Record "Item Journal Line")
    begin
        ItemJournalLine := ItemJournalLine2;
        ItemJournalLine.SetRange("Journal Template Name", ItemJournalLine2."Journal Template Name");
        ItemJournalLine.SetRange("Journal Batch Name", ItemJournalLine2."Journal Batch Name");
        if ItemJournalLine.FindLast() then;

        ItemJournalTemplate.Get(ItemJournalLine."Journal Template Name");
        ItemJournalBatch.Get(ItemJournalLine."Journal Template Name", ItemJournalLine."Journal Batch Name");

        PostingDate := ItemJournalLine2."Posting Date";
        DocNo := ItemJournalLine2."Document No.";

        DestinationType2 := DestinationType2::ItemJournalLine;
        ReportInitialized := true;

        OnAfterInitializeItemJournalLine(ItemJournalLine, ItemJournalTemplate, ItemJournalBatch);
    end;

    procedure InitializeTransferHeader(TransferHeader2: Record "Transfer Header")
    begin
        TransferLine.Reset();
        TransferLine.SetRange("Document No.", TransferHeader2."No.");
        if not TransferLine.FindLast() then begin
            TransferLine.Init();
            TransferLine."Document No." := TransferHeader2."No.";
        end;

        TransferHeader := TransferHeader2;

        DestinationType2 := DestinationType2::TransferHeader;
        ReportInitialized := true;
    end;

    procedure InitializeInternalMovement(InternalMovementHeader2: Record "Internal Movement Header")
    begin
        InternalMovementLine.Reset();
        InternalMovementLine.SetRange("No.", InternalMovementHeader2."No.");
        if not InternalMovementLine.FindLast() then begin
            InternalMovementLine.Init();
            InternalMovementLine."No." := InternalMovementHeader2."No.";
        end;
        InternalMovementHeader := InternalMovementHeader2;

        DestinationType2 := DestinationType2::InternalMovementHeader;
        ReportInitialized := true;
    end;

    local procedure InsertWhseWorksheetLine(BinContent: Record "Bin Content")
    begin
        WhseWorksheetLine.Init();
        WhseWorksheetLine."Line No." := WhseWorksheetLine."Line No." + 10000;
        WhseWorksheetLine.Validate("Location Code", BinContent."Location Code");
        WhseWorksheetLine.Validate("Item No.", BinContent."Item No.");
        WhseWorksheetLine.Validate("Variant Code", BinContent."Variant Code");
        WhseWorksheetLine.Validate("Unit of Measure Code", BinContent."Unit of Measure Code");
        WhseWorksheetLine.Validate("From Bin Code", BinContent."Bin Code");
        WhseWorksheetLine."From Zone Code" := BinContent."Zone Code";
        WhseWorksheetLine.Validate("From Unit of Measure Code", BinContent."Unit of Measure Code");
        WhseWorksheetLine.Validate(Quantity, CalcQtyUOM(QtyToEmptyBase, WhseWorksheetLine."Qty. per From Unit of Measure"));
        if QtyToEmptyBase <> (WhseWorksheetLine.Quantity * WhseWorksheetLine."Qty. per From Unit of Measure") then begin
            WhseWorksheetLine."Qty. (Base)" := QtyToEmptyBase;
            WhseWorksheetLine."Qty. Outstanding (Base)" := QtyToEmptyBase;
            WhseWorksheetLine."Qty. to Handle (Base)" := QtyToEmptyBase;
        end;
        WhseWorksheetLine."Whse. Document Type" := WhseWorksheetLine."Whse. Document Type"::"Whse. Mov.-Worksheet";
        WhseWorksheetLine."Whse. Document No." := WhseWorksheetLine.Name;
        WhseWorksheetLine."Whse. Document Line No." := WhseWorksheetLine."Line No.";
        OnBeforeInsertWWLine(WhseWorksheetLine, BinContent);
        WhseWorksheetLine.Insert();
    end;

    local procedure InsertWhseInternalPutawayLine(BinContent: Record "Bin Content")
    begin
        WhseInternalPutawayLine.Init();
        WhseInternalPutawayLine."Line No." := WhseInternalPutawayLine."Line No." + 10000;
        WhseInternalPutawayLine.Validate("Location Code", BinContent."Location Code");
        WhseInternalPutawayLine.Validate("Item No.", BinContent."Item No.");
        WhseInternalPutawayLine.Validate("Variant Code", BinContent."Variant Code");
        WhseInternalPutawayLine.Validate("Unit of Measure Code", BinContent."Unit of Measure Code");
        WhseInternalPutawayLine.Validate("From Bin Code", BinContent."Bin Code");
        WhseInternalPutawayLine."From Zone Code" := BinContent."Zone Code";
        WhseInternalPutawayLine.Validate("Unit of Measure Code", BinContent."Unit of Measure Code");
        WhseInternalPutawayLine.Validate(Quantity, CalcQtyUOM(QtyToEmptyBase, WhseInternalPutawayLine."Qty. per Unit of Measure"));
        if QtyToEmptyBase <> (WhseInternalPutawayLine.Quantity * WhseInternalPutawayLine."Qty. per Unit of Measure") then begin
            WhseInternalPutawayLine."Qty. (Base)" := QtyToEmptyBase;
            WhseInternalPutawayLine."Qty. Outstanding (Base)" := QtyToEmptyBase;
        end;
        OnBeforeInsertWIPLine(WhseInternalPutawayLine, BinContent);
        WhseInternalPutawayLine.Insert();
    end;

    local procedure InsertItemJournalLine(BinContent: Record "Bin Content")
    var
        SelectedLocation: Record Location;
        ItemLedgerEntryType: Enum "Item Ledger Entry Type";
        IsHandled: Boolean;
    begin
        ItemJournalLine.Init();
        ItemJournalLine."Line No." := ItemJournalLine."Line No." + 10000;
        ItemJournalLine."Source Code" := ItemJournalTemplate."Source Code";
        ItemJournalLine."Posting No. Series" := ItemJournalBatch."Posting No. Series";
        case ItemJournalTemplate.Type of
            ItemJournalTemplate.Type::Item:
                begin
                    SelectedLocation.Get(BinContent."Location Code");
                    if SelectedLocation."Directed Put-away and Pick" then
                        Error(DirectedWhseLocationErr, SelectedLocation.TableCaption(), SelectedLocation.Code, SelectedLocation.FieldCaption("Directed Put-away and Pick"));
                    ItemLedgerEntryType := Enum::"Item Ledger Entry Type"::"Negative Adjmt.";
                end;
            ItemJournalTemplate.Type::Transfer:
                ItemLedgerEntryType := Enum::"Item Ledger Entry Type"::Transfer;
            else
                ItemLedgerEntryType := Enum::"Item Ledger Entry Type"::" ";
        end;
        OnInsertItemJournalLineOnBeforeValidateEntryType(ItemJournalLine, BinContent, ItemLedgerEntryType, ItemJournalTemplate, ItemJournalBatch);
        ItemJournalLine.Validate("Entry Type", ItemLedgerEntryType);
        ItemJournalLine.Validate("Item No.", BinContent."Item No.");
        ItemJournalLine.Validate("Posting Date", PostingDate);
        ItemJournalLine.Validate("Document No.", DocNo);
        ItemJournalLine.Validate("Location Code", BinContent."Location Code");
        if ItemJournalTemplate.Type = ItemJournalTemplate.Type::Transfer then begin
            IsHandled := false;
            OnInsertItemJournalLineOnBeforeValidateNewLocationCode(ItemJournalLine, BinContent, IsHandled);
            if not IsHandled then
                ItemJournalLine.Validate("New Location Code", BinContent."Location Code");
        end;
        ItemJournalLine.Validate("Variant Code", BinContent."Variant Code");
        ItemJournalLine.Validate("Unit of Measure Code", BinContent."Unit of Measure Code");
        ItemJournalLine.Validate("Bin Code", BinContent."Bin Code");
        if ItemJournalTemplate.Type = ItemJournalTemplate.Type::Transfer then begin
            IsHandled := false;
            OnInsertItemJournalLineOnBeforeValidateNewBinCode(ItemJournalLine, BinContent, IsHandled);
            if not IsHandled then
                ItemJournalLine.Validate("New Bin Code", '');
        end;
        ItemJournalLine.Validate("Unit of Measure Code", BinContent."Unit of Measure Code");
        ItemJournalLine.Validate(Quantity, CalcQtyUOM(QtyToEmptyBase, ItemJournalLine."Qty. per Unit of Measure"));
        OnInsertItemJournalLineOnBeforeInsert(ItemJournalLine, BinContent);
        ItemJournalLine.Insert();
        OnAfterInsertItemJnlLine(ItemJournalLine, BinContent);
    end;

    local procedure InsertTransferLine(BinContent: Record "Bin Content")
    begin
        TransferLine.Init();
        TransferLine."Line No." := TransferLine."Line No." + 10000;
        TransferLine.Validate("Item No.", BinContent."Item No.");
        TransferLine.Validate("Variant Code", BinContent."Variant Code");
        TransferLine.Validate("Unit of Measure Code", BinContent."Unit of Measure Code");
        TransferLine.Validate("Transfer-from Bin Code", BinContent."Bin Code");
        TransferLine.Validate("Unit of Measure Code", BinContent."Unit of Measure Code");
        TransferLine.Validate(Quantity, CalcQtyUOM(QtyToEmptyBase, TransferLine."Qty. per Unit of Measure"));
        OnBeforeInsertTransferLine(TransferLine, BinContent);
        TransferLine.Insert();
    end;

    local procedure InsertIntMovementLine(BinContent: Record "Bin Content")
    begin
        InternalMovementLine.Init();
        InternalMovementLine."Line No." := InternalMovementLine."Line No." + 10000;
        InternalMovementLine.Validate("Location Code", BinContent."Location Code");
        InternalMovementLine.Validate("Item No.", BinContent."Item No.");
        InternalMovementLine.Validate("Variant Code", BinContent."Variant Code");
        InternalMovementLine.Validate("Unit of Measure Code", BinContent."Unit of Measure Code");
        InternalMovementLine.Validate("From Bin Code", BinContent."Bin Code");
        InternalMovementLine.Validate("To Bin Code", InternalMovementHeader."To Bin Code");
        InternalMovementLine.Validate("Unit of Measure Code", BinContent."Unit of Measure Code");
        InternalMovementLine.Validate(Quantity, CalcQtyUOM(QtyToEmptyBase, InternalMovementLine."Qty. per Unit of Measure"));
        OnBeforeInsertInternalMovementLine(InternalMovementLine, BinContent);
        InternalMovementLine.Insert();
    end;

    local procedure GetItemTracking(var BinContent: Record "Bin Content")
    var
        WarehouseEntry: Record "Warehouse Entry";
        TempTrackingSpecification: Record "Tracking Specification" temporary;
        ItemTrackingManagement: Codeunit "Item Tracking Management";
        ItemJnlLineReserve: Codeunit "Item Jnl. Line-Reserve";
        TransferLineReserve: Codeunit "Transfer Line-Reserve";
        BinContentByItemTracking: Query "Bin Content by Item Tracking";
        TotalTrackedQtyBase: Decimal;
        IsHandled: Boolean;
    begin
        IsHandled := false;
        OnBeforeGetItemTracking(BinContent, IsHandled, QtyToEmptyBase, DestinationType2, ItemJournalLine, TransferLine);
        if IsHandled then
            exit;

        Clear(ItemTrackingManagement);
        if not ItemTrackingManagement.GetWhseItemTrkgSetup(BinContent."Item No.") then
            exit;

        BinContentByItemTracking.SetRange(Location_Code, BinContent."Location Code");
        BinContentByItemTracking.SetRange(Bin_Code, BinContent."Bin Code");
        BinContentByItemTracking.SetRange(Item_No, BinContent."Item No.");
        BinContentByItemTracking.SetRange(Variant_Code, BinContent."Variant Code");
        BinContentByItemTracking.SetRange(Unit_of_Measure_Code, BinContent."Unit of Measure Code");
        BinContentByItemTracking.Open();
        while BinContentByItemTracking.Read() do begin
            WarehouseEntry.Reset();
            WarehouseEntry.SetRange("Item No.", BinContentByItemTracking.Item_No);
            WarehouseEntry.SetRange("Bin Code", BinContentByItemTracking.Bin_Code);
            WarehouseEntry.SetRange("Location Code", BinContentByItemTracking.Location_Code);
            WarehouseEntry.SetRange("Variant Code", BinContentByItemTracking.Variant_Code);
            WarehouseEntry.SetRange("Unit of Measure Code", BinContentByItemTracking.Unit_of_Measure_Code);
            if BinContentByItemTracking.Serial_No <> '' then
                WarehouseEntry.SetRange("Serial No.", BinContentByItemTracking.Serial_No);
            if BinContentByItemTracking.Lot_No <> '' then
                WarehouseEntry.SetRange("Lot No.", BinContentByItemTracking.Lot_No);
            if BinContentByItemTracking.Package_No <> '' then
                WarehouseEntry.SetRange("Package No.", BinContentByItemTracking.Package_No);
            OnGetItemTrackingOnAfterWarehouseEntrySetFilters(WarehouseEntry, "Bin Content");
            if WarehouseEntry.FindFirst() then
                GetItemTracking(BinContent, WarehouseEntry, TotalTrackedQtyBase, TempTrackingSpecification);
        end;

        if TotalTrackedQtyBase > QtyToEmptyBase then
            exit;

        case DestinationType2 of
            DestinationType2::ItemJournalLine:
                ItemJnlLineReserve.RegisterBinContentItemTracking(ItemJournalLine, TempTrackingSpecification);
            DestinationType2::TransferHeader:
                TransferLineReserve.RegisterBinContentItemTracking(TransferLine, TempTrackingSpecification);
        end;

        if GuiAllowed() then
            ProgressWindow.Update(2, '');
    end;

    procedure GetItemTracking(var BinContent: Record "Bin Content"; var WarehouseEntry: Record "Warehouse Entry"; var TotalTrackedQtyBase: Decimal; var TempTrackingSpecification: Record "Tracking Specification" temporary)
    var
        ItemTrackingSetup: Record "Item Tracking Setup";
        ItemTrackingManagement: Codeunit "Item Tracking Management";
        ItemJnlLineReserve: Codeunit "Item Jnl. Line-Reserve";
        TransferLineReserve: Codeunit "Transfer Line-Reserve";
        Direction: Enum "Transfer Direction";
        TrackedQtyToEmptyBase: Decimal;
    begin
        if GuiAllowed() then
            ProgressWindow.Update(2, CreateItemTrackingProgressWindowText(WarehouseEntry));
        if WarehouseEntry.TrackingExists() then begin
            ItemTrackingSetup.CopyTrackingFromWhseEntry(WarehouseEntry);

            TrackedQtyToEmptyBase := GetQtyToEmptyBase(ItemTrackingSetup);
            TotalTrackedQtyBase += TrackedQtyToEmptyBase;

            if TrackedQtyToEmptyBase > 0 then begin
                GetLocation(WarehouseEntry."Location Code", Location);
                ItemTrackingManagement.GetWhseExpirationDate(WarehouseEntry."Item No.", WarehouseEntry."Variant Code", Location, ItemTrackingSetup, WarehouseEntry."Expiration Date");

                case DestinationType2 of
                    DestinationType2::MovementWorksheet:
                        WhseWorksheetLine.SetItemTrackingLines(WarehouseEntry, TrackedQtyToEmptyBase);
                    DestinationType2::WhseInternalPutawayHeader:
                        WhseInternalPutawayLine.SetItemTrackingLines(WarehouseEntry, TrackedQtyToEmptyBase);
                    DestinationType2::ItemJournalLine:
                        ItemJnlLineReserve.InitFromItemJnlLine(TempTrackingSpecification, ItemJournalLine);
                    DestinationType2::TransferHeader:
                        TransferLineReserve.InitFromTransLine(TempTrackingSpecification, TransferLine, TransferLine."Shipment Date", Direction::Outbound);
                    DestinationType2::InternalMovementHeader:
                        InternalMovementLine.SetItemTrackingLines(WarehouseEntry, TrackedQtyToEmptyBase);
                    else
                        OnGetItemTrackingOnDestinationTypeCaseElse(DestinationType2, BinContent, WarehouseEntry, TrackedQtyToEmptyBase);
                end;
            end;
        end;
        if DestinationType2 in [DestinationType2::ItemJournalLine, DestinationType2::TransferHeader] then
            InsertTempTrackingSpecification(WarehouseEntry, TrackedQtyToEmptyBase, TempTrackingSpecification);
    end;

    protected procedure GetLocation(LocationCode: Code[10]; var Location: Record Location)
    begin
        if LocationCode = Location.Code then
            exit;

        if LocationCode = '' then
            Location.Init()
        else
            Location.Get(LocationCode);
    end;

    protected procedure InsertTempTrackingSpecification(WarehouseEntry: Record "Warehouse Entry"; QtyOnBin: Decimal; var TempTrackingSpecification: Record "Tracking Specification" temporary)
    begin
        TempTrackingSpecification.Init();
        TempTrackingSpecification."Item No." := WarehouseEntry."Item No.";
        TempTrackingSpecification.SetSkipSerialNoQtyValidation(true);
        TempTrackingSpecification.Validate("Serial No.", WarehouseEntry."Serial No.");
        TempTrackingSpecification.SetSkipSerialNoQtyValidation(false);
        TempTrackingSpecification."New Serial No." := WarehouseEntry."Serial No.";
        TempTrackingSpecification.Validate("Lot No.", WarehouseEntry."Lot No.");
        TempTrackingSpecification."New Lot No." := WarehouseEntry."Lot No.";
        OnInsertTempTrackingSpecOnAfterAssignTracking(TempTrackingSpecification, WarehouseEntry);
        TempTrackingSpecification."Quantity Handled (Base)" := 0;
        TempTrackingSpecification."Expiration Date" := WarehouseEntry."Expiration Date";
        TempTrackingSpecification."New Expiration Date" := WarehouseEntry."Expiration Date";
        TempTrackingSpecification.Validate("Quantity (Base)", QtyOnBin);
        TempTrackingSpecification."Entry No." += 1;
        TempTrackingSpecification.Insert();
        OnAfterInsertTempTrackingSpec(TempTrackingSpecification, WarehouseEntry);
    end;

    protected procedure CalcQtyUOM(QtyBase: Decimal; QtyPerUOM: Decimal): Decimal
    begin
        if QtyPerUOM = 0 then
            exit(0);

        exit(Round(QtyBase / QtyPerUOM, UOMMgt.QtyRndPrecision()));
    end;

    protected procedure GetQtyToEmptyBase(ItemTrackingSetup: Record "Item Tracking Setup"): Decimal
    var
        BinContent: Record "Bin Content";
        AvailableQty: Decimal;
    begin
        BinContent.Init();
        BinContent.Copy("Bin Content");
        BinContent.FilterGroup(8);
        BinContent.SetTrackingFilterFromItemTrackingSetupIfNotBlank(ItemTrackingSetup);
        case DestinationType2 of
            DestinationType2::TransferHeader:
                exit(BinContent.CalcQtyAvailToPick(0));

            DestinationType2::ItemJournalLine:
                begin
                    BinContent.CalcFields("Quantity (Base)", "Pick Quantity (Base)", "ATO Components Pick Qty (Base)");
                    AvailableQty := BinContent."Quantity (Base)" - (BinContent."Pick Quantity (Base)" + BinContent."ATO Components Pick Qty (Base)");
                    if AvailableQty > 0 then
                        exit(AvailableQty);
                    exit(0);
                end;
            else
                exit(BinContent.CalcQtyAvailToTake(0));
        end;
    end;

    local procedure CreateBinContentProgressWindowText(BinContent: Record "Bin Content") BinContentProgressWindowText: Text
    begin
        if BinContent."Location Code" <> '' then
            BinContentProgressWindowText := BinContent.FieldCaption("Location Code") + ' = ' + BinContent."Location Code";

        if BinContent."Bin Code" <> '' then
            if BinContentProgressWindowText <> '' then
                BinContentProgressWindowText := BinContentProgressWindowText + ', ' + BinContent.FieldCaption("Bin Code") + ' = ' + BinContent."Bin Code"
            else
                BinContentProgressWindowText := BinContent.FieldCaption("Bin Code") + ' = ' + BinContent."Bin Code";

        if BinContent."Item No." <> '' then
            if BinContentProgressWindowText <> '' then
                BinContentProgressWindowText := BinContentProgressWindowText + ', ' + BinContent.FieldCaption("Item No.") + ' = ' + BinContent."Item No."
            else
                BinContentProgressWindowText := BinContent.FieldCaption("Item No.") + ' = ' + BinContent."Item No.";

        if BinContent."Variant Code" <> '' then
            if BinContentProgressWindowText <> '' then
                BinContentProgressWindowText := BinContentProgressWindowText + ', ' + BinContent.FieldCaption("Variant Code") + ' = ' + BinContent."Variant Code"
            else
                BinContentProgressWindowText := BinContent.FieldCaption("Variant Code") + ' = ' + BinContent."Variant Code";

        if BinContent."Unit of Measure Code" <> '' then
            if BinContentProgressWindowText <> '' then
                BinContentProgressWindowText := BinContentProgressWindowText + ', ' + BinContent.FieldCaption("Unit of Measure Code") + ' = ' + BinContent."Unit of Measure Code"
            else
                BinContentProgressWindowText := BinContent.FieldCaption("Unit of Measure Code") + ' = ' + BinContent."Unit of Measure Code";
    end;

    local procedure CreateItemTrackingProgressWindowText(WarehouseEntry: Record "Warehouse Entry") ItemTrackingProgressWindowText: Text
    begin
        if WarehouseEntry."Serial No." <> '' then
            ItemTrackingProgressWindowText := WarehouseEntry.FieldCaption("Serial No.") + ' = ' + WarehouseEntry."Serial No.";

        if WarehouseEntry."Lot No." <> '' then
            if ItemTrackingProgressWindowText <> '' then
                ItemTrackingProgressWindowText := ItemTrackingProgressWindowText + ', ' + WarehouseEntry.FieldCaption("Lot No.") + ' = ' + WarehouseEntry."Lot No."
            else
                ItemTrackingProgressWindowText := WarehouseEntry.FieldCaption("Lot No.") + ' = ' + WarehouseEntry."Lot No.";

        if WarehouseEntry."Package No." <> '' then
            if ItemTrackingProgressWindowText <> '' then
                ItemTrackingProgressWindowText := ItemTrackingProgressWindowText + ', ' + WarehouseEntry.FieldCaption("Package No.") + ' = ' + WarehouseEntry."Package No."
            else
                ItemTrackingProgressWindowText := WarehouseEntry.FieldCaption("Package No.") + ' = ' + WarehouseEntry."Package No.";
    end;

    [IntegrationEvent(false, false)]
    local procedure OnAfterInsertItemJnlLine(var ItemJournalLine: Record "Item Journal Line"; BinContent: Record "Bin Content")
    begin
    end;

    [IntegrationEvent(true, false)]
    local procedure OnAfterInitializeItemJournalLine(var ItemJournalLine: Record "Item Journal Line"; var ItemJournalTemplate: Record "Item Journal Template"; var ItemJournalBatch: Record "Item Journal Batch")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnAfterInsertTempTrackingSpec(var TempTrackingSpecification: Record "Tracking Specification" temporary; WarehouseEntry: Record "Warehouse Entry")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnAfterBinContentOnPostDataItem(ItemJournalLine: Record "Item Journal Line"; TransferHeader: Record "Transfer Header"; InternalMovementHeader: Record "Internal Movement Header"; DestinationType2: Option MovementWorksheet,WhseInternalPutawayHeader,ItemJournalLine,TransferHeader,InternalMovementHeader)
    begin
    end;

    [IntegrationEvent(true, false)]
    local procedure OnBinContenOnAfterGetRecordOnAfterCalcShouldSkipReportForQty(var BinContent: Record "Bin Content"; var ShouldSkipReportForQty: Boolean; DestinationType2: Enum "Warehouse Destination Type 2"; WhseWorksheetLine: Record "Whse. Worksheet Line"; WhseInternalPutawayLine: Record "Whse. Internal Put-away Line"; ItemJournalLine: Record "Item Journal Line"; TransferLine: Record "Transfer Line"; InternalMovementLine: Record "Internal Movement Line"; PostingDate: Date; DocumentNo: Code[20])
    begin
    end;

    [IntegrationEvent(true, false)]
    local procedure OnBinContentOnAfterGetRecordOnDestinationTypeElseCase(QtyToEmptyBase: Decimal; var BinContent: Record "Bin Content"; DestinationType2: Enum "Warehouse Destination Type 2")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnInsertTempTrackingSpecOnAfterAssignTracking(var TempTrackingSpecification: Record "Tracking Specification" temporary; WarehouseEntry: Record "Warehouse Entry")
    begin
    end;

#if not CLEAN27
    [Obsolete('The GetItemTracking method has been refactored to use a query-based approach for improved performance. While this event publisher remains available, please verify that your subscriber logic continues to function as expected with the updated implementation.', '27.0')]
#endif
    [IntegrationEvent(true, false)]
    local procedure OnBeforeGetItemTracking(var BinContent: Record "Bin Content"; var IsHandled: Boolean; QtyToEmptyBase: Decimal; DestinationType2: Enum "Warehouse Destination Type 2"; var ItemJournalLine: Record "Item Journal Line"; var TransferLine: Record "Transfer Line")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnBeforeInsertInternalMovementLine(var InternalMovementLine: Record "Internal Movement Line"; BinContent: Record "Bin Content")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnBeforeInsertTransferLine(var TransferLine: Record "Transfer Line"; BinContent: Record "Bin Content")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnBeforeInsertWIPLine(var WhseInternalPutAwayLine: Record "Whse. Internal Put-away Line"; BinContent: Record "Bin Content")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnBeforeInsertWWLine(var WhseWorksheetLine: Record "Whse. Worksheet Line"; BinContent: Record "Bin Content")
    begin
    end;

#if not CLEAN27
    [Obsolete('The GetItemTracking method has been refactored to use a query-based approach for improved performance. While this event publisher remains available, please verify that your subscriber logic continues to function as expected with the updated implementation.', '27.0')]
#endif
    [IntegrationEvent(false, false)]
    local procedure OnGetItemTrackingOnDestinationTypeCaseElse(DestinationType2: Enum "Warehouse Destination Type 2"; BinContent: Record "Bin Content"; WarehouseEntry: Record "Warehouse Entry"; TrackedQtyToEmptyBase: Decimal)
    begin
    end;

#if not CLEAN27
    [Obsolete('The GetItemTracking method has been refactored to use a query-based approach for improved performance. While this event publisher remains available, please verify that your subscriber logic continues to function as expected with the updated implementation.', '27.0')]
#endif
    [IntegrationEvent(false, false)]
    local procedure OnGetItemTrackingOnAfterWarehouseEntrySetFilters(var WarehouseEntry: Record "Warehouse Entry"; var BinContent: Record "Bin Content")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnInsertItemJournalLineOnBeforeInsert(var ItemJournalLine: Record "Item Journal Line"; BinContent: Record "Bin Content")
    begin
    end;

    [IntegrationEvent(true, false)]
    local procedure OnInsertItemJournalLineOnBeforeValidateEntryType(var ItemJournalLine: Record "Item Journal Line"; var BinContent: Record "Bin Content"; var ItemLedgerEntryType: Enum "Item Ledger Entry Type"; ItemJournalTemplate: Record "Item Journal Template"; ItemJournalBatch: Record "Item Journal Batch")
    begin
    end;

    [IntegrationEvent(true, false)]
    local procedure OnInsertItemJournalLineOnBeforeValidateNewLocationCode(var ItemJournalLine: Record "Item Journal Line"; var BinContent: Record "Bin Content"; var IsHandled: Boolean)
    begin
    end;

    [IntegrationEvent(true, false)]
    local procedure OnInsertItemJournalLineOnBeforeValidateNewBinCode(var ItemJournalLine: Record "Item Journal Line"; BinContent: Record "Bin Content"; var IsHandled: Boolean)
    begin
    end;
}