summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHetashree Chauhan <hch@odoo.com>2018-11-12 10:02:00 +0000
committerSimon Lejeune <sle@openerp.com>2019-10-28 10:30:29 +0000
commit3116191e78bfd6b5cce8e92ae54e848965fd7811 (patch)
tree27c9b996cf713d7333a280fc649670f8e6fc4617
parent2bc65e9052bc53eb58e28b58f1f743c4da0ee1f0 (diff)
[IMP] mrp: log activity on parent manufacturing order.
Before commit: - If there are multi level production order, and user cancelled any one then, there is no activity logged on related production order. After this commit: - In multi level production order (i.e. one production order creates another production order to consume the raw material) if user cancelled raw material production order then, exception will be generated on main production order, so that user can easily get the idea that raw material for this production order is not available. [ADD] sale_mrp: add testcase for cancellation of the multilevel production orders task-1819526. closes odoo/odoo#28708 Signed-off-by: Simon Lejeune (sle) <sle@openerp.com>
-rw-r--r--addons/mrp/models/mrp_production.py21
-rw-r--r--addons/sale_mrp/tests/test_multistep_manufacturing.py41
2 files changed, 50 insertions, 12 deletions
diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py
index cb4a55f1e2f..98e2755e0e3 100644
--- a/addons/mrp/models/mrp_production.py
+++ b/addons/mrp/models/mrp_production.py
@@ -874,6 +874,10 @@ class MrpProduction(models.Model):
self.workorder_ids.filtered(lambda x: x.state not in ['done', 'cancel']).action_cancel()
finish_moves = self.move_finished_ids.filtered(lambda x: x.state not in ('done', 'cancel'))
raw_moves = self.move_raw_ids.filtered(lambda x: x.state not in ('done', 'cancel'))
+
+ # log an activity on Parent MO if child MO is cancelled.
+ if finish_moves:
+ self._log_downside_manufactured_quantity({finish_move: (self.product_uom_qty, 0.0) for finish_move in finish_moves}, cancel=True)
(finish_moves | raw_moves)._action_cancel()
picking_ids = self.picking_ids.filtered(lambda x: x.state not in ('done', 'cancel'))
picking_ids.action_cancel()
@@ -980,7 +984,7 @@ class MrpProduction(models.Model):
)
return super(MrpProduction, self).get_empty_list_help(help)
- def _log_downside_manufactured_quantity(self, moves_modification):
+ def _log_downside_manufactured_quantity(self, moves_modification, cancel=False):
def _keys_in_sorted(move):
""" sort by picking and the responsible for the product the
@@ -997,21 +1001,14 @@ class MrpProduction(models.Model):
def _render_note_exception_quantity_mo(rendering_context):
values = {
'production_order': self,
- 'order_exceptions': dict((key, d[key]) for d in rendering_context for key in d),
+ 'order_exceptions': rendering_context,
'impacted_pickings': False,
- 'cancel': False
+ 'cancel': cancel
}
return self.env.ref('mrp.exception_on_mo').render(values=values)
- documents = {}
- for move, (old_qty, new_qty) in moves_modification.items():
- document = self.env['stock.picking']._log_activity_get_documents(
- {move: (old_qty, new_qty)}, 'move_dest_ids', 'DOWN', _keys_in_sorted, _keys_in_groupby)
- for key, value in document.items():
- if documents.get(key):
- documents[key] += [value]
- else:
- documents[key] = [value]
+ documents = self.env['stock.picking']._log_activity_get_documents(moves_modification, 'move_dest_ids', 'DOWN', _keys_in_sorted, _keys_in_groupby)
+ documents = self.env['stock.picking']._less_quantities_than_expected_add_documents(moves_modification, documents)
self.env['stock.picking']._log_activity(_render_note_exception_quantity_mo, documents)
def _log_manufacture_exception(self, documents, cancel=False):
diff --git a/addons/sale_mrp/tests/test_multistep_manufacturing.py b/addons/sale_mrp/tests/test_multistep_manufacturing.py
index 73bb601f72a..3a13b58de59 100644
--- a/addons/sale_mrp/tests/test_multistep_manufacturing.py
+++ b/addons/sale_mrp/tests/test_multistep_manufacturing.py
@@ -85,3 +85,44 @@ class TestMultistepManufacturing(TestMrpCommon):
self.assertEqual(mo_procurement.location_dest_id.id, self.warehouse.lot_stock_id.id, "Destination location does not match.")
self.assertEqual(len(mo_procurement), 1, "No Procurement !")
+
+ def test_cancel_multilevel_manufacturing(self):
+ """ Testing for multilevel Manufacturing orders.
+ When user creates multi-level manufacturing orders,
+ and then cancelles child manufacturing order,
+ an activity should be generated on parent MO, to notify user that
+ demands from child MO has been cancelled.
+ """
+
+ product_form = Form(self.env['product.product'])
+ product_form.name = 'Screw'
+ self.product_screw = product_form.save()
+
+ # Add routes for manufacturing and make to order to the raw material product
+ with Form(self.product_raw) as p1:
+ p1.route_ids.clear()
+ p1.route_ids.add(self.warehouse_1.manufacture_pull_id.route_id)
+ p1.route_ids.add(self.warehouse_1.mto_pull_id.route_id)
+
+ # New BoM for raw material product, it will generate another Production order i.e. child Production order
+ bom_product_form = Form(self.env['mrp.bom'])
+ bom_product_form.product_id = self.product_raw
+ bom_product_form.product_tmpl_id = self.product_raw.product_tmpl_id
+ bom_product_form.product_qty = 1.0
+ with bom_product_form.bom_line_ids.new() as bom_line:
+ bom_line.product_id = self.product_screw
+ bom_line.product_qty = 5.0
+ self.bom_prod_manu = bom_product_form.save()
+
+ # create MO from sale order.
+ self.sale_order.action_confirm()
+ # Find child MO.
+ child_manufaturing = self.env['mrp.production'].search([('product_id', '=', self.product_raw.id)])
+ self.assertTrue((len(child_manufaturing.ids) == 1), 'Manufacturing order of raw material must be generated.')
+ # Cancel child MO.
+ child_manufaturing.action_cancel()
+ manufaturing_from_so = self.env['mrp.production'].search([('product_id', '=', self.product_manu.id)])
+ # Check if activity is generated or not on parent MO.
+ exception = self.env['mail.activity'].search([('res_model', '=', 'mrp.production'),
+ ('res_id', '=', manufaturing_from_so.id)])
+ self.assertEqual(len(exception.ids), 1, 'When user cancelled child manufacturing, exception must be generated on parent manufacturing.')