diff --git a/addons/stock/report/stock_forecasted.py b/addons/stock/report/stock_forecasted.py index e75dc62718e..dab2705aa29 100644 --- a/addons/stock/report/stock_forecasted.py +++ b/addons/stock/report/stock_forecasted.py @@ -186,7 +186,7 @@ class StockForecasted(models.AbstractModel): def _get_report_lines(self, product_template_ids, product_ids, wh_location_ids, wh_stock_location, read=True): - def _get_out_move_reserved_data(out, ins, used_reserved_moves): + def _get_out_move_reserved_data(out, ins, used_reserved_moves, currents): reserved_out = 0 linked_moves = self.env['stock.move'].browse(out._rollup_move_origs()).filtered(lambda m: m.id not in ins.ids) # the move to show when qty is reserved @@ -203,6 +203,7 @@ class StockForecasted(models.AbstractModel): # add to reserved line data reserved_out += reserved used_reserved_moves[move] += reserved + currents[(out.product_id.id, move.location_id.id)] -= reserved if float_compare(reserved_out, out.product_qty, precision_rounding=move.product_id.uom_id.rounding) >= 0: break @@ -292,14 +293,16 @@ class StockForecasted(models.AbstractModel): # any sublocation qties will be added to the main stock location qty if location_id in wh_stock_sub_location_ids: location_id = wh_stock_location.id - currents[(qty['product_id'][0], location_id)] += qty['quantity'] - qty['reserved_quantity'] + currents[(qty['product_id'][0], location_id)] += qty['quantity'] moves_data = {} for _, out_moves in outs_per_product.items(): # to handle multiple out wtih same in (ex: same pick/pack for 2 outs) used_reserved_moves = defaultdict(float) - # for all out moves, check for linked moves and remove qty from current stock + # for all out moves, check for linked moves and count reserved quantity + for out in out_moves: + moves_data[out] = _get_out_move_reserved_data(out, ins, used_reserved_moves, currents) + # another loop to remove qty from current stock after reserved is counted for for out in out_moves: - moves_data[out] = _get_out_move_reserved_data(out, ins, used_reserved_moves) data = _get_out_move_taken_from_stock_data(out, currents, moves_data[out]) moves_data[out].update(data) lines = [] diff --git a/addons/stock/tests/test_report.py b/addons/stock/tests/test_report.py index fd525cc1dd7..01cca185b15 100644 --- a/addons/stock/tests/test_report.py +++ b/addons/stock/tests/test_report.py @@ -1227,6 +1227,39 @@ class TestReports(TestReportsCommon): self.assertEqual(all_delivery.move_ids.mapped("forecast_availability"), [3, 3, -3.0, -3.0]) + def test_report_forecast_12_reserved_transit(self): + """ Tests the transit feature, in 2 step incoming shipment warehouse, create + incoming transfer, validate it, create outgoing transfer and check report to show + quantities needed are in transit + """ + grp_multi_loc = self.env.ref('stock.group_stock_multi_locations') + grp_multi_routes = self.env.ref('stock.group_adv_location') + self.env.user.write({'groups_id': [(4, grp_multi_loc.id)]}) + self.env.user.write({'groups_id': [(4, grp_multi_routes.id)]}) + # Warehouse config. + warehouse = self.env.ref('stock.warehouse0') + warehouse.reception_steps = 'two_steps' + outgoing = Form(self.env['stock.picking']) + outgoing.picking_type_id = self.picking_type_out + with outgoing.move_ids_without_package.new() as move: + move.product_id = self.product + move.product_uom_qty = 2 + outgoing = outgoing.save() + outgoing.action_confirm() + incoming = Form(self.env['stock.picking']) + incoming.picking_type_id = self.picking_type_in + with incoming.move_ids_without_package.new() as move: + move.product_id = self.product + move.product_uom_qty = 2 + incoming = incoming.save() + incoming.action_confirm() + incoming.action_set_quantities_to_reservation() + incoming.button_validate() + _, _, lines = self.get_report_forecast(product_template_ids=self.product_template.ids) + self.assertEqual(len(lines), 1) + self.assertEqual(bool(lines[0]['move_out']), True) + self.assertEqual(lines[0]['in_transit'], True) + def test_report_reception_1_one_receipt(self): """ Create 2 deliveries and 1 receipt where some of the products being received can be reserved for the deliveries. Check that the reception report correctly