diff --git a/addons/stock_account/models/product.py b/addons/stock_account/models/product.py index 8ff09ba1ee7dc47491a4f9c46de87b9d84dc84f2..07aadea626e1ba624d0765a8abd5e9912c6706c5 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 0db6ec7e9527c7bc85640e8c3d251c1b41094ef5..13e0cd15c2b118c74bc361bf63a05599ca5ea9f1 100644 --- a/addons/stock_account/tests/test_stockvaluation.py +++ b/addons/stock_account/tests/test_stockvaluation.py @@ -2087,7 +2087,7 @@ class TestStockValuation(SavepointCase): 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(SavepointCase): 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 c05f90429238221ab4ffc2283110446612966a49..df804b3c57fbdb31b6c09d7e44692cf103f6ef07 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): + move1 = self._make_in_move(self.product1, 1, unit_cost=1.00) + move2 = self._make_in_move(self.product1, 1, unit_cost=1.00) + move3 = self._make_in_move(self.product1, 1, unit_cost=1.01) + + self.assertAlmostEqual(self.product1.value_svl, 3.01) + + move4 = 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):