Skip to content

[Event Request] codeunit 22 "Item Jnl.-Post Line" #30213

Description

@Simon110394

Why do you need this change?

We need four events inside the codeunit "Item Jnl.-Post Line".
OnBeforeTestOldItemLedgEntryLocationCode will be used to be able to set a condition before testing the location code.
At the moment there no other alternative events to exploit to have the possibility to skip the line OldItemLedgEntry.TestField("Location Code", ItemJnlLine."Location Code");

The the three events requested for procedure RedoApplications are intended to be able to manage the standard dialog window only under particular conditions.
At the moment there are no alternative events to manage this logic.

Describe the request

In procedure ApplyItemLedgEntry of codeunit 22 "Item Jnl.-Post Line" we need an event:

[IntegrationEvent(false, false)]
local procedure OnBeforeTestOldItemLedgEntryLocationCode(var Ishandled: Boolean; var OldItemLedgEntry: Record "Item Ledger Entry")
begin
end;

Changes between **:

procedure ApplyItemLedgEntry(var ItemLedgEntry: Record "Item Ledger Entry"; var OldItemLedgEntry: Record "Item Ledger Entry"; var ValueEntry: Record "Value Entry"; CausedByTransfer: Boolean)
    var
        ItemLedgEntry2: Record "Item Ledger Entry";
        OldValueEntry: Record "Value Entry";
        ReservEntry: Record "Reservation Entry";
        ReservEntry2: Record "Reservation Entry";
        AppliesFromItemLedgEntry: Record "Item Ledger Entry";
        EntryFindMethod: Text[1];
        AppliedQty: Decimal;
        FirstReservation: Boolean;
        FirstApplication: Boolean;
        StartApplication: Boolean;
        UseReservationApplication: Boolean;
        IsHandled: Boolean;
        SkipReservationCheck: Boolean;
    begin
        OnBeforeApplyItemLedgEntry(ItemLedgEntry, OldItemLedgEntry, ValueEntry, CausedByTransfer, IsHandled, ItemJnlLine, ItemApplnEntryNo);
        if IsHandled then
            exit;

        if (ItemLedgEntry."Remaining Quantity" = 0) or
           (ItemLedgEntry."Drop Shipment" and (ItemLedgEntry."Applies-to Entry" = 0)) or
           ((Item."Costing Method" = Item."Costing Method"::Specific) and ItemLedgEntry.Positive) or
           (ItemJnlLine."Direct Transfer" and (ItemLedgEntry."Location Code" = '') and ItemLedgEntry.Positive)
        then
            exit;

        Clear(OldItemLedgEntry);
        ItemLedgEntry2.ReadIsolation(IsolationLevel::ReadUnCommitted);
        FirstReservation := true;
        FirstApplication := true;
        StartApplication := false;
        repeat
            if ItemJnlLine."Assemble to Order" then
                VerifyItemJnlLineAsembleToOrder(ItemJnlLine)
            else
                VerifyItemJnlLineApplication(ItemJnlLine, ItemLedgEntry);

            if not CausedByTransfer and not PostponeReservationHandling then begin
                if Item."Costing Method" = Item."Costing Method"::Specific then
                    ItemJnlLine.TestField("Serial No.");

                SkipReservationCheck := //posting together with PO
                    (ItemJnlLine."Document Type" = ItemJnlLine."Document Type"::"Purchase Receipt")
                    and (ItemJnlLine."Entry Type" = ItemJnlLine."Entry Type"::"Negative Adjmt.")
                    and (ItemJnlLine."Job No." <> '');

                IsHandled := false;
                OnApplyItemLedgEntryOnBeforeFirstReservationSetFilters(ItemJnlLine, StartApplication, FirstReservation, IsHandled);
                if not IsHandled then
                    if FirstReservation then begin
                        FirstReservation := false;
                        ReservEntry.Reset();
                        ReservEntry.SetCurrentKey(
                          "Source ID", "Source Ref. No.", "Source Type", "Source Subtype",
                          "Source Batch Name", "Source Prod. Order Line", "Reservation Status");
                        ReservEntry.SetRange("Reservation Status", ReservEntry."Reservation Status"::Reservation);
                        ItemJnlLine.SetReservationFilters(ReservEntry);
                        ReservEntry.SetRange("Item No.", ItemJnlLine."Item No.");
                    end;

                if TempTrackingSpecification.IsEmpty() then
                    if ItemJnlLine."Document Type" = ItemJnlLine."Document Type"::"Direct Transfer" then
                        if ItemLedgEntry.Quantity < 0 then
                            ReservEntry.SetRange(Positive, false)
                        else
                            ReservEntry.SetRange(Positive, true);

                if not SkipReservationCheck then
                    UseReservationApplication := FindReservationEntryWithAdditionalCheckForAssemblyItem(ReservEntry);

                IsHandled := false;
                OnApplyItemLedgEntryOnBeforeCloseSurplusTrackingEntry(ItemJnlLine, StartApplication, UseReservationApplication, IsHandled);
                if not IsHandled then
                    if not UseReservationApplication then begin // No reservations exist
                        ReservEntry.SetRange(
                          "Reservation Status", ReservEntry."Reservation Status"::Tracking,
                          ReservEntry."Reservation Status"::Prospect);
                        if ReservEntry.FindSet() then
                            repeat
                                ReservEngineMgt.CloseSurplusTrackingEntry(ReservEntry);
                            until ReservEntry.Next() = 0;
                        StartApplication := true;
                    end;

                if UseReservationApplication then begin
                    ReservEntry2.SetLoadFields("Source Type", "Source Ref. No.", "Item No.", "Quantity (Base)");
                    OnApplyItemLedgEntryOnAfterSetLoadFieldsOnReservEntry(ReservEntry2);
                    ReservEntry2.Get(ReservEntry."Entry No.", not ReservEntry.Positive);
                    if ReservEntry2."Source Type" <> DATABASE::"Item Ledger Entry" then
                        if ItemLedgEntry.Quantity < 0 then
                            Error(Text003, ReservEntry."Item No.");
                    OldItemLedgEntry.Get(ReservEntry2."Source Ref. No.");
                    if ItemLedgEntry.Quantity < 0 then
                        if OldItemLedgEntry."Remaining Quantity" < ReservEntry2."Quantity (Base)" then
                            Error(Text003, ReservEntry2."Item No.");

                    OldItemLedgEntry.TestField("Item No.", ItemJnlLine."Item No.");
                    OldItemLedgEntry.TestField("Variant Code", ItemJnlLine."Variant Code");
					**Ishandled := false;
					OnBeforeTestOldItemLedgEntryLocationCode(Ishandled, OldItemLedgEntry)
					if not Ishandled then**
						OldItemLedgEntry.TestField("Location Code", ItemJnlLine."Location Code");
                    OnApplyItemLedgEntryOnBeforeCloseReservEntry(OldItemLedgEntry, ItemJnlLine, ItemLedgEntry, ReservEntry);
                    ReservEngineMgt.CloseReservEntry(ReservEntry, false, false);
                    OnApplyItemLedgEntryOnAfterCloseReservEntry(OldItemLedgEntry, ItemJnlLine, ItemLedgEntry, ReservEntry);
                    OldItemLedgEntry.CalcReservedQuantity();
                    AppliedQty := -Abs(ReservEntry."Quantity (Base)");
                end;
            end else
                StartApplication := true;

            OnApplyItemLedgEntryOnBeforeStartApplication(ItemLedgEntry, OldItemLedgEntry, StartApplication, AppliedQty, Item, ItemJnlLine);

            if StartApplication then begin
                ItemLedgEntry.CalcReservedQuantity();
                if ItemLedgEntry."Applies-to Entry" <> 0 then begin
                    if FirstApplication then begin
                        FirstApplication := false;
                        OldItemLedgEntry.Get(ItemLedgEntry."Applies-to Entry");
                        TestFirstApplyItemLedgEntry(OldItemLedgEntry, ItemLedgEntry);
                        OnApplyItemLedgEntryOnAfterTestFirstApplyItemLedgEntry(OldItemLedgEntry, ItemLedgEntry);
                    end else
                        exit;
                end else
                    if FindOpenItemLedgEntryToApply(ItemLedgEntry2, ItemLedgEntry, FirstApplication, EntryFindMethod) then
                        OldItemLedgEntry.Copy(ItemLedgEntry2)
                    else
                        exit;

                OldItemLedgEntry.CalcReservedQuantity();
                OnAfterApplyItemLedgEntryOnBeforeCalcAppliedQty(OldItemLedgEntry, ItemLedgEntry);

                if Abs(OldItemLedgEntry."Remaining Quantity" - OldItemLedgEntry."Reserved Quantity") >
                   Abs(ItemLedgEntry."Remaining Quantity" - ItemLedgEntry."Reserved Quantity")
                then
                    AppliedQty := ItemLedgEntry."Remaining Quantity" - ItemLedgEntry."Reserved Quantity"
                else begin
                    AppliedQty := -(OldItemLedgEntry."Remaining Quantity" - OldItemLedgEntry."Reserved Quantity");
                    if AppliedQty = 0 then
                        AppliedQty := UpdateAppliedQtyIfConsumptionEntry(ItemLedgEntry, OldItemLedgEntry);
                end;

                OnApplyItemLedgEntryOnAfterCalcAppliedQty(OldItemLedgEntry, ItemLedgEntry, AppliedQty);

                if (ItemLedgEntry."Entry Type" = ItemLedgEntry."Entry Type"::Transfer) and not ItemLedgEntry.Positive then
                    if OldItemLedgEntry.EntryNoHasSameSign(ItemLedgEntry."Entry No.") and (OldItemLedgEntry."Entry No." > ItemLedgEntry."Entry No.") and (ItemLedgEntry."Entry No." >= 0) and not ItemLedgEntry.Positive or
                        not OldItemLedgEntry.EntryNoHasSameSign(ItemLedgEntry."Entry No.") and ((OldItemLedgEntry.SystemId > ItemLedgEntry.SystemId) and not IsNullGuid(ItemLedgEntry.SystemId) or IsNullGuid(OldItemLedgEntry.SystemId)) // Preview?
                    then
                        AppliedQty := 0;

                if (OldItemLedgEntry."Order Type" = OldItemLedgEntry."Order Type"::Production) and
                   (OldItemLedgEntry."Order No." <> '')
                then
                    if not AllowProdApplication(OldItemLedgEntry, ItemLedgEntry) then
                        AppliedQty := 0;
                if ItemJnlLine."Applies-from Entry" <> 0 then begin
                    AppliesFromItemLedgEntry.Get(ItemJnlLine."Applies-from Entry");
                    if ItemApplnEntry.CheckIsCyclicalLoop(AppliesFromItemLedgEntry, OldItemLedgEntry) then
                        AppliedQty := 0;
                end;
                OnApplyItemLedgEntryOnAfterSetAppliedQtyZero(OldItemLedgEntry, ItemLedgEntry, AppliedQty, ItemJnlLine);
            end;

            CheckIsCyclicalLoop(ItemLedgEntry, OldItemLedgEntry, PrevAppliedItemLedgEntry, AppliedQty);

            if AppliedQty <> 0 then begin
                if not OldItemLedgEntry.Positive and
                   (OldItemLedgEntry."Remaining Quantity" = -AppliedQty) and
                   (OldItemLedgEntry."Entry No." = ItemLedgEntry."Applies-to Entry")
                then begin
                    OldValueEntry.SetCurrentKey("Item Ledger Entry No.");
                    OldValueEntry.SetRange("Item Ledger Entry No.", OldItemLedgEntry."Entry No.");
                    if OldValueEntry.Find('-') then
                        repeat
                            if OldValueEntry."Valued By Average Cost" then begin
                                OldValueEntry."Valued By Average Cost" := false;
                                OldValueEntry.Modify();
                            end;
                        until OldValueEntry.Next() = 0;
                end;

                UpdateOldItemLedgerEntryRemainingQuantity(OldItemLedgEntry, AppliedQty);

                if ItemLedgEntry.Positive then begin
                    OnApplyItemLedgEntryOnItemLedgEntryPositiveOnBeforeInsertApplEntry(OldItemLedgEntry, ItemLedgEntry, GlobalItemLedgEntry, AppliedQty);
                    if ItemLedgEntry."Posting Date" >= OldItemLedgEntry."Posting Date" then
                        InsertApplEntry(
                          OldItemLedgEntry."Entry No.", ItemLedgEntry."Entry No.",
                          OldItemLedgEntry."Entry No.", 0, ItemLedgEntry."Posting Date", -AppliedQty, false)
                    else
                        InsertApplEntry(
                          OldItemLedgEntry."Entry No.", ItemLedgEntry."Entry No.",
                          OldItemLedgEntry."Entry No.", 0, OldItemLedgEntry."Posting Date", -AppliedQty, false);

                    if ItemApplnEntry."Cost Application" then
                        ItemLedgEntry."Applied Entry to Adjust" := true;
                end else begin
                    OnApplyItemLedgEntryOnBeforeCheckApplyEntry(OldItemLedgEntry);

                    CheckPostingDateWithExpirationDate(ItemLedgEntry);

                    OnApplyItemLedgEntryOnBeforeInsertApplEntry(ItemLedgEntry, ItemJnlLine, OldItemLedgEntry, GlobalItemLedgEntry, AppliedQty);

                    InsertApplEntry(
                      ItemLedgEntry."Entry No.", OldItemLedgEntry."Entry No.", ItemLedgEntry."Entry No.", 0,
                      ItemLedgEntry."Posting Date", AppliedQty, true);

                    if ItemApplnEntry."Cost Application" then
                        OldItemLedgEntry."Applied Entry to Adjust" := true;
                end;

                OnApplyItemLedgEntryOnBeforeOldItemLedgEntryModify(ItemLedgEntry, OldItemLedgEntry, ItemJnlLine, AverageTransfer);
                OldItemLedgEntry.Modify();
                AutoTrack(OldItemLedgEntry, true);

                EnsureValueEntryLoaded(ValueEntry, ItemLedgEntry);
                IsHandled := false;
                OnApplyItemLedgEntryOnBeforeGetValuationDate(ValueEntry, IsHandled);
                if not IsHandled then
                    GetValuationDate(ValueEntry, OldItemLedgEntry);

                if (ItemLedgEntry."Entry Type" = ItemLedgEntry."Entry Type"::Transfer) and
                   (AppliedQty < 0) and
                   not CausedByTransfer and
                   not ItemLedgEntry.Correction
                then begin
                    if ItemLedgEntry."Completely Invoiced" then
                        ItemLedgEntry."Completely Invoiced" := OldItemLedgEntry."Completely Invoiced";
                    if AverageTransfer then
                        TotalAppliedQty := TotalAppliedQty + AppliedQty
                    else
                        InsertTransferEntry(ItemLedgEntry, OldItemLedgEntry, AppliedQty);
                end;

                UpdateItemLedgerEntryRemainingQuantity(ItemLedgEntry, AppliedQty, OldItemLedgEntry, CausedByTransfer);

                ItemLedgEntry.CalcReservedQuantity();
                if ItemLedgEntry."Remaining Quantity" + ItemLedgEntry."Reserved Quantity" = 0 then
                    exit;
            end;
            OnApplyItemLedgEntryOnApplicationLoop(ItemLedgEntry);
        until false;
    end;

