diff --git a/addons/mrp/models/stock_move.py b/addons/mrp/models/stock_move.py index 5205a2c81b458395b153c478544661a5308007cf..5e9d36c9773d999af64c14b723fbc2f6ef4e5e9c 100644 --- a/addons/mrp/models/stock_move.py +++ b/addons/mrp/models/stock_move.py @@ -243,11 +243,25 @@ class StockMove(models.Model): return defaults def write(self, vals): - if 'product_uom_qty' in vals and 'move_line_ids' in vals: - # first update lines then product_uom_qty as the later will unreserve - # so possibly unlink lines - move_line_vals = vals.pop('move_line_ids') - super().write({'move_line_ids': move_line_vals}) + if 'product_uom_qty' in vals: + if 'move_line_ids' in vals: + # first update lines then product_uom_qty as the later will unreserve + # so possibly unlink lines + move_line_vals = vals.pop('move_line_ids') + super().write({'move_line_ids': move_line_vals}) + procurement_requests = [] + for move in self: + if move.raw_material_production_id.state != 'confirmed' \ + or not float_is_zero(move.product_uom_qty, precision_rounding=move.product_uom.rounding) \ + or move.procure_method != 'make_to_order': + continue + values = move._prepare_procurement_values() + origin = move._prepare_procurement_origin() + procurement_requests.append(self.env['procurement.group'].Procurement( + move.product_id, vals['product_uom_qty'], move.product_uom, + move.location_id, move.rule_id and move.rule_id.name or "/", + origin, move.company_id, values)) + self.env['procurement.group'].run(procurement_requests) return super().write(vals) def _action_assign(self): diff --git a/addons/mrp/tests/test_procurement.py b/addons/mrp/tests/test_procurement.py index f2408edf653ff1f3258fc634f83900a98a05051a..3931009d23633409afdb76f1a4b85ac6d5999430 100644 --- a/addons/mrp/tests/test_procurement.py +++ b/addons/mrp/tests/test_procurement.py @@ -751,3 +751,38 @@ class TestProcurement(TestMrpCommon): {'product_qty': 1, 'bom_id': bom01.id, 'picking_type_id': manu_operation01.id, 'location_dest_id': stock_location01.id}, {'product_qty': 2, 'bom_id': bom02.id, 'picking_type_id': manu_operation02.id, 'location_dest_id': stock_location02.id}, ]) + + def test_pbm_and_additionnal_components(self): + """ + 2-steps manufacturring. + When adding a new component to a confirmed MO, it should add an SM in + the PBM picking. Also, it should be possible to define the to-consume + qty of the new line even if the MO is locked + """ + warehouse = self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1) + warehouse.manufacture_steps = 'pbm' + + mo_form = Form(self.env['mrp.production']) + mo_form.bom_id = self.bom_4 + mo = mo_form.save() + mo.action_confirm() + + if not mo.is_locked: + mo.action_toggle_is_locked() + + with Form(mo) as mo_form: + with mo_form.move_raw_ids.new() as raw_line: + raw_line.product_id = self.product_2 + raw_line.product_uom_qty = 2.0 + + move_vals = mo._get_move_raw_values(self.product_10, 0, self.product_2.uom_id) + mo.move_raw_ids = [(0, 0, move_vals)] + mo.move_raw_ids[-1].product_uom_qty = 10.0 + + expected_vals = [ + {'product_id': self.product_1.id, 'product_uom_qty': 1.0}, + {'product_id': self.product_2.id, 'product_uom_qty': 2.0}, + {'product_id': self.product_10.id, 'product_uom_qty': 10.0}, + ] + self.assertRecordValues(mo.move_raw_ids, expected_vals) + self.assertRecordValues(mo.picking_ids.move_lines, expected_vals) diff --git a/addons/mrp/views/mrp_production_views.xml b/addons/mrp/views/mrp_production_views.xml index 07c0d19886d52532897c3f31274aebabdbce8d7c..34067f06b766959ab0d4b0ac86e7346d04805495 100644 --- a/addons/mrp/views/mrp_production_views.xml +++ b/addons/mrp/views/mrp_production_views.xml @@ -295,7 +295,7 @@ <field name="location_dest_id" domain="[('id', 'child_of', parent.location_dest_id)]" invisible="1"/> <field name="state" invisible="1" force_save="1"/> <field name="should_consume_qty" invisible="1"/> - <field name="product_uom_qty" widget="mrp_should_consume" force_save="1" string="To Consume" attrs="{'readonly': ['&', ('parent.state', '!=', 'draft'), '|', '&', ('parent.state', 'not in', ('confirmed', 'progress', 'to_close')), ('parent.is_planned', '!=', True), ('parent.is_locked', '=', True)]}" width="1"/> + <field name="product_uom_qty" widget="mrp_should_consume" force_save="1" string="To Consume" attrs="{'readonly': ['&', ('parent.state', '!=', 'draft'), '|', '&', ('parent.state', 'not in', ('confirmed', 'progress', 'to_close')), ('parent.is_planned', '!=', True), '&', ('state', '!=', 'draft'), ('parent.is_locked', '=', True)]}" width="1"/> <field name="product_uom" attrs="{'readonly': [('state', '!=', 'draft'), ('id', '!=', False)]}" options="{'no_open': True, 'no_create': True}" groups="uom.group_uom"/> <field name="product_type" invisible="1"/> <field name="product_qty" invisible="1" readonly="1"/>