[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:
committed by
Simon Lejeune
parent
2bc65e9052
commit
3116191e78
@@ -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.')
|
||||
|
||||
Reference in New Issue
Block a user