[FIX] stock_account: always compute FIFO no matter the cost method

This is to ease the change of cost method.

opw 779284
This commit is contained in:
Simon Lejeune
2017-11-14 17:44:15 +01:00
parent c6c802aac6
commit 217661ab7f
2 changed files with 19 additions and 23 deletions
+18 -17
View File
@@ -235,7 +235,7 @@ class StockMove(models.Model):
break
# Update the standard price with the price of the last used candidate, if any.
if new_standard_price:
if new_standard_price and move.product_id.cost_method == 'fifo':
move.product_id.standard_price = new_standard_price
# If there's still quantity to value but we're out of candidates, we fall in the
@@ -264,29 +264,30 @@ class StockMove(models.Model):
valued_move_lines = self.move_line_ids.filtered(lambda ml: not ml.location_id._should_be_valued() and ml.location_dest_id._should_be_valued())
valued_quantity = sum(valued_move_lines.mapped('qty_done'))
if self.product_id.cost_method in ['fifo', 'average']:
price_unit = self._get_price_unit()
value = price_unit * (quantity or valued_quantity)
vals = {
'price_unit': price_unit,
'value': value if quantity is None or not self.value else self.value,
'remaining_value': value if quantity is None else self.remaining_value + value,
}
if self.product_id.cost_method == 'fifo':
vals['remaining_qty'] = valued_quantity if quantity is None else self.remaining_qty + quantity
self.write(vals)
else: # standard
# Note: we always compute the fifo `remaining_value` and `remaining_qty` fields no
# matter which cost method is set, to ease the switching of cost method.
vals = {}
price_unit = self._get_price_unit()
value = price_unit * (quantity or valued_quantity)
vals = {
'price_unit': price_unit,
'value': value if quantity is None or not self.value else self.value,
'remaining_value': value if quantity is None else self.remaining_value + value,
}
vals['remaining_qty'] = valued_quantity if quantity is None else self.remaining_qty + quantity
if self.product_id.cost_method == 'standard':
value = self.product_id.standard_price * (quantity or valued_quantity)
self.write({
vals.update({
'price_unit': self.product_id.standard_price,
'value': value if quantity is None or not self.value else self.value,
})
self.write(vals)
elif self._is_out():
valued_move_lines = self.move_line_ids.filtered(lambda ml: ml.location_id._should_be_valued() and not ml.location_dest_id._should_be_valued())
valued_quantity = sum(valued_move_lines.mapped('qty_done'))
if self.product_id.cost_method == 'fifo':
self.env['stock.move']._run_fifo(self, quantity=quantity)
elif self.product_id.cost_method in ['standard', 'average']:
self.env['stock.move']._run_fifo(self, quantity=quantity)
if self.product_id.cost_method in ['standard', 'average']:
curr_rounding = self.company_id.currency_id.rounding
value = -float_round(self.product_id.standard_price * (valued_quantity if quantity is None else quantity), precision_rounding=curr_rounding)
self.write({
@@ -2140,7 +2140,6 @@ class TestStockValuation(TransactionCase):
move1._action_done()
self.assertEqual(move1.value, 900.0)
self.assertEqual(move1.remaining_qty, 0.0) # unusedin average move
# Purchase 140 units @ 15.50 per unit
move2 = self.env['stock.move'].create({
@@ -2407,7 +2406,6 @@ class TestStockValuation(TransactionCase):
move1.quantity_done = 10.0
move1._action_done()
self.assertEqual(move1.value, -990.0) # as no move out were done for this product, fallback on the standard price
self.assertEqual(move1.remaining_qty, 0.0) # unused in average move
def test_average_negative_3(self):
""" Send goods that you don't have in stock but received and send some units before.
@@ -2433,7 +2431,6 @@ class TestStockValuation(TransactionCase):
move1._action_done()
self.assertEqual(move1.value, 100.0)
self.assertEqual(move1.remaining_qty, 0.0) # unused in average move
# send 10 products
move2 = self.env['stock.move'].create({
@@ -2467,7 +2464,6 @@ class TestStockValuation(TransactionCase):
move3._action_done()
self.assertEqual(move3.value, -100.0) # as no move out were done for this product, fallback on latest cost
self.assertEqual(move3.remaining_qty, 0.0) # unused in average move
def test_average_negative_4(self):
self.product1.product_tmpl_id.cost_method = 'average'
@@ -2491,7 +2487,6 @@ class TestStockValuation(TransactionCase):
move1._action_done()
self.assertEqual(move1.value, 100.0)
self.assertEqual(move1.remaining_qty, 0.0) # unused in average move
def test_average_negative_5(self):
self.product1.product_tmpl_id.cost_method = 'average'
@@ -2678,7 +2673,7 @@ class TestStockValuation(TransactionCase):
# ---------------------------------------------------------------------
# Change the production valuation to AVCO
# ---------------------------------------------------------------------
self.product1.with_context(debug=True).product_tmpl_id.cost_method = 'average'
self.product1.product_tmpl_id.cost_method = 'average'
# valuation should stay to ~240
self.assertAlmostEqual(self.product1.stock_value, 240, delta=0.03)