Skip to content

[Main]- Production order can be deleted with registered unconsumed warehouse picks - #11261

Open
DeepsShukla wants to merge 1 commit into
mainfrom
bugs/Bug-647854-Production-order-can-be-delete-with-registeredPick-Main
Open

[Main]- Production order can be deleted with registered unconsumed warehouse picks#11261
DeepsShukla wants to merge 1 commit into
mainfrom
bugs/Bug-647854-Production-order-can-be-delete-with-registeredPick-Main

Conversation

@DeepsShukla

@DeepsShukla DeepsShukla commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Workitem Bug 647854: [All-E] [Repair Item] Production order can be deleted with registered unconsumed warehouse picks

Fixes AB#647854

@DeepsShukla
DeepsShukla requested a review from a team September 9, 2026 10:30
@DeepsShukla
DeepsShukla requested a review from a team as a code owner September 9, 2026 10:30
@github-actions github-actions Bot added this to the Version 30.0 milestone Sep 9, 2026
@github-actions github-actions Bot added the Team: SCM GitHub request for SCM area label Sep 9, 2026
end;

local procedure ConfirmDeletion()
internal procedure CheckPickedQtyBeforeDeletion()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟡\ Medium\ Severity\ —\ Breaking\ Changes}$

Replacing the previous confirm-based deletion check with a hard Error() is a user-visible breaking change. Before this change, users could still proceed with deletion after acknowledging the warning, and locations whose production warehouse handling was configured as No Warehouse Handling bypassed the check entirely. Preserve that compatibility path or stage the stricter behavior as an explicit migration, otherwise existing production-order, line, and component deletion flows will start failing immediately.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

end;

local procedure ConfirmDeletion()
internal procedure CheckPickedQtyBeforeDeletion()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟡\ Medium\ Severity\ —\ Breaking\ Changes}$

Replacing the previous confirm-based deletion check with a hard Error() is a user-visible breaking change. Before this change, users could still proceed with deletion after acknowledging the warning, and locations whose production warehouse handling was configured as No Warehouse Handling bypassed the check entirely. Preserve that compatibility path or stage the stricter behavior as an explicit migration, otherwise existing production-order, line, and component deletion flows will start failing immediately.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

Text99000009: Label 'Automatic reservation is not possible.\Do you want to reserve items manually?';
#pragma warning restore AA0074
ConfirmDeleteQst: Label '%1 = %2 is greater than %3 = %4. If you delete the %5, the items will remain in the operation area until you put them away.\Any related item tracking information defined during the pick process will be deleted.\Do you still want to delete the %5?', Comment = '%1 = FieldCaption("Qty. Picked"), %2 = "Qty. Picked", %3 = Qty. Posted, %4 = ("Expected Quantity" - "Remaining Quantity"), %5 = TableCaption';
CannotDeleteWithPickedQtyErr: Label 'You cannot delete the production order because one or more components have a picked quantity that has not been consumed. Consume or return the picked quantity before deleting the production order.';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟡\ Medium\ Severity\ —\ Error\ Handling}$

The replacement error for picked-quantity deletion is hard-coded to "You cannot delete the production order..." even though this path is deleting a Prod. Order Component record. That gives the user the wrong operation name in the error dialog. Use component-specific text here, or parameterize the helper so the message can reflect the record actually being deleted.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

Text99000009: Label 'Automatic reservation is not possible.\Do you want to reserve items manually?';
#pragma warning restore AA0074
ConfirmDeleteQst: Label '%1 = %2 is greater than %3 = %4. If you delete the %5, the items will remain in the operation area until you put them away.\Any related item tracking information defined during the pick process will be deleted.\Do you still want to delete the %5?', Comment = '%1 = FieldCaption("Qty. Picked"), %2 = "Qty. Picked", %3 = Qty. Posted, %4 = ("Expected Quantity" - "Remaining Quantity"), %5 = TableCaption';
CannotDeleteWithPickedQtyErr: Label 'You cannot delete the production order because one or more components have a picked quantity that has not been consumed. Consume or return the picked quantity before deleting the production order.';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟡\ Medium\ Severity\ —\ Error\ Handling}$

The new CannotDeleteWithPickedQtyErr text says the user cannot delete "the production order", but this label is raised from Prod. Order Component deletion and is also reused by the new Prod. Order Line deletion path. That makes the blocked operation read incorrectly for component and line deletes. Tailor the message to the actual delete target, or pass the caller caption into the shared check so each path reports the right entity.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

