diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py
index 2387ebc26a6..84af8642414 100644
--- a/addons/mrp/models/mrp_production.py
+++ b/addons/mrp/models/mrp_production.py
@@ -222,6 +222,13 @@ class MrpProduction(models.Model):
picking_ids = fields.Many2many('stock.picking', compute='_compute_picking_ids', string='Picking associated to this manufacturing order')
delivery_count = fields.Integer(string='Delivery Orders', compute='_compute_picking_ids')
confirm_cancel = fields.Boolean(compute='_compute_confirm_cancel')
+ consumption = fields.Selection([
+ ('strict', 'Strict'),
+ ('flexible', 'Flexible')],
+ required=True,
+ readonly=True,
+ default='strict',
+ )
mrp_production_child_count = fields.Integer("Number of generated MO", compute='_compute_mrp_production_child_count')
mrp_production_source_count = fields.Integer("Number of source MO", compute='_compute_mrp_production_source_count')
@@ -529,7 +536,7 @@ class MrpProduction(models.Model):
if production.workorder_ids and not self.env.context.get('force_date', False):
raise UserError(_('You cannot move a planned manufacturing order.'))
if 'move_raw_ids' in vals and production.state != 'draft':
- production.move_raw_ids.filtered(lambda m: m.state == 'draft')._action_confirm()
+ production._autoconfirm_production()
if not production.routing_id and vals.get('date_planned_start') and not vals.get('date_planned_finished'):
new_date_planned_start = fields.Datetime.to_datetime(vals.get('date_planned_start'))
if not production.date_planned_finished or new_date_planned_start >= production.date_planned_finished:
@@ -711,6 +718,22 @@ class MrpProduction(models.Model):
return 'assigned'
return 'confirmed'
+ def _autoconfirm_production(self):
+ """Automatically run `action_confirm` on `self`.
+
+ If the production has one of its move was added after the initial call
+ to `action_confirm`.
+ """
+ moves_to_confirm = self.env['stock.move']
+ for production in self:
+ if production.state in ('done', 'cancel'):
+ continue
+ moves_to_confirm |= (production.move_raw_ids | production.move_finished_ids).filtered(
+ lambda move: move.state == 'draft' and move.additional
+ )
+ if moves_to_confirm:
+ moves_to_confirm._action_confirm()
+
def action_view_mrp_production_childs(self):
self.ensure_one()
mrp_production_ids = self.procurement_group_id.stock_move_ids.created_production_id.ids
@@ -754,6 +777,7 @@ class MrpProduction(models.Model):
def action_confirm(self):
self._check_company()
for production in self:
+ production.consumption = production.bom_id.consumption
if not production.move_raw_ids:
raise UserError(_("Add some materials to consume before marking this MO as to do."))
for move_raw in production.move_raw_ids:
diff --git a/addons/mrp/models/stock_move.py b/addons/mrp/models/stock_move.py
index d0d9082db22..8485dd64f98 100644
--- a/addons/mrp/models/stock_move.py
+++ b/addons/mrp/models/stock_move.py
@@ -151,8 +151,11 @@ class StockMove(models.Model):
defaults = super(StockMove, self).default_get(fields_list)
if self.env.context.get('default_raw_material_production_id'):
production_id = self.env['mrp.production'].browse(self.env.context['default_raw_material_production_id'])
- if production_id.state == 'done':
- defaults['state'] = 'done'
+ if production_id.state in ('confirmed', 'done'):
+ if production_id.state == 'confirmed':
+ defaults['state'] = 'draft'
+ else:
+ defaults['state'] = 'done'
defaults['product_uom_qty'] = 0.0
defaults['additional'] = True
return defaults
diff --git a/addons/mrp/tests/test_workorder_operation.py b/addons/mrp/tests/test_workorder_operation.py
index a40de34a204..d6acdf1db76 100644
--- a/addons/mrp/tests/test_workorder_operation.py
+++ b/addons/mrp/tests/test_workorder_operation.py
@@ -1791,3 +1791,37 @@ class TestRoutingAndKits(SavepointCase):
wo1 = mo.workorder_ids[0]
lines = wo1.raw_workorder_line_ids
self.assertEqual(lines.product_id, add_product)
+
+ def test_add_move_2(self):
+ """ Make a production using multi step routing. Add an additional move
+ on a specific operation and check that the produce is consumed into the
+ right workorder. """
+ self.bom_finished1.consumption = 'flexible'
+ add_product = self.env['product.product'].create({
+ 'name': 'Additional',
+ })
+ mo_form = Form(self.env['mrp.production'])
+ mo_form.product_id = self.finished1
+ mo_form.bom_id = self.bom_finished1
+ mo_form.product_qty = 10.0
+ mo = mo_form.save()
+ mo.action_confirm()
+ mo_form = Form(mo)
+ with mo_form.move_raw_ids.new() as move:
+ move.name = mo.name
+ move.product_id = add_product
+ move.product_uom = add_product.uom_id
+ move.location_id = mo.location_src_id
+ move.location_dest_id = mo.production_location_id
+ move.product_uom_qty = 2
+ move.operation_id = mo.routing_id.operation_ids[0]
+ mo = mo_form.save()
+ new_move = mo.move_raw_ids.filtered(lambda move: move.additional)
+ self.assertEqual(len(mo.move_raw_ids), 3)
+ self.assertEqual(len(new_move), 1)
+ self.assertEqual(mo.move_raw_ids.mapped('state'), ['confirmed'] * 3)
+ mo.button_plan()
+ self.assertEqual(len(mo.workorder_ids), 3)
+ wo1 = mo.workorder_ids[0]
+ lines = wo1.raw_workorder_line_ids
+ self.assertEqual(lines.product_id, add_product)
diff --git a/addons/mrp/views/mrp_production_views.xml b/addons/mrp/views/mrp_production_views.xml
index 75c140d8d4b..803e29c28e1 100644
--- a/addons/mrp/views/mrp_production_views.xml
+++ b/addons/mrp/views/mrp_production_views.xml
@@ -73,6 +73,7 @@