diff --git a/addons/stock_account/models/product.py b/addons/stock_account/models/product.py index 7a91a181693..3acfe3cc35f 100644 --- a/addons/stock_account/models/product.py +++ b/addons/stock_account/models/product.py @@ -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 diff --git a/addons/stock_account/tests/test_stockvaluation.py b/addons/stock_account/tests/test_stockvaluation.py index bebe8b9ecb5..3e4d7cb3441 100644 --- a/addons/stock_account/tests/test_stockvaluation.py +++ b/addons/stock_account/tests/test_stockvaluation.py @@ -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' diff --git a/addons/stock_account/tests/test_stockvaluationlayer.py b/addons/stock_account/tests/test_stockvaluationlayer.py index 6b11f29dc10..0e3b1062a3c 100644 --- a/addons/stock_account/tests/test_stockvaluationlayer.py +++ b/addons/stock_account/tests/test_stockvaluationlayer.py @@ -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):