Skip to content

Commit

Permalink
[FIX] stock_picking_batch: ensure batch consistency
Browse files Browse the repository at this point in the history
When processing a batch without backorder, if a picking is not fully
done, it will be removed from the batch

To reproduce the issue:
1. Create two delivery pickings P1 et P2 with demands = 5
2. Have the quantity in the stock
3. Add both to a batch and confirm it
4. Set the done quantity on P1
5. On P2, set a done quantity to 4
6. Process the batch without backorder

Error: Both pickings are done, and so does the batch, but P2 is not
linked to that batch anymore

When processing the batch, we will call `button_validate` on the
pickings recordset
https://github.com/odoo/odoo/blob/213b74be16cecc50e6e99c00f47786a9cbf327a8/addons/stock_picking_batch/models/stock_picking_batch.py#L252-L258
Later on, there is an override of `StockPicking._action_done` in the
batch module. In this override, once we have called `super`, we then
ensure that all pickings of the batch are done, else we detach some
of them:
https://github.com/odoo/odoo/blob/213b74be16cecc50e6e99c00f47786a9cbf327a8/addons/stock_picking_batch/models/stock_picking_batch.py#L252-L258
But here is the issue: as mentionned above, we first call
`button_validate` on pickings recordset. In this method, we will
call `StockPicking._action_done` two times:
https://github.com/odoo/odoo/blob/ca168f7fbcbb8a300a8fa0b46f79a6c116b5aa93/addons/stock/models/stock_picking.py#L1088-L1089
The first time, for the pickings without the backorder option (P2 in
the above use case), and the second time, for the pickings with the
backorder option (P1 in the above use case). As a result, during the
first call, we reach the override in batch module, and of course, P1 is
not yet processed (it will be done during the second call of
`_action_done`). Therefore, we think there is an inconsistency, and we
detach P2.

OPW-3346255

closes odoo#132037

X-original-commit: c281728
Signed-off-by: William Henrotin (whe) <[email protected]>
Signed-off-by: Adrien Widart (awt) <[email protected]>
  • Loading branch information
adwid committed Aug 16, 2023
1 parent 4ae61ce commit 9a5df70
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
6 changes: 4 additions & 2 deletions addons/stock_picking_batch/models/stock_picking.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,10 @@ def action_confirm(self):
picking._find_auto_batch()
return res

def _action_done(self):
res = super()._action_done()
def button_validate(self):
res = super().button_validate()
if res is not True:
return res
to_assign_ids = set()
if self and self.env.context.get('pickings_to_detach'):
self.env['stock.picking'].browse(self.env.context['pickings_to_detach']).batch_id = False
Expand Down
27 changes: 27 additions & 0 deletions addons/stock_picking_batch/tests/test_batch_picking.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,33 @@ def test_remove_all_transfers_from_confirmed_batch(self):
self.batch.write({'picking_ids': [[5, 0, 0]]})
self.assertEqual(self.batch.state, 'cancel', 'Batch Transfers should be cancelled when there are no transfers.')

def test_backorder_on_one_picking(self):
"""
Two pickings. The first only is fully done. The second one is not. The
user validates the batch without any backorder. Both pickings should be
done and still part of the batch
"""
self.env['stock.quant']._update_available_quantity(self.productA, self.stock_location, 10.0)
self.env['stock.quant']._update_available_quantity(self.productB, self.stock_location, 8.0)

self.batch.action_confirm()

self.batch.action_assign()
self.picking_client_1.move_ids.quantity_done = 10
self.picking_client_2.move_ids.quantity_done = 7

action = self.batch.action_done()
wizard = Form(self.env[action['res_model']].with_context(action['context'])).save()
wizard.process_cancel_backorder()

self.assertEqual(self.picking_client_1.state, 'done')
self.assertEqual(self.picking_client_2.state, 'done')
self.assertEqual(self.batch.picking_ids, self.picking_client_1 | self.picking_client_2)
self.assertRecordValues(self.batch.move_ids.sorted('id'), [
{'product_id': self.productA.id, 'product_uom_qty': 10.0, 'quantity_done': 10.0, 'state': 'done'},
{'product_id': self.productB.id, 'product_uom_qty': 7.0, 'quantity_done': 7.0, 'state': 'done'},
{'product_id': self.productB.id, 'product_uom_qty': 3.0, 'quantity_done': 0.0, 'state': 'cancel'},
])

@tagged('-at_install', 'post_install')
class TestBatchPicking02(TransactionCase):
Expand Down

0 comments on commit 9a5df70

Please sign in to comment.