Skip to content

Commit

Permalink
[FIX] Change price history and stock valuation report to standard_pri…
Browse files Browse the repository at this point in the history
…ce on variant

As the standard price on the product template changed towards the product variant,
we should also change the product price history to be by variant.

Also the inventory value calculated in the Stock Valuation report should be by variant.
  • Loading branch information
jco-odoo committed Sep 16, 2015
1 parent 4449984 commit 9ac8d98
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 43 deletions.
71 changes: 37 additions & 34 deletions addons/product/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ class produce_price_history(osv.osv):

_columns = {
'company_id': fields.many2one('res.company', required=True),
'product_template_id': fields.many2one('product.template', 'Product Template', required=True, ondelete='cascade'),
'product_id': fields.many2one('product.product', 'Product', required=True, ondelete='cascade'),
'datetime': fields.datetime('Date'),
'cost': fields.float('Cost'),
}
Expand Down Expand Up @@ -418,30 +418,6 @@ def _set_product_template_price(self, cr, uid, id, name, value, args, context=No

return product.write({'list_price': value})

def get_history_price(self, cr, uid, product_tmpl, company_id, date=None, context=None):
if context is None:
context = {}
if date is None:
date = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
price_history_obj = self.pool.get('product.price.history')
history_ids = price_history_obj.search(cr, uid, [('company_id', '=', company_id), ('product_template_id', '=', product_tmpl), ('datetime', '<=', date)], limit=1)
if history_ids:
return price_history_obj.read(cr, uid, history_ids[0], ['cost'], context=context)['cost']
return 0.0

def _set_standard_price(self, cr, uid, product_tmpl_id, value, context=None):
''' Store the standard price change in order to be able to retrieve the cost of a product template for a given date'''
if context is None:
context = {}
price_history_obj = self.pool['product.price.history']
user_company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id
company_id = context.get('force_company', user_company)
price_history_obj.create(cr, uid, {
'product_template_id': product_tmpl_id,
'cost': value,
'company_id': company_id,
}, context=context)

def _get_product_variant_count(self, cr, uid, ids, name, arg, context=None):
res = {}
for product in self.browse(cr, uid, ids, context=context):
Expand Down Expand Up @@ -724,7 +700,6 @@ def create(self, cr, uid, vals, context=None):
product_template_id = super(product_template, self).create(cr, uid, vals, context=context)
if not context or "create_product_product" not in context:
self.create_variant_ids(cr, uid, [product_template_id], context=context)
self._set_standard_price(cr, uid, product_template_id, vals.get('standard_price', 0.0), context=context)

# TODO: this is needed to set given values to first variant after creation
# these fields should be moved to product as lead to confusion
Expand All @@ -745,12 +720,6 @@ def create(self, cr, uid, vals, context=None):
return product_template_id

def write(self, cr, uid, ids, vals, context=None):
''' Store the standard price change in order to be able to retrieve the cost of a product template for a given date'''
if isinstance(ids, (int, long)):
ids = [ids]
if 'standard_price' in vals:
for prod_template_id in ids:
self._set_standard_price(cr, uid, prod_template_id, vals['standard_price'], context=context)
res = super(product_template, self).write(cr, uid, ids, vals, context=context)
if 'attribute_line_ids' in vals or vals.get('active'):
self.create_variant_ids(cr, uid, ids, context=context)
Expand Down Expand Up @@ -1184,10 +1153,44 @@ def open_product_template(self, cr, uid, ids, context=None):
'target': 'new'}

def create(self, cr, uid, vals, context=None):
ctx = dict(context or {}, create_product_product=True)
product_id = super(product_product, self).create(cr, uid, vals, context=ctx)
self._set_standard_price(cr, uid, product_id, vals.get('standard_price', 0.0), context=context)
return product_id

def write(self, cr, uid, ids, vals, context=None):
''' Store the standard price change in order to be able to retrieve the cost of a product for a given date'''
if isinstance(ids, (int, long)):
ids = [ids]
res = super(product_product, self).write(cr, uid, ids, vals, context=context)
if 'standard_price' in vals:
for product_id in ids:
self._set_standard_price(cr, uid, product_id, vals['standard_price'], context=context)
return res

