diff --git a/addons/mrp/tests/test_stock_report.py b/addons/mrp/tests/test_stock_report.py index b15495d1bae75..a99c6d04961e8 100644 --- a/addons/mrp/tests/test_stock_report.py +++ b/addons/mrp/tests/test_stock_report.py @@ -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') diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py index 6e35a0d16e08d..f9b0e5c64f512 100644 --- a/addons/stock/models/stock_move.py +++ b/addons/stock/models/stock_move.py @@ -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: