diff options
| author | svs-odoo <svs@odoo.com> | 2019-06-24 07:32:08 +0000 |
|---|---|---|
| committer | svs-odoo <svs@odoo.com> | 2019-07-31 12:37:39 +0000 |
| commit | b499c3308cd036e464578045996b63cfa877aa92 (patch) | |
| tree | a8b182136066f30e433bbc8d98ca9ee6d4584ba6 /addons | |
| parent | 3d4c0f92af86e534bc44ed48eb0ebf2ade3f7a92 (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.py | 13 | ||||
| -rw-r--r-- | addons/mrp/models/mrp_workorder.py | 11 | ||||
| -rw-r--r-- | addons/mrp/tests/test_cancel_mo.py | 27 | ||||
| -rw-r--r-- | addons/mrp/wizard/change_production_qty.py | 4 | ||||
| -rw-r--r-- | addons/mrp/wizard/mrp_product_produce.py | 2 |
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): |
