[FIX] mrp: create SM for by-products when RR triggered

When combining a reordering rule, the 3-steps manufacture and
by-products option, the picking from the post-production to the stock
will not contain the residual products produced by the MO (by-products)

To reproduce the error:
1. In Settings, enable:
    - By-Products
    - Multi-Step Routes
2. Inventory > Configuration > Warehouse Management > Warehouses, edit
company's warehouse:
    - Manufacture: 3 steps
3. Create 3 products P_compo, P_finished, P_secondary
    - P_compo is consumable
    - P_finished and P_secondary are storable
    - Routes of P_finished: Manufacture
4. Create a reordering rule for P_finished:
    - Min = Max = 1
5. Create a BoM:
    - Product: P_finished
    - Type: Manufacture
    - Components: 1 x P_compo
    - By-products: 1 x P_secondary
6. Inventory > Operations > Run Scheduler
7. Open the generated MO
8. Check Availability, Produce, Mark as Done
    - Note that in the "Produce" wizard, we mention that one P_secondary
is also produced
    - Also note that in "Finished Products" tab, there are 1 x
P_finished and 1 x P_secondary
9. Open the Transfers

Error: The picking Post-Production -> Stock does not exist

When creating the byproducts move
https://github.com/odoo/odoo/blob/ad62f877c174d56b90ec516cf24494d751383db9/addons/mrp/models/mrp_production.py#L587
the field `move_dest_ids` is present (is the move created after
evaluating the RR)
https://github.com/odoo/odoo/blob/ad62f877c174d56b90ec516cf24494d751383db9/addons/mrp/models/mrp_production.py#L580
so it is used, but this will cause the `_push_apply` to skip the
evaluation of the move
https://github.com/odoo/odoo/blob/f0eaa756c4947e2a595359959b34b14bfda81a07/addons/stock/models/stock_move.py#L678-L679
and `_assign_picking` will not run, as it normally do when creating the
manufacture

Thanks to this change, the picking Post-Production -> Stock will exist
and contain the residual products

OPW-2581762

closes odoo/odoo#75068

X-original-commit: 098af2fa85d2aebfc71b7e2342a1bbf05100e10d
Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>
This commit is contained in:
Adrien Widart
2021-08-16 07:05:51 +00:00
parent aa1fdace61
commit 89f5f504be
2 changed files with 82 additions and 1 deletions
+1 -1
View File
@@ -856,7 +856,7 @@ class MrpProduction(models.Model):
'origin': self.name,
'group_id': self.procurement_group_id.id,
'propagate_cancel': self.propagate_cancel,
'move_dest_ids': [(4, x.id) for x in move_dest_ids],
'move_dest_ids': [(4, x.id) for x in self.move_dest_ids if not byproduct_id],
}
def _get_moves_finished_values(self):
@@ -308,3 +308,84 @@ class TestMultistepManufacturingWarehouse(TestMrpCommon):
pbm_move = move_raw_ids.move_orig_ids
self.assertEqual(len(pbm_move), 2)
self.assertTrue(new_product in pbm_move.product_id)
def test_3_steps_and_byproduct(self):
""" Suppose a warehouse with Manufacture option set to '3 setps' and a product P01 with a reordering rule.
Suppose P01 has a BoM and this BoM mentions that when some P01 are produced, some P02 are produced too.
This test ensures that when a MO is generated thanks to the reordering rule, 2 pickings are also
generated:
- One to bring the components
- Another to return the P01 and P02 produced
"""
warehouse = self.warehouse
warehouse.manufacture_steps = 'pbm_sam'
warehouse_stock_location = warehouse.lot_stock_id
pre_production_location = warehouse.pbm_loc_id
post_production_location = warehouse.sam_loc_id
one_unit_uom = self.env.ref('uom.product_uom_unit')
[two_units_uom, four_units_uom] = self.env['uom.uom'].create([{
'name': 'x%s' % i,
'category_id': self.ref('uom.product_uom_categ_unit'),
'uom_type': 'bigger',
'factor_inv': i,
} for i in [2, 4]])
finished_product = self.env['product.product'].create({
'name': 'Super Product',
'route_ids': [(4, self.ref('mrp.route_warehouse0_manufacture'))],
'type': 'product',
})
secondary_product = self.env['product.product'].create({
'name': 'Secondary',
'type': 'product',
})
component = self.env['product.product'].create({
'name': 'Component',
'type': 'consu',
})
self.env['mrp.bom'].create({
'product_tmpl_id': finished_product.product_tmpl_id.id,
'product_qty': 1,
'product_uom_id': two_units_uom.id,
'bom_line_ids': [(0, 0, {
'product_id': component.id,
'product_qty': 1,
'product_uom_id': one_unit_uom.id,
})],
'byproduct_ids': [(0, 0, {
'product_id': secondary_product.id,
'product_qty': 1,
'product_uom_id': four_units_uom.id,
})],
})
self.env['stock.warehouse.orderpoint'].create({
'warehouse_id': warehouse.id,
'location_id': warehouse_stock_location.id,
'product_id': finished_product.id,
'product_min_qty': 2,
'product_max_qty': 2,
})
self.env['procurement.group'].run_scheduler()
mo = self.env['mrp.production'].search([('product_id', '=', finished_product.id)])
pickings = mo.picking_ids
self.assertEqual(len(pickings), 2)
preprod_picking = pickings[0] if pickings[0].location_id == warehouse_stock_location else pickings[1]
self.assertEqual(preprod_picking.location_id, warehouse_stock_location)
self.assertEqual(preprod_picking.location_dest_id, pre_production_location)
postprod_picking = pickings - preprod_picking
self.assertEqual(postprod_picking.location_id, post_production_location)
self.assertEqual(postprod_picking.location_dest_id, warehouse_stock_location)
byproduct_postprod_move = self.env['stock.move'].search([
('product_id', '=', secondary_product.id),
('location_id', '=', post_production_location.id),
('location_dest_id', '=', warehouse_stock_location.id),
])
self.assertEqual(byproduct_postprod_move.state, 'waiting')
self.assertEqual(byproduct_postprod_move.group_id.name, mo.name)