diff options
| author | Rémy Voet (ryv) <ryv@odoo.com> | 2021-03-01 13:41:35 +0000 |
|---|---|---|
| committer | Rémy Voet (ryv) <ryv@odoo.com> | 2021-03-04 15:03:12 +0000 |
| commit | 6737feef848dc47120cf3d2cca84e033e869c985 (patch) | |
| tree | 015d6a4b57452b9345302ef949563ce359bdd880 /addons | |
| parent | d43e9cb9ad8d1c0c020209de0e8f6ffdcbc960a1 (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')
| -rw-r--r-- | addons/stock/models/stock_orderpoint.py | 26 |
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({ |
