summaryrefslogtreecommitdiff
path: root/addons/stock
diff options
context:
space:
mode:
authorRémy Voet (ryv) <ryv@odoo.com>2021-03-01 13:41:35 +0000
committerRémy Voet (ryv) <ryv@odoo.com>2021-03-04 15:03:12 +0000
commit6737feef848dc47120cf3d2cca84e033e869c985 (patch)
tree015d6a4b57452b9345302ef949563ce359bdd880 /addons/stock
parentd43e9cb9ad8d1c0c020209de0e8f6ffdcbc960a1 (diff)
[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: Arnold Moyaux <amoyaux@users.noreply.github.com>
Diffstat (limited to 'addons/stock')
-rw-r--r--addons/stock/models/stock_orderpoint.py26
1 files changed, 20 insertions, 6 deletions
diff --git a/addons/stock/models/stock_orderpoint.py b/addons/stock/models/stock_orderpoint.py
index 1d6949a5b75..f30af5dff15 100644
--- a/addons/stock/models/stock_orderpoint.py
+++ b/addons/stock/models/stock_orderpoint.py
@@ -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({