[FIX] stock_account: Performance of _compute_stock_value
On the ticket 1961412, the custommer has more than 12 millions of stock moves. Before this commit, the search request does not take too much time to execute but fetching the fields on the recordset takes a lot of time due to the 'in' in the where clause of the associated SQL request. This optimization permit to avoid this 'where clause' and decrease the time to gather all the different fields. The time has been reduce to less than one minutes where it takes approximately 20 minutes before. closes odoo/odoo#32520 Signed-off-by: Simon Lejeune (sle) <sle@openerp.com>
This commit is contained in:
@@ -201,18 +201,30 @@ class ProductProduct(models.Model):
|
||||
for row in res:
|
||||
fifo_automated_values[(row[0], row[1])] = (row[2], row[3], list(row[4]))
|
||||
|
||||
product_values = {product: 0 for product in self}
|
||||
product_move_ids = {product: [] for product in self}
|
||||
product_values = {product.id: 0 for product in self}
|
||||
product_move_ids = {product.id: [] for product in self}
|
||||
|
||||
if to_date:
|
||||
domain = [('product_id', 'in', self.ids), ('date', '<=', to_date)] + StockMove._get_all_base_domain()
|
||||
for move in StockMove.search(domain).with_context(prefetch_fields=False):
|
||||
product_values[move.product_id] += move.value
|
||||
product_move_ids[move.product_id].append(move.id)
|
||||
value_field_name = 'value'
|
||||
else:
|
||||
domain = [('product_id', 'in', self.ids)] + StockMove._get_all_base_domain()
|
||||
for move in StockMove.search(domain).with_context(prefetch_fields=False):
|
||||
product_values[move.product_id] += move.remaining_value
|
||||
product_move_ids[move.product_id].append(move.id)
|
||||
value_field_name = 'remaining_value'
|
||||
|
||||
StockMove.check_access_rights('read')
|
||||
query = StockMove._where_calc(domain)
|
||||
StockMove._apply_ir_rules(query, 'read')
|
||||
from_clause, where_clause, params = query.get_sql()
|
||||
query_str = """
|
||||
SELECT stock_move.product_id, SUM(COALESCE(stock_move.{}, 0.0)), ARRAY_AGG(stock_move.id)
|
||||
FROM {}
|
||||
WHERE {}
|
||||
GROUP BY stock_move.product_id
|
||||
""".format(value_field_name, from_clause, where_clause)
|
||||
self.env.cr.execute(query_str, params)
|
||||
for product_id, value, move_ids in self.env.cr.fetchall():
|
||||
product_values[product_id] = value
|
||||
product_move_ids[product_id] = move_ids
|
||||
|
||||
for product in self:
|
||||
if product.cost_method in ['standard', 'average']:
|
||||
@@ -228,9 +240,9 @@ class ProductProduct(models.Model):
|
||||
elif product.cost_method == 'fifo':
|
||||
if to_date:
|
||||
if product.product_tmpl_id.valuation == 'manual_periodic':
|
||||
product.stock_value = product_values[product]
|
||||
product.stock_value = product_values[product.id]
|
||||
product.qty_at_date = product.with_context(company_owned=True, owner_id=False).qty_available
|
||||
product.stock_fifo_manual_move_ids = StockMove.browse(product_move_ids[product])
|
||||
product.stock_fifo_manual_move_ids = StockMove.browse(product_move_ids[product.id])
|
||||
elif product.product_tmpl_id.valuation == 'real_time':
|
||||
valuation_account_id = product.categ_id.property_stock_valuation_account_id.id
|
||||
value, quantity, aml_ids = fifo_automated_values.get((product.id, valuation_account_id)) or (0, 0, [])
|
||||
@@ -238,10 +250,10 @@ class ProductProduct(models.Model):
|
||||
product.qty_at_date = quantity
|
||||
product.stock_fifo_real_time_aml_ids = self.env['account.move.line'].browse(aml_ids)
|
||||
else:
|
||||
product.stock_value, moves = product_values[product], StockMove.browse(product_move_ids[product])
|
||||
product.stock_value = product_values[product.id]
|
||||
product.qty_at_date = product.with_context(company_owned=True, owner_id=False).qty_available
|
||||
if product.product_tmpl_id.valuation == 'manual_periodic':
|
||||
product.stock_fifo_manual_move_ids = moves
|
||||
product.stock_fifo_manual_move_ids = StockMove.browse(product_move_ids[product.id])
|
||||
elif product.product_tmpl_id.valuation == 'real_time':
|
||||
valuation_account_id = product.categ_id.property_stock_valuation_account_id.id
|
||||
value, quantity, aml_ids = fifo_automated_values.get((product.id, valuation_account_id)) or (0, 0, [])
|
||||
|
||||
Reference in New Issue
Block a user