Skip to content
Snippets Groups Projects
Commit 6737feef authored by Rémy Voet (ryv)'s avatar Rémy Voet (ryv)
Browse files

[FIX] stock: fix replenishement with archived RR


If some RR is archived and where the a forecasted demand on the
warehouse location, it Replenishement will crash will due to the
SQL constraint. It happens because the archived RR aren't take in
account in `_get_orderpoint_action` and the method will try to
create a orderpoint with same product + location which
lead to trigger the SQL constraint `product_location_check`.

Also avoid filtered in for loop to improve performance and use the
read_group instead.

task-2439019

closes odoo/odoo#67263

Signed-off-by: default avatarArnold Moyaux <amoyaux@users.noreply.github.com>
parent d43e9cb9
No related branches found
No related tags found
No related merge requests found
......@@ -294,7 +294,11 @@ class StockWarehouseOrderpoint(models.Model):
"""
action = self.env["ir.actions.actions"]._for_xml_id("stock.action_orderpoint_replenish")
action['context'] = self.env.context
orderpoints = self.env['stock.warehouse.orderpoint'].search([])
# Search also with archived ones to avoid to trigger product_location_check SQL constraints later
# It means that when there will be a archived orderpoint on a location + product, the replenishment
# report won't take in account this location + product and it won't create any manual orderpoint
# In master: the active field should be remove
orderpoints = self.env['stock.warehouse.orderpoint'].with_context(active_test=False).search([])
# Remove previous automatically created orderpoint that has been refilled.
to_remove = orderpoints.filtered(lambda o: o.create_uid.id == SUPERUSER_ID and o.qty_to_order <= 0.0 and o.trigger == 'manual')
to_remove.unlink()
......@@ -317,13 +321,13 @@ class StockWarehouseOrderpoint(models.Model):
dummy, qty_by_product_wh = self.env['product.product'].browse(product_ids)._get_quantity_in_progress(warehouse_ids=warehouse_ids)
rounding = self.env['decimal.precision'].precision_get('Product Unit of Measure')
# Group orderpoint by product-warehouse
grouped_orderpoint_data = self.env['stock.warehouse.orderpoint'].read_group(
orderpoint_by_product_warehouse = self.env['stock.warehouse.orderpoint'].read_group(
[('id', 'in', orderpoints.ids)],
['product_id', 'warehouse_id', 'qty_to_order:sum'],
['product_id', 'warehouse_id'], lazy=False)
orderpoint_by_product_warehouse = {
(record.get('product_id')[0], record.get('warehouse_id')[0]): record.get('qty_to_order')
for record in grouped_orderpoint_data
for record in orderpoint_by_product_warehouse
}
for (product, warehouse), product_qty in to_refill.items():
qty_in_progress = qty_by_product_wh.get((product, warehouse)) or 0.0
......@@ -340,12 +344,22 @@ class StockWarehouseOrderpoint(models.Model):
], ['lot_stock_id'])
lot_stock_id_by_warehouse = {w['id']: w['lot_stock_id'][0] for w in lot_stock_id_by_warehouse}
# With archived ones to avoid `product_location_check` SQL constraints
orderpoint_by_product_location = self.env['stock.warehouse.orderpoint'].with_context(active_test=False).read_group(
[('id', 'in', orderpoints.ids)],
['product_id', 'location_id', 'ids:array_agg(id)'],
['product_id', 'location_id'], lazy=False)
orderpoint_by_product_location = {
(record.get('product_id')[0], record.get('location_id')[0]): record.get('ids')[0]
for record in orderpoint_by_product_location
}
orderpoint_values_list = []
for (product, warehouse), product_qty in to_refill.items():
lot_stock_id = lot_stock_id_by_warehouse[warehouse]
orderpoint = orderpoints.filtered(lambda o: o.product_id.id == product and o.location_id.id == lot_stock_id)
if orderpoint:
orderpoint[0].qty_forecast += product_qty
orderpoint_id = orderpoint_by_product_location.get((product, lot_stock_id))
if orderpoint_id:
self.env['stock.warehouse.orderpoint'].browse(orderpoint_id).qty_forecast += product_qty
else:
orderpoint_values = self.env['stock.warehouse.orderpoint']._get_orderpoint_values(product, lot_stock_id)
orderpoint_values.update({
......
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