[FIX] stock: display backorder wizard

To reproduce the issue:
1. Create a planned receipt with two lines:
   - 10 x P
   - 10 x P
2. Confirm and set the done quantities:
   - 12 x P
   - 8 x P
3. Validate

Error: The receipt is directly processed and a backorder is created.
In case a backorder could be created, we should first display the
wizard that asks for a user's confirmation

When checking for the backorder wizard, we compare, for each
**product**, the sum of the demands with the sum of the done
quantities. In the above use case, we will have `10 + 10 == 12 + 8`,
so we don't display the wizard.

However, while processing the SMs, this is different. For the second
SM, we will set its demand to 8, create a third SM with a demand
equal to 2 and create a new picking (the backorder) for this new SM.
This behaviour is legit, the backorder creation makes sense. This is
why this commit fixes the wizard display conditions.

OPW-3373255

closes odoo/odoo#138863

X-original-commit: 5affa219d8add6f256030b699f61ddf77a928c82
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Signed-off-by: Adrien Widart (awt) <awt@odoo.com>
This commit is contained in:
Adrien Widart (awt)
2023-10-17 06:25:12 +00:00
parent 65f0c7bc9a
commit 55f461060e
2 changed files with 36 additions and 9 deletions
+3 -9
View File
@@ -1245,16 +1245,10 @@ class Picking(models.Model):
for picking in self:
if picking.picking_type_id.create_backorder != 'ask':
continue
quantity_todo = {}
quantity_done = {}
for move in picking.move_ids.filtered(lambda m: m.state != "cancel"):
quantity_todo.setdefault(move.product_id.id, 0)
quantity_done.setdefault(move.product_id.id, 0)
quantity_todo[move.product_id.id] += move.product_uom._compute_quantity(move.product_uom_qty, move.product_id.uom_id, rounding_method='HALF-UP')
quantity_done[move.product_id.id] += move.product_uom._compute_quantity(move.quantity_done, move.product_id.uom_id, rounding_method='HALF-UP')
if any(
float_compare(quantity_done[x], quantity_todo.get(x, 0), precision_digits=prec,) == -1
for x in quantity_done
float_compare(move.quantity_done, move.product_uom_qty, precision_digits=prec) < 0
for move in picking.move_ids
if move.state != 'cancel'
):
backorder_pickings |= picking
return backorder_pickings
+33
View File
@@ -2643,3 +2643,36 @@ class TestStockFlowPostInstall(TestStockCommon):
delivery.button_validate()
self.assertEqual(sn.last_delivery_partner_id, partner)
def test_several_sm_with_same_product_and_backorders(self):
picking = self.env['stock.picking'].create({
'picking_type_id': self.picking_type_in,
'location_id': self.supplier_location,
'location_dest_id': self.stock_location,
})
move01, move02 = self.env['stock.move'].create([{
'name': self.productA.name,
'product_id': self.productA.id,
'product_uom_qty': 10,
'product_uom': self.productA.uom_id.id,
'description_picking': desc,
'picking_id': picking.id,
'location_id': self.supplier_location,
'location_dest_id': self.stock_location,
} for desc in ['Lorem', 'Ipsum']])
picking.action_confirm()
move01.quantity_done = 12
move02.quantity_done = 8
res = picking.button_validate()
self.assertIsInstance(res, dict)
self.assertEqual(res.get('res_model'), 'stock.backorder.confirmation')
wizard = Form(self.env[res['res_model']].with_context(res['context'])).save()
wizard.process()
backorder = picking.backorder_ids
self.assertEqual(backorder.move_ids.product_uom_qty, 2)
self.assertEqual(backorder.move_ids.description_picking, 'Ipsum')