def _set_standard_price(self, cr, uid, product_id, value, context=None):
''' Store the standard price change in order to be able to retrieve the cost of a product for a given date'''
if context is None:
context = {}
ctx = dict(context or {}, create_product_product=True)
return super(product_product, self).create(cr, uid, vals, context=ctx)
price_history_obj = self.pool['product.price.history']
user_company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id
company_id = context.get('force_company', user_company)
price_history_obj.create(cr, uid, {
'product_id': product_id,
'cost': value,
'company_id': company_id,
}, context=context)

def get_history_price(self, cr, uid, product_id, company_id, date=None, context=None):
if context is None:
context = {}
if date is None:
date = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
price_history_obj = self.pool.get('product.price.history')
history_ids = price_history_obj.search(cr, uid, [('company_id', '=', company_id), ('product_id', '=', product_id), ('datetime', '<=', date)], limit=1)
if history_ids:
return price_history_obj.read(cr, uid, history_ids[0], ['cost'], context=context)['cost']
return 0.0


class product_packaging(osv.osv):
Expand Down
2 changes: 1 addition & 1 deletion addons/stock_account/stock_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def _anglo_saxon_sale_move_lines(self, cr, uid, i_line, res, context=None):
to_unit = i_line.move_id.product_uom.id
price_unit = self.pool['product.uom']._compute_price(cr, uid, from_unit, price, to_uom_id=to_unit)
else:
price_unit = i_line.product_id.standard_pric
price_unit = i_line.product_id.standard_price
return [
{
'type':'src',
Expand Down
16 changes: 8 additions & 8 deletions addons/stock_account/wizard/stock_valuation_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,16 @@ def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, con
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_rec = self.pool['product.product'].read(cr, uid, product_ids, ['cost_method', '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'))
cost_method_product_ids = list(set(product['id'] for product in products_rec if product['cost_method'] != 'real'))
histories = []
if cost_method_product_tmpl_ids:
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))
if cost_method_product_ids:
cr.execute('SELECT DISTINCT ON (product_id, company_id) product_id, company_id, cost FROM product_price_history WHERE product_id in %s AND datetime <= %s ORDER BY product_id, company_id, datetime DESC', (tuple(cost_method_product_ids), date))
histories = cr.dictfetchall()
histories_dict = {}
for history in histories:
histories_dict[(history['product_template_id'], history['company_id'])] = history['cost']
histories_dict[(history['product_id'], history['company_id'])] = history['cost']
for line in res:
inv_value = 0.0
lines = group_lines.get(str(line.get('__domain', [])))
Expand All @@ -81,7 +81,7 @@ def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, con
if product['cost_method'] == 'real':
price = line_rec['price_unit_on_quant']
else:
price = histories_dict.get((product['product_tmpl_id'][0], line_rec['company_id']), 0.0)
price = histories_dict.get((product['id'], line_rec['company_id']), 0.0)
inv_value += price * line_rec['quantity']
line['inventory_value'] = inv_value
return res
Expand All @@ -90,13 +90,13 @@ def _get_inventory_value(self, cr, uid, ids, name, attr, context=None):
if context is None:
context = {}
date = context.get('history_date')
product_tmpl_obj = self.pool.get("product.template")
product_obj = self.pool.get("product.product")
res = {}
for line in self.browse(cr, uid, ids, context=context):
if line.product_id.cost_method == 'real':
res[line.id] = line.quantity * line.price_unit_on_quant
else:
res[line.id] = line.quantity * product_tmpl_obj.get_history_price(cr, uid, line.product_id.product_tmpl_id.id, line.company_id.id, date=date, context=context)
res[line.id] = line.quantity * product_obj.get_history_price(cr, uid, line.product_id.id, line.company_id.id, date=date, context=context)
return res

_columns = {
Expand Down

0 comments on commit 9ac8d98

Please sign in to comment.