Skip to content

[W1][Codeunit][7312][Create Pick] Add QtyAvailableBase parameter to OnFindBWPickBinOnBeforeEndLoop #30179

@MortegaITB

Description

@MortegaITB

Why do you need this change?

We subscribe to OnFindBWPickBinOnBeforeFromBinContentFindSet to control which bin contents are considered when generating pick lines (custom bin selection logic for specific integrations and warehouse workflows).

When our subscriber overrides the standard bin recordset, we also need to control when the repeat-until loop should stop inside FindBWPickBin. For that, we subscribe to the existing OnFindBWPickBinOnBeforeEndLoop event and set IsHandled := true to bypass the standard Next() / TotalQtyToPickBase = 0 check.

However, to make a correct loop-termination decision, we need to know QtyAvailableBase for the current FromBinContent record — specifically, whether the available quantity in the current bin is enough to cover TotalQtyToPickBase. This value is calculated earlier in the same iteration (via CalcQtyAvailToPick minus assigned pick qty) but is not currently exposed in the event signature.

Without QtyAvailableBase, subscribers cannot implement correct loop-termination logic without duplicating the CalcQtyAvailToPick call outside the standard procedure, which introduces redundant database reads and a maintenance liability with every BC update.

Alternatives evaluated

  • OnFindBWPickBinOnBeforeFromBinContentFindSet: Already used for bin filtering. Fires before the loop — cannot control per-iteration termination.
  • OnCalcAvailQtyOnFindBWPickBin: Fires earlier in the same iteration and allows modifying QtyAvailableBase, but does not expose EndLoop or IsHandled, so it cannot be used to terminate the loop.
  • OnBeforeFindBWPickBin: Fires before any filtering — too early, no access to per-iteration data.
  • TryFunction wrapper: Silently swallows all errors without discrimination. Not safe or maintainable.
  • Duplicating standard logic: Creates a maintenance liability with every BC update. Rejected.
  • Passing the value indirectly via a global or setup table: Anti-pattern that introduces coupling and state management risk. Rejected.

There is no existing event that simultaneously exposes QtyAvailableBase, TotalQtyToPickBase, EndLoop, and IsHandled in the same loop iteration context.

Performance & data considerations

FindBWPickBin is called once per pick line — not in bulk loops over large datasets. The event fires once per loop iteration, bounded by the number of matching bin content records (typically small). QtyAvailableBase is a Decimal primitive passed by value — negligible overhead. No sensitive or GDPR-relevant data is exposed; FromBinContent is already present in the existing signature and widely exposed in other standard BC events.

Multi-extension interaction

The IsHandled pattern is already in place on this event. If multiple extensions subscribe and both set IsHandled := true, the first subscriber controls the outcome — consistent with standard BC behavior for all IsHandled events. The worst-case conflict is that the loop terminates earlier than expected, which is the intended outcome for any subscriber setting IsHandled := true. No data corruption or inconsistent warehouse state can result.

Describe the request

Add QtyAvailableBase: Decimal as a new parameter to the existing event publisher OnFindBWPickBinOnBeforeEndLoop in Codeunit 7312 Create Pick".

This is a one-line change to the existing event signature — no logic changes, no new variables, no refactoring required.

Proposed code (before → after)

Before:

EndLoop := false;
IsHandled := false;
OnFindBWPickBinOnBeforeEndLoop(FromBinContent, TotalQtyToPickBase, EndLoop, IsHandled, QtytoPick, QtyToPickBase);
if not IsHandled then
    EndLoop := (FromBinContent.Next() = 0) or (TotalQtyToPickBase = 0);

After:

EndLoop := false;
IsHandled := false;
OnFindBWPickBinOnBeforeEndLoop(FromBinContent, QtyAvailableBase, TotalQtyToPickBase, EndLoop, IsHandled, QtytoPick, QtyToPickBase);
if not IsHandled then
    EndLoop := (FromBinContent.Next() = 0) or (TotalQtyToPickBase = 0);

Updated publisher signature:

[IntegrationEvent(false, false)]
local procedure OnFindBWPickBinOnBeforeEndLoop(var FromBinContent: Record "Bin Content"; QtyAvailableBase: Decimal; var TotalQtyToPickBase: Decimal; var EndLoop: Boolean; var IsHandled: Boolean; QtytoPick: Decimal; QtyToPickBase: Decimal)
begin
end;

QtyAvailableBase is passed by value (no var) — subscribers should only
read it, not modify it, preserving the integrity of the quantity calculation.

Subscriber example (illustrative)

[EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Pick", OnFindBWPickBinOnBeforeEndLoop, '', false, false)]
local procedure OnFindBWPickBinOnBeforeEndLoop(var FromBinContent: Record "Bin Content"; QtyAvailableBase: Decimal; var TotalQtyToPickBase: Decimal; var EndLoop: Boolean; var IsHandled: Boolean; QtytoPick: Decimal; QtyToPickBase: Decimal)
begin
    if TotalQtyToPickBase = 0 then
        exit;

    if TotalQtyToPickBase <= QtyAvailableBase then
        IsHandled := true;
end;

Justification for IsHandled

The IsHandled pattern is already in place on this event. This request is not asking to introduce a new IsHandled event — it is asking to add one missing parameter (QtyAvailableBase) to an existing IsHandled event publisher.

The parameter is essential for subscribers to make an informed decision about loop termination without duplicating the CalcQtyAvailToPick call outside the standard procedure, which would introduce redundant database reads and maintenance risk.

Metadata

Metadata

Assignees

No one assigned

    Labels

    SCMGitHub request for SCM areaevent-requestRequest for adding an event

    Type

    No fields configured for Task.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions