Skip to content

Commit

Permalink
[FIX] stock: consider multi-steps in forecast availability
Browse files Browse the repository at this point in the history
Steps to reproduce:

- Enable multi-step routes in the settings
- Inventory > Configuration > Warehouse Management > Warehouses
- Change your warehouse to manufacturing in 3 steps
- Create a storable product COMP with 10 units in stock
- Create a manufacturing order for a product Final product using COMP as
  components

> The forcast of the components indicates that they are not available

Cause of the issue:

The location query of the `_get_forecast_availability_outgoing` was
recently changed to:
https://github.com/odoo/odoo/blob/49061347c181b1a451435bc363bb9508db8b6fab/addons/stock/models/stock_move.py#L2253
This change was made for optimisation purposes because the forecast
lines now take care of the precise locations here:
https://github.com/odoo/odoo/blob/49061347c181b1a451435bc363bb9508db8b6fab/addons/stock/models/stock_move.py#L2255
However, this optimisation is not correct as the forecast the result of
this query is used in order to determine if a move is incoming or
outgoing here:
https://github.com/odoo/odoo/blob/49061347c181b1a451435bc363bb9508db8b6fab/addons/stock/report/stock_forecasted.py#L31-L44
and these domains only makes sense if the wh_location_ids are indeed all
the locations of the warehouse and not these that are children of the
"pre-prod" location.

opw-3979953

closes odoo#179989

X-original-commit: be55bf0
Signed-off-by: William Henrotin (whe) <[email protected]>
Signed-off-by: Lancelot Semal (lase) <[email protected]>
  • Loading branch information
lase-odoo committed Sep 12, 2024
1 parent ba4ca8f commit 9d6f200
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 2 deletions.
33 changes: 33 additions & 0 deletions addons/mrp/tests/test_stock_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,3 +387,36 @@ def test_overview_with_component_also_as_byproduct(self):
mo.action_confirm()
overview_values = self.env['report.mrp.report_mo_overview'].get_report_values(mo.id)
self.assertEqual(overview_values['data']['id'], mo.id, "Unexpected disparity between overview and MO data")

def test_multi_step_component_forecast_availability(self):
"""
Test that the component availability is correcly forecasted
in multi step manufacturing
"""
# Configures the warehouse.
warehouse = self.env.ref('stock.warehouse0')
warehouse.manufacture_steps = 'pbm_sam'
final_product, component = self.product, self.product1
bom = self.env['mrp.bom'].create({
'product_id': final_product.id,
'product_tmpl_id': final_product.product_tmpl_id.id,
'product_uom_id': final_product.uom_id.id,
'product_qty': 1.0,
'type': 'normal',
'bom_line_ids': [
Command.create({'product_id': component.id, 'product_qty': 10}),
],
})
# Creates a MO without any component in stock
mo_form = Form(self.env['mrp.production'])
mo_form.bom_id = bom
mo_form.product_qty = 2
mo = mo_form.save()
mo.action_confirm()
self.assertEqual(mo.components_availability, 'Not Available')
self.assertEqual(mo.move_raw_ids.forecast_availability, -20.0)
self.env['stock.quant']._update_available_quantity(component, warehouse.lot_stock_id, 100)
# change the qty_producing to force a recompute of the availability
with Form(mo) as mo_form:
mo_form.qty_producing = 2.0
self.assertEqual(mo.components_availability, 'Available')
3 changes: 1 addition & 2 deletions addons/stock/models/stock_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -2261,8 +2261,7 @@ def _get_forecast_availability_outgoing(self, warehouse, location_id=False):
:return: a defaultdict of outgoing moves from warehouse for product_id in self, values are tuple (sum_qty_expected, max_date_expected)
:rtype: defaultdict
"""
wh_location_query = self.env['stock.location']._search([('id', 'child_of', location_id.id if location_id else warehouse.view_location_id.id)])

wh_location_query = self.env['stock.location']._search([('id', 'child_of', warehouse.view_location_id.id)])
forecast_lines = self.env['stock.forecasted_product_product']._get_report_lines(False, self.product_id.ids, wh_location_query, location_id or warehouse.lot_stock_id, read=False)
result = defaultdict(lambda: (0.0, False))
for line in forecast_lines:
Expand Down

0 comments on commit 9d6f200

Please sign in to comment.