Skip to content
Snippets Groups Projects
Commit e9377bfe authored by Walid HANNICHE (waha)'s avatar Walid HANNICHE (waha)
Browse files

[FIX] stock, mrp: do not create an order point for kit BOMs

Steps to reproduce:
- install sales, MPS, and purchase
- Create a product P with Manufacturing route and
component cp with Buy route
- Make sure that components cp are not enough in stock
and the system runs reorder rule for it.
- Create a Sales order for product P and confirm
- run scheduler > the system will create a reordering rule
for both products ( product P and its child component CP).
- Now delete the Reordering rule for product P and change its BoM to Kit
- Run the scheduler again
- Try accessing the Replenishment

Bug:
An error message "A product with a kit-type bill of materials
can not have a reordering rule."

Fix:
back porting this fix [1] (prevent creating an order point for
manufactured products of type kit)

opw-2998740

[1]:https://github.com/odoo/odoo/pull/104366



closes odoo/odoo#107231

Signed-off-by: default avatarWilliam Henrotin (whe) <whe@odoo.com>
parent d2d23e51
No related branches found
No related tags found
No related merge requests found
......@@ -124,3 +124,9 @@ class StockWarehouseOrderpoint(models.Model):
('state', '=', 'draft'),
]).action_confirm()
return super()._post_process_scheduler()
def _product_exclude_list(self):
# don't create an order point for kit products
boms = self.env['mrp.bom'].search([('type', '=', 'phantom')])
variant_boms = boms.filtered(lambda x: x.product_id)
return super()._product_exclude_list() + variant_boms.product_id.ids + (boms - variant_boms).product_tmpl_id.product_variant_ids.ids
......@@ -234,3 +234,80 @@ class TestSaleMrpProcurement(TransactionCase):
mo = self.env['mrp.production'].search([('product_id', '=', product.id)], order='id desc', limit=1)
self.assertIn(so.name, mo.origin)
def test_so_reordering_rule(self):
Orderpoint = self.env['stock.warehouse.orderpoint']
# mulitple variant product
car = self.env['product.template'].create({
'name': 'Car',
})
color_attribute = self.env['product.attribute'].create({'name': 'Color', 'sequence': 1})
color_red = self.env['product.attribute.value'].create({
'name': 'Red',
'attribute_id': color_attribute.id,
'sequence': 1,
})
color_blue = self.env['product.attribute.value'].create({
'name': 'Blue',
'attribute_id': color_attribute.id,
'sequence': 2,
})
self.env['product.template.attribute.line'].create({
'product_tmpl_id': car.id,
'attribute_id': color_attribute.id,
'value_ids': [(6, 0, [color_red.id, color_blue.id])],
})
mrp_prod = car.product_variant_id
component_prod = self.env['product.product'].create({
'name': 'Component 1',
'type': 'product',
})
bom = self.env['mrp.bom'].create([{
'product_tmpl_id': mrp_prod.product_tmpl_id.id,
'product_id': mrp_prod.id,
'product_qty': 1,
'type': 'normal',
'bom_line_ids': [
(0, 0, {'product_id': component_prod.id, 'product_qty': 2}),
],
}])
customer = self.env['res.partner'].create({
'name': 'customer',
})
self.env['sale.order'].create({
'partner_id': customer.id,
'order_line': [
(0, 0, {
'product_id': mrp_prod.id,
'product_uom_qty': 3,
})],
}).action_confirm()
Orderpoint._get_orderpoint_action()
# change product type to Kit
mrp_prod.orderpoint_ids.unlink()
bom.type = 'phantom'
self.env['sale.order'].create({
'partner_id': customer.id,
'order_line': [
(0, 0, {
'product_id': mrp_prod.id,
'product_uom_qty': 3,
})],
}).action_confirm()
Orderpoint._get_orderpoint_action()
orderpoint_kit = Orderpoint.search([('product_id', '=', mrp_prod.id)])
orderpoint_component = Orderpoint.search([('product_id', '=', component_prod.id)])
self.assertFalse(orderpoint_kit)
self.assertEqual(orderpoint_component.qty_to_order, 3*2)
# only exclude the kit variant
self.assertIn(car.product_variant_id.id, Orderpoint._product_exclude_list())
self.assertNotIn((car.product_variant_ids - car.product_variant_id).id, Orderpoint._product_exclude_list())
......@@ -303,6 +303,10 @@ class StockWarehouseOrderpoint(models.Model):
'to_date': datetime.combine(self.lead_days_date, time.max)
}
def _product_exclude_list(self):
# added to be overwitten in mrp
return []
def _get_orderpoint_action(self):
"""Create manual orderpoints for missing product in each warehouses. It also removes
orderpoints that have been replenish. In order to do it:
......@@ -329,16 +333,13 @@ class StockWarehouseOrderpoint(models.Model):
# Take 3 months since it's the max for the forecast report
to_date = add(fields.date.today(), months=3)
qty_by_product_warehouse = self.env['report.stock.quantity'].read_group(
[('date', '=', to_date), ('state', '=', 'forecast')],
[('date', '=', to_date), ('state', '=', 'forecast'), ('product_qty', '<', 0.0), ('warehouse_id', '!=', False), ('product_id', 'not in', self._product_exclude_list())],
['product_id', 'product_qty', 'warehouse_id'],
['product_id', 'warehouse_id'], orderby="id", lazy=False)
for group in qty_by_product_warehouse:
warehouse_id = group.get('warehouse_id') and group['warehouse_id'][0]
if group['product_qty'] >= 0.0 or not warehouse_id:
continue
all_product_ids.append(group['product_id'][0])
all_warehouse_ids.append(warehouse_id)
to_refill[(group['product_id'][0], warehouse_id)] = group['product_qty']
all_warehouse_ids.append(group['warehouse_id'][0])
to_refill[(group['product_id'][0], group['warehouse_id'][0])] = group['product_qty']
if not to_refill:
return action
......
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