In procedure RedoApplications of codeunit 22 "Item Jnl.-Post Line" we need three events:

[IntegrationEvent(false, false)]
local procedure OnBeforeOpenDialogWindow(var Ishandled: Boolean)
begin
end;

[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateDialogWindow(var Ishandled: Boolean)
begin
end;

[IntegrationEvent(false, false)]
local procedure OnBeforeCloseDialogWindow(var Ishandled: Boolean)
begin
end;

Changes between **:

procedure RedoApplications()
    var
        TouchedItemLedgEntry: Record "Item Ledger Entry";
        DialogWindow: Dialog;
        "Count": Integer;
        t: Integer;
		**Ishandled: Boolean;**
    begin
        TempTouchedItemLedgerEntries.SetCurrentKey("Item No.", Open, "Variant Code", Positive, "Location Code", "Posting Date", "Entry No.");
        if TempTouchedItemLedgerEntries.Find('-') then begin
			**Ishandled := false;
			OnBeforeOpenDialogWindow(Ishandled);
			if not Ishandled then **
				DialogWindow.Open(Text01 +
				  '@1@@@@@@@@@@@@@@@@@@@@@@@');
            Count := TempTouchedItemLedgerEntries.Count();
            t := 0;

            repeat
                t := t + 1;
				**Ishandled := false;
				OnBeforeUpdateDialogWindow(Ishandled);
				if not Ishandled then **
					DialogWindow.Update(1, Round(t * 10000 / Count, 1));
                TouchedItemLedgEntry.Get(TempTouchedItemLedgerEntries."Entry No.");
                if TouchedItemLedgEntry."Remaining Quantity" <> 0 then begin
                    ReApply(TouchedItemLedgEntry, 0);
                    TouchedItemLedgEntry.Get(TempTouchedItemLedgerEntries."Entry No.");
                end;
            until TempTouchedItemLedgerEntries.Next() = 0;
            if AnyTouchedEntries() then
                VerifyTouchedOnInventory();
            TempTouchedItemLedgerEntries.DeleteAll();
            DeleteTouchedEntries();
			**Ishandled := false;
			OnBeforeCloseDialogWindow(Ishandled);
			if not Ishandled then **
				DialogWindow.Close();
        end;
    end;

Metadata

Metadata

Assignees

No one assigned

    Labels

    missing-infoThe issue misses information that prevents it from completion.

    Type

    No fields configured for Task.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions