[Main]- Production order can be deleted with registered unconsumed warehouse picks - #11261
Conversation
| end; | ||
|
|
||
| local procedure ConfirmDeletion() | ||
| internal procedure CheckPickedQtyBeforeDeletion() |
There was a problem hiding this comment.
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() |
There was a problem hiding this comment.
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.'; |
There was a problem hiding this comment.
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.'; |
There was a problem hiding this comment.
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
| 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; |
There was a problem hiding this comment.
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.
| 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); |
There was a problem hiding this comment.
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
Good Sense Reviewer - Round 1Recommendation: Request ChangesWhat this PR doesThis 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 fitFit: 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. SuggestionsS1 (🔴 High): Account for returned picked quantity Risk assessment and necessityRisk: 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.
|
Workitem Bug 647854: [All-E] [Repair Item] Production order can be deleted with registered unconsumed warehouse picks
Fixes AB#647854