Comment on lines +1841 to +1847
ProdOrderComponent.SetRange(Status, Status);
ProdOrderComponent.SetRange("Prod. Order No.", "Prod. Order No.");
ProdOrderComponent.SetRange("Prod. Order Line No.", "Line No.");
if ProdOrderComponent.FindSet() then
repeat
ProdOrderComponent.CheckPickedQtyBeforeDeletion();
until ProdOrderComponent.Next() = 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟡\ Medium\ Severity\ —\ Performance}$

The production-order-line deletion scan loops over every component on the line even though only components with picked quantity can fail the new check. Filter "Qty. Picked (Base)" before FindSet() so the loop only evaluates rows that can actually block deletion.

Suggested change
ProdOrderComponent.SetRange(Status, Status);
ProdOrderComponent.SetRange("Prod. Order No.", "Prod. Order No.");
ProdOrderComponent.SetRange("Prod. Order Line No.", "Line No.");
if ProdOrderComponent.FindSet() then
repeat
ProdOrderComponent.CheckPickedQtyBeforeDeletion();
until ProdOrderComponent.Next() = 0;
ProdOrderComponent.SetRange(Status, Status);
ProdOrderComponent.SetRange("Prod. Order No.", "Prod. Order No.");
ProdOrderComponent.SetRange("Prod. Order Line No.", "Line No.");
ProdOrderComponent.SetFilter("Qty. Picked (Base)", '>%1', 0);
if ProdOrderComponent.FindSet() then
repeat
ProdOrderComponent.CheckPickedQtyBeforeDeletion();
until ProdOrderComponent.Next() = 0;

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

ProdOrderComponent: Record "Prod. Order Component";
Confirmed: Boolean;
begin
ProdOrderComponent.SetRange(Status, Rec.Status);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟡\ Medium\ Severity\ —\ Performance}$

The production-order deletion scan iterates every component for the order even though components with zero picked quantity can be excluded up front. Add a SetFilter("Qty. Picked (Base)", '>%1', 0) before FindSet() so rows that cannot trigger CheckPickedQtyBeforeDeletion() never cross the AL loop.

Suggested fix (apply manually — could not be anchored as a one-click suggestion):

        ProdOrderComponent.SetRange(Status, Rec.Status);
        ProdOrderComponent.SetRange("Prod. Order No.", "No.");
        ProdOrderComponent.SetFilter("Qty. Picked (Base)", '>%1', 0);
        if ProdOrderComponent.FindSet() then
            repeat
                ProdOrderComponent.CheckPickedQtyBeforeDeletion();
            until ProdOrderComponent.Next() = 0;

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 1

Recommendation: Request Changes

What this PR does

This change blocks released production order, production order line, and component deletion when a component has picked quantity that has not been consumed. The new check runs before header deletion cascades, and the direct line and component paths are covered too. Using base quantities is the right direction, and the new tests cover the blocked header, line, and component paths. However, the guard still uses cumulative picked quantity only, so it does not prove the picked stock is still outstanding after a return movement.

Problem-solution fit

Fit: Partial

The change fixes the main reported failure by preventing deletion while registered picked quantity is still unconsumed. It does not fully match the requested behavior because a returned picked quantity can still leave the stored picked quantity higher than consumed quantity.

Suggestions

S1 (🔴 High): Account for returned picked quantity
The check uses cumulative Qty. Picked (Base) as if every unconsumed pick is still in the operation area. A supported return movement can move stock out without reducing this field, so deletion can still be blocked after the quantity is returned. Base the guard on outstanding picked quantity, or update the value this check uses when the return is registered.

Risk assessment and necessity

Risk: The changed area protects manufacturing production orders that use warehouse picks. If the guard is too weak, warehouse entries and bin content can be left without the production document needed for reconciliation. If it is too broad, users can be blocked from deleting an order after they have already moved the stock back through a supported return flow. The tests cover the new blocked deletion paths, but not the return/success path.

Necessity: The change is needed because the old confirmation allowed a released production order to be deleted after a registered pick but before consumption. The scope is focused on the right delete paths, but it needs to recognize when picked quantity is no longer outstanding.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=11261 round=1 by=alexei-dobriansky at=2026-09-09T12:04:44Z lastSha=333c7894b10f213f2778ddf4519119ec00e5bbc3 reviewKey=e3047268b5b4aa92d91b706ad36997b9c27ca77a62173b3583bef9dc5da9212c suggestions=S1@d50b13ad

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Team: SCM GitHub request for SCM area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants