[FIX] stock_account: fix valuate empty stock.

To reproduce, product A in AVCO:
- Buy 2 product A at 1.00 $
- Buy 1 product A at 1.01 $
- Sell 3 product A.
- The stock valuation won't be correct: still remain 0.01 in
stock without quantity and the svl related to the sell
have a value of 3.00 (instead of 3.01)

To fix:
In case of AVCO, add the rounding error value to the out
stock move layer.

closes odoo/odoo#65117

X-original-commit: f6b019fcfdd35a693e8af43ae38d10e31e96284a
Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>
This commit is contained in:
Rémy Voet (ryv)
2021-01-27 12:56:08 +00:00
committed by William Henrotin
parent 6328d4307b
commit 8a1a825d57
3 changed files with 38 additions and 1 deletions
+6
View File
@@ -185,6 +185,12 @@ class ProductProduct(models.Model):
if self.cost_method in ('average', 'fifo'):
fifo_vals = self._run_fifo(abs(quantity), company)
vals['remaining_qty'] = fifo_vals.get('remaining_qty')
# in case of AVCO, fix rounding issue of standard price when needed.
if self.cost_method == 'average':
rounding_error = self.standard_price * self.quantity_svl - self.value_svl
vals['value'] += self.env.company.currency_id.round(rounding_error)
if self.quantity_svl:
vals['unit_cost'] = self.value_svl / self.quantity_svl
if self.cost_method == 'fifo':
vals.update(fifo_vals)
return vals
@@ -2087,7 +2087,7 @@ class TestStockValuation(TransactionCase):
move5.move_line_ids.qty_done = 30.0
move5._action_done()
self.assertEqual(move5.stock_valuation_layer_ids.value, -477.6)
self.assertEqual(move5.stock_valuation_layer_ids.value, -477.5)
# Receives 10 units but assign them to an owner, the valuation should not be impacted.
move6 = self.env['stock.move'].create({
@@ -2107,6 +2107,24 @@ class TestStockValuation(TransactionCase):
self.assertEqual(move6.stock_valuation_layer_ids.value, 0)
# Sale 50 units @ $19.50 per unit (no stock anymore)
move7 = self.env['stock.move'].create({
'name': '50 units @ $19.50 per unit',
'location_id': self.stock_location.id,
'location_dest_id': self.customer_location.id,
'product_id': self.product1.id,
'product_uom': self.uom_unit.id,
'product_uom_qty': 50.0,
})
move7._action_confirm()
move7._action_assign()
move7.move_line_ids.qty_done = 50.0
move7._action_done()
self.assertEqual(move7.stock_valuation_layer_ids.value, -796.0)
self.assertAlmostEqual(self.product1.quantity_svl, 0.0)
self.assertAlmostEqual(self.product1.value_svl, 0.0)
def test_average_perpetual_2(self):
self.product1.categ_id.property_cost_method = 'average'
@@ -485,6 +485,19 @@ class TestStockValuationAVCO(TestStockValuationCommon):
self.assertEqual(self.product1.quantity_svl, 2)
self.assertEqual(self.product1.standard_price, 15)
def test_rounding_1(self):
self._make_in_move(self.product1, 1, unit_cost=1.00)
self._make_in_move(self.product1, 1, unit_cost=1.00)
self._make_in_move(self.product1, 1, unit_cost=1.01)
self.assertAlmostEqual(self.product1.value_svl, 3.01)
self._make_out_move(self.product1, 3, create_picking=True)
self.assertEqual(self.product1.value_svl, 0)
self.assertEqual(self.product1.quantity_svl, 0)
self.assertEqual(self.product1.standard_price, 1.00)
class TestStockValuationFIFO(TestStockValuationCommon):
def setUp(self):