[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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user