[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>
This commit is contained in:
Hetashree Chauhan
2019-10-28 10:30:29 +00:00
committed by Simon Lejeune
parent 2bc65e9052
commit 3116191e78
2 changed files with 50 additions and 12 deletions
+9 -12
View File
@@ -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):
@@ -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.')