[FIX] stock_account: stock valuation report performances
Basically, computation of the `inventory_value` is now done in batch instead of one by one. In a real use case, the computation of the stock valuation passed from 20+ minutes to less than a minute. This revision contains an unusual SQL request: `SELECT DISTINCT ON` Basically, it returns the most recent line of table product_price_history for each tuple `(product_template_id, company_id)` which is actually what we want, with good performances. See postgresql doc for more information: http://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-DISTINCT opw-641154
This commit is contained in:
parent
0d5b01543e
commit
55b7f15ee2
|
@ -46,21 +46,39 @@ class stock_history(osv.osv):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
date = context.get('history_date')
|
date = context.get('history_date')
|
||||||
prod_dict = {}
|
|
||||||
if 'inventory_value' in fields:
|
if 'inventory_value' in fields:
|
||||||
|
group_lines = {}
|
||||||
|
for line in res:
|
||||||
|
domain = line.get('__domain', [])
|
||||||
|
group_lines.setdefault(str(domain), self.search(cr, uid, domain, context=context))
|
||||||
|
line_ids = set()
|
||||||
|
for ids in group_lines.values():
|
||||||
|
for product_id in ids:
|
||||||
|
line_ids.add(product_id)
|
||||||
|
line_ids = list(line_ids)
|
||||||
|
cr.execute('SELECT id, product_id, price_unit_on_quant, company_id, quantity FROM stock_history WHERE id in %s', (tuple(line_ids),))
|
||||||
|
lines_rec = cr.dictfetchall()
|
||||||
|
lines_dict = dict((line['id'], line) for line in lines_rec)
|
||||||
|
product_ids = list(set(line_rec['product_id'] for line_rec in lines_rec))
|
||||||
|
products_rec = self.pool['product.product'].read(cr, uid, product_ids, ['cost_method', 'product_tmpl_id'], context=context)
|
||||||
|
products_dict = dict((product['id'], product) for product in products_rec)
|
||||||
|
cost_method_product_tmpl_ids = list(set(product['product_tmpl_id'][0] for product in products_rec if product['cost_method'] != 'real'))
|
||||||
|
cr.execute('SELECT DISTINCT ON (product_template_id, company_id) product_template_id, company_id, cost FROM product_price_history WHERE product_template_id in %s AND datetime <= %s ORDER BY product_template_id, company_id, datetime DESC', (tuple(cost_method_product_tmpl_ids), date))
|
||||||
|
histories = cr.dictfetchall()
|
||||||
|
histories_dict = {}
|
||||||
|
for history in histories:
|
||||||
|
histories_dict[(history['product_template_id'], history['company_id'])] = history['cost']
|
||||||
for line in res:
|
for line in res:
|
||||||
lines = self.search(cr, uid, line.get('__domain', []), context=context)
|
|
||||||
inv_value = 0.0
|
inv_value = 0.0
|
||||||
product_tmpl_obj = self.pool.get("product.template")
|
lines = group_lines.get(str(line.get('__domain', [])))
|
||||||
lines_rec = self.browse(cr, uid, lines, context=context)
|
for line_id in lines:
|
||||||
for line_rec in lines_rec:
|
line_rec = lines_dict[line_id]
|
||||||
if line_rec.product_id.cost_method == 'real':
|
product = products_dict[line_rec['product_id']]
|
||||||
price = line_rec.price_unit_on_quant
|
if product['cost_method'] == 'real':
|
||||||
|
price = line_rec['price_unit_on_quant']
|
||||||
else:
|
else:
|
||||||
if not line_rec.product_id.id in prod_dict:
|
price = histories_dict.get((product['product_tmpl_id'][0], line_rec['company_id']), 0.0)
|
||||||
prod_dict[line_rec.product_id.id] = product_tmpl_obj.get_history_price(cr, uid, line_rec.product_id.product_tmpl_id.id, line_rec.company_id.id, date=date, context=context)
|
inv_value += price * line_rec['quantity']
|
||||||
price = prod_dict[line_rec.product_id.id]
|
|
||||||
inv_value += price * line_rec.quantity
|
|
||||||
line['inventory_value'] = inv_value
|
line['inventory_value'] = inv_value
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue