[FIX] stock: quantities in transit not seen by report

Before this commit, if there is a demand for quantities and they are
available but reserved in transit (not yet in a stock location) they are
shown as not available.

To reproduce:

1) Have 2/3 step incoming shipments in warehouse
2) Purchase a quantity to create the incoming transfer
3) Validate the first step so that quantity is now in Input location
4) Create a MO with the component with quantity only in Input location
5) Go to forecast report of component, the quantity is shown not available.

closes odoo/odoo#117372

X-original-commit: 39ff1feae9f44b64ee3fff6ccee837ac4922ad1e
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Ahmed Khalaf  <ahkh@odoo.com>
This commit is contained in:
Ahmed Khalaf
2023-04-03 10:41:37 +02:00
parent 8f8adf760b
commit dd6fd233ed
2 changed files with 40 additions and 4 deletions
+7 -4
View File
@@ -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 = []
+33
View File
@@ -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