[FIX] mrp: fully cancel MO even if no component

When cancelling a manufacturing order that does not include any
component, the associated moves won't be cancelled.

To reproduce the issue:
1. Create a storable product P
2. Create & Confirm a MO for 1 x P
3. Cancel the MO
4. Consult the form page of P

Error: The forecasted quantity of P is 1 instead of 0

The finished move associated to the MO hasn't been cancelled. Since [1],
we have the possibility to process MOs without any component, so the
cancellation process shouldn't be bypassed anymore.

[1] bf5e1debf9

OPW-2691422

closes odoo/odoo#80407

X-original-commit: 2adff866a598fc8fb872fb8127875fbb7cc7335c
Signed-off-by: Arnold Moyaux <arm@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
This commit is contained in:
Adrien Widart
2021-11-25 15:19:53 +00:00
parent 5716f6fabf
commit 42331b3fb5
3 changed files with 19 additions and 8 deletions
+1 -4
View File
@@ -456,7 +456,7 @@ class MrpProduction(models.Model):
for production in self:
if not production.state:
production.state = 'draft'
elif production.state == 'cancel' or (production.move_raw_ids and all(move.state == 'cancel' for move in production.move_raw_ids)):
elif production.state == 'cancel' or (production.move_finished_ids and all(move.state == 'cancel' for move in production.move_finished_ids)):
production.state = 'cancel'
elif production.state == 'done' or (production.move_raw_ids and all(move.state in ('cancel', 'done') for move in production.move_raw_ids)):
production.state = 'done'
@@ -1359,9 +1359,6 @@ class MrpProduction(models.Model):
def action_cancel(self):
""" Cancels production order, unfinished stock moves and set procurement
orders in exception """
if not self.move_raw_ids:
self.state = 'cancel'
return True
self._action_cancel()
return True
+3 -4
View File
@@ -312,10 +312,9 @@ class StockMove(models.Model):
def _action_cancel(self):
res = super(StockMove, self)._action_cancel()
for production in self.mapped('raw_material_production_id'):
if production.state != 'cancel':
continue
production._action_cancel()
mo_to_cancel = self.mapped('raw_material_production_id').filtered(lambda p: all(m.state == 'cancel' for m in p.move_raw_ids))
if mo_to_cancel:
mo_to_cancel._action_cancel()
return res
def _prepare_move_split_vals(self, qty):
+15
View File
@@ -101,3 +101,18 @@ class TestMrpCancelMO(TestMrpCommon):
self.assertEqual(manufacturing_order.exists().state, 'progress')
with self.assertRaises(UserError):
manufacturing_order.unlink()
def test_cancel_mo_without_component(self):
product_form = Form(self.env['product.product'])
product_form.name = "SuperProduct"
product = product_form.save()
mo_form = Form(self.env['mrp.production'])
mo_form.product_id = product
mo = mo_form.save()
mo.action_confirm()
mo.action_cancel()
self.assertEqual(mo.move_finished_ids.state, 'cancel')
self.assertEqual(mo.state, 'cancel')