summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorsvs-odoo <svs@odoo.com>2019-06-24 07:32:08 +0000
committersvs-odoo <svs@odoo.com>2019-07-31 12:37:39 +0000
commitb499c3308cd036e464578045996b63cfa877aa92 (patch)
treea8b182136066f30e433bbc8d98ca9ee6d4584ba6 /addons
parent3d4c0f92af86e534bc44ed48eb0ebf2ade3f7a92 (diff)
[IMP] mrp: can delete active MO
Before this commit, you can delete only canceled MO. Now, if you want to delete a non-canceled MO, it will try to cancel it then to unlink it. Task #1969034 closes odoo/odoo#34026 Signed-off-by: Arnold Moyaux <amoyaux@users.noreply.github.com>
Diffstat (limited to 'addons')
-rw-r--r--addons/mrp/models/mrp_production.py13
-rw-r--r--addons/mrp/models/mrp_workorder.py11
-rw-r--r--addons/mrp/tests/test_cancel_mo.py27
-rw-r--r--addons/mrp/wizard/change_production_qty.py4
-rw-r--r--addons/mrp/wizard/mrp_product_produce.py2
5 files changed, 51 insertions, 6 deletions
diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py
index f336f10293c..90783f311d1 100644
--- a/addons/mrp/models/mrp_production.py
+++ b/addons/mrp/models/mrp_production.py
@@ -468,8 +468,17 @@ class MrpProduction(models.Model):
return super(MrpProduction, self).create(values)
def unlink(self):
- if any(production.state != 'cancel' for production in self):
- raise UserError(_('Cannot delete a manufacturing order not in cancel state'))
+ if any(production.state == 'done' for production in self):
+ raise UserError(_('Cannot delete a manufacturing order in done state.'))
+ self.action_cancel()
+ not_cancel = self.filtered(lambda m: m.state != 'cancel')
+ if not_cancel:
+ productions_name = ', '.join([prod.display_name for prod in not_cancel])
+ raise UserError(_('%s cannot be deleted. Try to cancel them before.') % productions_name)
+
+ workorders_to_delete = self.workorder_ids.filtered(lambda wo: wo.state != 'done')
+ if workorders_to_delete:
+ workorders_to_delete.unlink()
return super(MrpProduction, self).unlink()
def action_toggle_is_locked(self):
diff --git a/addons/mrp/models/mrp_workorder.py b/addons/mrp/models/mrp_workorder.py
index 03ff2c69bcf..667ccc32fa5 100644
--- a/addons/mrp/models/mrp_workorder.py
+++ b/addons/mrp/models/mrp_workorder.py
@@ -202,6 +202,11 @@ class MrpWorkorder(models.Model):
def name_get(self):
return [(wo.id, "%s - %s - %s" % (wo.production_id.name, wo.product_id.name, wo.name)) for wo in self]
+ def unlink(self):
+ # Removes references to workorder to avoid Validation Error
+ (self.mapped('move_raw_ids') | self.mapped('move_finished_ids')).write({'workorder_id': False})
+ return super(MrpWorkorder, self).unlink()
+
@api.depends('production_id.product_qty', 'qty_produced')
def _compute_is_produced(self):
for order in self:
@@ -563,8 +568,10 @@ class MrpWorkorderLine(models.Model):
_inherit = ["mrp.abstract.workorder.line"]
_description = "Workorder move line"
- raw_workorder_id = fields.Many2one('mrp.workorder', 'Component for Workorder')
- finished_workorder_id = fields.Many2one('mrp.workorder', 'Finished Product for Workorder')
+ raw_workorder_id = fields.Many2one('mrp.workorder', 'Component for Workorder',
+ ondelete='cascade')
+ finished_workorder_id = fields.Many2one('mrp.workorder', 'Finished Product for Workorder',
+ ondelete='cascade')
@api.model
def _get_raw_workorder_inverse_name(self):
diff --git a/addons/mrp/tests/test_cancel_mo.py b/addons/mrp/tests/test_cancel_mo.py
index 629f1c2d824..fdbfb50531f 100644
--- a/addons/mrp/tests/test_cancel_mo.py
+++ b/addons/mrp/tests/test_cancel_mo.py
@@ -115,3 +115,30 @@ class TestMrpCancelMO(TestMrpCommon):
"Due to 'post_inventory', a move finished must stay in done state")
self.assertEqual(manufacturing_order.move_finished_ids[1].state, 'cancel',
"The other move finished is cancelled like its MO.")
+
+ def test_unlink_mo(self):
+ """ Try to unlink a Manufacturing Order, and check it's possible or not
+ depending of the MO state (must be in cancel state to be unlinked, but
+ the unlink method will try to cancel MO before unlink them).
+ """
+ # Case #1: Create MO, do nothing and try to unlink it (can be deleted)
+ manufacturing_order = self.generate_mo()[0]
+ self.assertEqual(manufacturing_order.exists().state, 'confirmed')
+ manufacturing_order.unlink()
+ # Check the MO is deleted.
+ self.assertEqual(manufacturing_order.exists().state, False)
+
+ # Case #2: Create MO, make and post some production, then try to unlink
+ # it (cannot be deleted)
+ manufacturing_order = self.generate_mo()[0]
+ # Produce some quantity (not all to avoid to done the MO when post inventory)
+ produce_form = Form(self.env['mrp.product.produce'].with_context(active_id=manufacturing_order.id))
+ produce_form.qty_producing = 2
+ produce = produce_form.save()
+ produce.do_produce()
+ # Post Inventory
+ manufacturing_order.post_inventory()
+ # Unlink the MO must raises an UserError since it cannot be really cancelled
+ self.assertEqual(manufacturing_order.exists().state, 'progress')
+ with self.assertRaises(UserError):
+ manufacturing_order.unlink()
diff --git a/addons/mrp/wizard/change_production_qty.py b/addons/mrp/wizard/change_production_qty.py
index d2fad9cc431..cc2b8ff4ff4 100644
--- a/addons/mrp/wizard/change_production_qty.py
+++ b/addons/mrp/wizard/change_production_qty.py
@@ -10,8 +10,8 @@ class ChangeProductionQty(models.TransientModel):
_name = 'change.production.qty'
_description = 'Change Production Qty'
- # TDE FIXME: add production_id field
- mo_id = fields.Many2one('mrp.production', 'Manufacturing Order', required=True)
+ mo_id = fields.Many2one('mrp.production', 'Manufacturing Order',
+ required=True, ondelete='cascade')
product_qty = fields.Float(
'Quantity To Produce',
digits='Product Unit of Measure', required=True)
diff --git a/addons/mrp/wizard/mrp_product_produce.py b/addons/mrp/wizard/mrp_product_produce.py
index d4f402a16af..1c8c26fbd96 100644
--- a/addons/mrp/wizard/mrp_product_produce.py
+++ b/addons/mrp/wizard/mrp_product_produce.py
@@ -50,6 +50,8 @@ class MrpProductProduce(models.TransientModel):
'raw_product_produce_id', string='Components')
finished_workorder_line_ids = fields.One2many('mrp.product.produce.line',
'finished_product_produce_id', string='By-products')
+ production_id = fields.Many2one('mrp.production', 'Manufacturing Order',
+ required=True, ondelete='cascade')
@api.depends('qty_producing')
def _compute_pending_production(self):