Skip to content

Commit

Permalink
[FIX] mrp: confirm production order at the end
Browse files Browse the repository at this point in the history
This commit removes the action_confirm from the run_manufacture to do it
only after all the orderpoints have been processed.

In case a production, created in run_manufacture, triggers procurements
for one of its component. And those procurements have the same
parameters than another one still not run because after the manufacture
one in the queue. This new procurement will replenish its quantity plus
the other procurement's one.

That means too much quantity will be replenished.

closes odoo#77025

X-original-commit: a7bb9f1
Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>
Signed-off-by: Arnold Moyaux <amoyaux@users.noreply.github.com>
  • Loading branch information
Whenrow committed Sep 27, 2021
1 parent 1dbf02e commit b4fd050
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 1 deletion.
10 changes: 10 additions & 0 deletions addons/mrp/models/stock_orderpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,13 @@ def _prepare_procurement_values(self, date=False, group=False):
values = super()._prepare_procurement_values(date=date, group=group)
values['bom_id'] = self.bom_id
return values

def _post_process_scheduler(self):
""" Confirm the productions only after all the orderpoints have run their
procurement to avoid the new procurement created from the production conflict
with them. """
self.env['mrp.production'].sudo().search([
('orderpoint_id', 'in', self.ids),
('move_raw_ids', '!=', False),
]).action_confirm()
return super()._post_process_scheduler()
2 changes: 1 addition & 1 deletion addons/mrp/models/stock_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def _run_manufacture(self, procurements):
self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
productions._create_workorder()
productions.action_confirm()
productions.filtered(lambda p: not p.orderpoint_id).action_confirm()

for production in productions:
origin_production = production.move_dest_ids and production.move_dest_ids[0].raw_material_production_id or False
Expand Down
76 changes: 76 additions & 0 deletions addons/purchase_mrp/tests/test_purchase_mrp_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,3 +410,79 @@ def test_01_sale_mrp_kit_qty_delivered(self):
# Check the components quantities that backorder_4 should have
for move in backorder_4.move_lines:
self.assertEqual(move.product_qty, 1)

def test_concurent_procurements(self):
""" Check a production created to fulfill a procurement will not
replenish more that needed if others procurements have the same products
than the production component. """

warehouse = self.env.ref('stock.warehouse0')
buy_route = warehouse.buy_pull_id.route_id
manufacture_route = warehouse.manufacture_pull_id.route_id

vendor1 = self.env['res.partner'].create({'name': 'aaa', 'email': 'from.test@example.com'})
supplier_info1 = self.env['product.supplierinfo'].create({
'name': vendor1.id,
'price': 50,
})

component = self.env['product.product'].create({
'name': 'component',
'type': 'product',
'route_ids': [(4, buy_route.id)],
'seller_ids': [(6, 0, [supplier_info1.id])],
})
finished = self.env['product.product'].create({
'name': 'finished',
'type': 'product',
'route_ids': [(4, manufacture_route.id)],
})
self.env['stock.warehouse.orderpoint'].create({
'name': 'A RR',
'location_id': warehouse.lot_stock_id.id,
'product_id': component.id,
'route_id': buy_route.id,
'product_min_qty': 0,
'product_max_qty': 0,
})
self.env['stock.warehouse.orderpoint'].create({
'name': 'A RR',
'location_id': warehouse.lot_stock_id.id,
'product_id': finished.id,
'route_id': manufacture_route.id,
'product_min_qty': 0,
'product_max_qty': 0,
})

self.env['mrp.bom'].create({
'product_id': finished.id,
'product_tmpl_id': finished.product_tmpl_id.id,
'product_uom_id': self.uom_unit.id,
'product_qty': 1.0,
'consumption': 'flexible',
'operation_ids': [
],
'type': 'normal',
'bom_line_ids': [
(0, 0, {'product_id': component.id, 'product_qty': 1}),
]})

# Delivery to trigger replenishment
picking_form = Form(self.env['stock.picking'])
picking_form.picking_type_id = warehouse.out_type_id
with picking_form.move_ids_without_package.new() as move:
move.product_id = finished
move.product_uom_qty = 3
with picking_form.move_ids_without_package.new() as move:
move.product_id = component
move.product_uom_qty = 2
picking = picking_form.save()
picking.action_confirm()

# Find PO
purchase = self.env['purchase.order.line'].search([
('product_id', '=', component.id),
]).order_id
self.assertTrue(purchase)
self.assertEqual(purchase.order_line.product_qty, 5)

0 comments on commit b4fd050

Please sign in to comment.