[FIX] purchase: fifo_price.yml

bzr revid: qdp-launchpad@openerp.com-20130903162757-p3rquk1uap0qz8qb
This commit is contained in:
Quentin (OpenERP) 2013-09-03 18:27:57 +02:00
parent 5ef4e485ff
commit e7d5622c7e
3 changed files with 44 additions and 17 deletions

View File

@ -88,7 +88,7 @@
picking_id: outgoing_fifo_shipment
product_id: product_fifo_icecream
product_uom: product.product_uom_kgm
product_qty: 20.0
product_uom_qty: 20.0
location_id: stock.stock_location_stock
location_dest_id: stock.stock_location_customers
picking_type_id: stock.picking_type_out
@ -107,7 +107,7 @@
Check product standard price changed to 65.0 (because last outgoing shipment was made of 10 kg at 50€ and 10 kg at 80€)
-
!python {model: product.product}: |
assert self.browse(cr, uid, ref("product_fifo_icecream")).standard_price == 65.0
assert self.browse(cr, uid, ref("product_fifo_icecream")).standard_price == 65.0, "Product price not updated accordingly. %s found instead of 65" %(self.browse(cr, uid, ref("product_fifo_icecream")).standard_price,)
-
Do a delivery of an extra 500 g (delivery order)
-
@ -122,7 +122,7 @@
product_uom: product.product_uom_gram
location_id: stock.stock_location_stock
location_dest_id: stock.stock_location_customers
product_qty: 500.0
product_uom_qty: 500.0
picking_type_id: stock.picking_type_out
-
I assign this outgoing shipment
@ -139,7 +139,7 @@
Check product price changed to 80.0 (because last outgoing shipment was made of 0.5 kg at 80€)
-
!python {model: product.product}: |
assert self.browse(cr, uid, ref("product_fifo_icecream")).standard_price == 80.0
assert self.browse(cr, uid, ref("product_fifo_icecream")).standard_price == 80.0, "Product price not updated accordingly. %s found instead of 80" %(self.browse(cr, uid, ref("product_fifo_icecream")).standard_price,)
-
We will temporarily change the currency rate on the sixth of June to have the same results all year
-
@ -204,7 +204,7 @@
picking_id: outgoing_fifo_shipment_cur
product_id: product_fifo_icecream
product_uom: product.product_uom_kgm
product_qty: 49.5
product_uom_qty: 49.5
location_id: stock.stock_location_stock
location_dest_id: stock.stock_location_customers
picking_type_id: stock.picking_type_out
@ -223,7 +223,7 @@
Check rounded price is 102 euro (because last outgoing shipment was made of 19.5kg at 80€ and 30kg at $150 (rate=1.2834)
-
!python {model: product.product}: |
assert round(self.browse(cr, uid, ref("product_fifo_icecream")).standard_price) == 102, "Price after doing other currency is wrong"
assert round(self.browse(cr, uid, ref("product_fifo_icecream")).standard_price) == 102, "Product price not updated accordingly. %s found instead of 102 (rounded values)" %(round(self.browse(cr, uid, ref("product_fifo_icecream")).standard_price),)
-
Do a delivery of an extra 10 kg
-
@ -236,7 +236,7 @@
picking_id: outgoing_fifo_shipment_ret
product_id: product_fifo_icecream
product_uom: product.product_uom_kgm
product_qty: 10.0
product_uom_qty: 10.0
location_id: stock.stock_location_stock
location_dest_id: stock.stock_location_customers
picking_type_id: stock.picking_type_out
@ -255,7 +255,7 @@
Check rounded price is 150.0 / 1.2834
-
!python {model: product.product}: |
assert round(self.browse(cr, uid, ref("product_fifo_icecream")).standard_price) == round(150.0 / 1.2834)
assert round(self.browse(cr, uid, ref("product_fifo_icecream")).standard_price) == round(150.0 / 1.2834), "Product price not updated accordingly. %s found instead of %s" %(self.browse(cr, uid, ref("product_fifo_icecream")).standard_price, round(150.0/1.2834))
-
Let us create some outs to get negative stock. Create outpicking. We create delivery order of 200 kg, but will pick only 100 kg
-
@ -268,7 +268,7 @@
picking_id: outgoing_fifo_shipment_neg
product_id: product_fifo_icecream
product_uom: product.product_uom_kgm
product_qty: 200.0
product_uom_qty: 200.0
location_id: stock.stock_location_stock
location_dest_id: stock.stock_location_customers
picking_type_id: stock.picking_type_out
@ -284,7 +284,7 @@
picking_id: outgoing_fifo_shipment_neg2
product_id: product_fifo_icecream
product_uom: product.product_uom_kgm
product_qty: 400.0
product_uom_qty: 400.0
location_id: stock.stock_location_stock
location_dest_id: stock.stock_location_customers
picking_type_id: stock.picking_type_out
@ -323,7 +323,7 @@
Assert price on product is still the old price as the out move has not been received fully yet
-
!python {model: product.product}: |
assert round(self.browse(cr, uid, ref("product_fifo_icecream")).standard_price) == round(150.0 / 1.2834)
assert round(self.browse(cr, uid, ref("product_fifo_icecream")).standard_price) == round(150.0 / 1.2834), 'The product price should not have been updated'
-
Receive purchase order with 60 kg FIFO Ice Cream at 80 euro/kg
-
@ -351,4 +351,4 @@
The price of the product should have changed back to 65.0
-
!python {model: product.product}: |
assert self.browse(cr, uid, ref("product_fifo_icecream")).standard_price == 65.0
assert self.browse(cr, uid, ref("product_fifo_icecream")).standard_price == 65.0, "Product price not updated accordingly. %s found instead of 65" %(self.browse(cr, uid, ref("product_fifo_icecream")).standard_price,)

View File

@ -231,6 +231,7 @@ class stock_quant(osv.osv):
result += self._quants_get_lifo(cr, uid, location, product, qty, domain, prefered_order=prefered_order, context=context)
else:
raise osv.except_osv(_('Error!'), _('Removal strategy %s not implemented.' % (removal_strategy,)))
print 'Quant get result', result
return result
#
@ -241,7 +242,7 @@ class stock_quant(osv.osv):
def _quant_create(self, cr, uid, qty, move, lot_id = False, context=None):
# FP Note: TODO: compute the right price according to the move, with currency convert
# QTY is normally already converted to main product's UoM
price_unit = move.price_unit
price_unit = self.pool.get('stock.move').get_price_unit(cr, uid, move, context=context)
vals = {
'product_id': move.product_id.id,
'location_id': move.location_dest_id.id,
@ -253,7 +254,6 @@ class stock_quant(osv.osv):
'lot_id': lot_id,
}
negative_quant_id = False
if move.location_id.usage == 'internal':
#if we were trying to move something from an internal location and reach here (quant creation),
#it means that a negative quant has to be created as well.
@ -262,9 +262,9 @@ class stock_quant(osv.osv):
negative_vals['qty'] = -qty
negative_vals['cost'] = price_unit
negative_quant_id = self.create(cr, uid, negative_vals, context=context)
vals.update({'propagated_from_id': negative_quant_id})
#create the quant
vals.update({'propagated_from_id': negative_quant_id})
quant_id = self.create(cr, uid, vals, context=context)
return self.browse(cr, uid, quant_id, context=context)
@ -975,6 +975,10 @@ class stock_move(osv.osv):
_order = 'date_expected desc, id'
_log_create = False
def get_price_unit(self, cr, uid, move, context=None):
""" Returns the unit price to store on the move """
return move.price_unit or move.product_id.standard_price
def name_get(self, cr, uid, ids, context=None):
res = []
for line in self.browse(cr, uid, ids, context=context):
@ -1497,7 +1501,7 @@ class stock_move(osv.osv):
for move in self.browse(cr, uid, ids, context=context):
if move.picking_id:
pickings.add(move.picking_id.id)
qty = move.product_uom_qty
qty = move.product_qty
# for qty, location_id in move_id.prefered_location_ids:
# quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, qty, context=context)

View File

@ -70,7 +70,6 @@ class stock_quant(osv.osv):
return line.cost * line.qty
return super(stock_quant, self)._get_inventory_value(cr, uid, line, prodbrow, context=context)
# FP Note: this is where we should post accounting entries for adjustment
def _price_update(self, cr, uid, quant, newprice, context=None):
super(stock_quant, self)._price_update(cr, uid, quant, newprice, context=context)
@ -198,4 +197,28 @@ class stock_quant(osv.osv):
return move_obj.create(cr, uid, {'journal_id': journal_id,
'line_id': move_lines,
'ref': move.picking_id and move.picking_id.name}, context=context)
class stock_move(osv.osv):
_inherit = "stock.move"
def action_done(self, cr, uid, ids, context=None):
super(stock_move, self).action_done(cr, uid, ids, context=context)
self.product_price_update(cr, uid, ids, context=context)
def product_price_update(self, cr, uid, ids, context=None):
'''
This method adapts the price on the product when necessary (if the cost_method is 'real'), so that a return or an inventory loss is made using the last value used for an outgoing valuation.
'''
product_obj = self.pool.get('product.product')
for move in self.browse(cr, uid, ids, context=context):
if move.product_id.cost_method == 'real' and move.location_dest_id.usage != 'internal':
if any([q.qty <= 0 for q in move.quant_ids]):
#if there is a negative quant, the standard price shouldn't be updated
continue
#get the average price of the move
#Note: here we can't use the quant.cost directly as we may have moved out 2 units (1 unit to 5€ and 1 unit to 7€) and in case of a product return of 1 unit, we can't know which of the 2 cost has to be used (5€ or 7€?). So at that time, thanks to the average valuation price we are storing we will svaluate it at 6€
average_valuation_price = 0.0
for q in move.quant_ids:
average_valuation_price += q.qty * q.cost
average_valuation_price = average_valuation_price / move.product_qty
product_obj.write(cr, uid, move.product_id.id, {'standard_price': average_valuation_price}, context=context)
self.write(cr, uid, move.id, {'price_unit': average_valuation_price}, context=context)