Skip to content
Snippets Groups Projects
Commit ba8f99c0 authored by Adrien Widart (awt)'s avatar Adrien Widart (awt)
Browse files

[FIX] mrp: create PBM SM from confirmed MO

To reproduce the issue:
1. In Settings, enable "Multi Routes"
2. Edit the warehouse:
   - Manufacture: 2 steps
3. Create three storable products P1, P2, P3
4. Create and confirm a MO for 1 x P1 with 1 x P2
   - It should create the PBM picking
5. Add a component line for P3
6. (Because the MO is locked, the user can not edit the 'to consume'
   quantity, so) Unlock the MO
7. Set the 'to consume' qty to 1
8. Save the MO

Error: P3 is not added to PBM picking. Worst: suppose the user does
the internal transfer and then checks the availability of P3, the
line will still be unreserved

Step 6, when unlocking the MO, it also triggers a save. As a result,
the SM for P3 is created with its demand defined to 0. When adding
such SM, we do several things through this method call:
https://github.com/odoo/odoo/blob/be0b61cbaf3d3b7082aca8f96dcf8a6ee7885fea/addons/mrp/models/mrp_production.py#L776


- We will adapt its procure method (here, because of 2-steps
  manufacturing, it will be MTO)
- We will confirm the new SM -> we will run a procurement for a zero
  quantity -> it will not generate any new SM

Then, when updating the SM quantity (step 7), nothing will run a new
procurement.

Moreover, this also explains why trying to reserve the SM does not
work: it's an MTO one, but it does not have any `move_orig_ids`, so
it is not possible to assign it.

Solutions:
- It should be possible to edit the 'to consume' qty of a new SM,
  even on a locked and confirmed MO
- A procurement should be executed when updating the demand of an SM
  from 0 to >0. From 16.1, a procurement will always be executed
  each time the quantity changed (see [1]). Here, we want to limit
  the impact/risk of the fix

[1] 1f4fb64a

OPW-3253204

closes odoo/odoo#135478

Signed-off-by: default avatarWilliam Henrotin (whe) <whe@odoo.com>
parent ece650c1
No related branches found
No related tags found
No related merge requests found
......@@ -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):
......
......@@ -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)
......@@ -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': ['&amp;', ('parent.state', '!=', 'draft'), '|', '&amp;', ('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': ['&amp;', ('parent.state', '!=', 'draft'), '|', '&amp;', ('parent.state', 'not in', ('confirmed', 'progress', 'to_close')), ('parent.is_planned', '!=', True), '&amp;', ('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"/>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment