[FIX] Change price history and stock valuation report to standard_price 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.
This commit is contained in:
+37
-34
@@ -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'),
|
||||
}
|
||||
@@ -418,30 +418,6 @@ class product_template(osv.osv):
|
||||
|
||||
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):
|
||||
@@ -724,7 +700,6 @@ class product_template(osv.osv):
|
||||
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
|
||||
@@ -745,12 +720,6 @@ class product_template(osv.osv):
|
||||
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)
|
||||
@@ -1184,10 +1153,44 @@ class product_product(osv.osv):
|
||||
'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):
|
||||
|
||||
@@ -83,7 +83,7 @@ class account_invoice_line(osv.osv):
|
||||
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',
|
||||
|
||||
@@ -62,16 +62,16 @@ class stock_history(osv.osv):
|
||||
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', [])))
|
||||
@@ -81,7 +81,7 @@ class stock_history(osv.osv):
|
||||
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
|
||||
@@ -90,13 +90,13 @@ class stock_history(osv.osv):
|
||||
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 = {
|
||||
|
||||
Reference in New Issue
Block a user