[FIX] stock_account: AVCO manual price change Rounding error

## To reproduce:
=> Import 5 units of P1 at $5
=> Import 2 units of P1 at $2
----> Current valuation: Qty 7, Value $37, Std Price $5.29 (rounded)
=> Change standard Price to 7
----> Current valuation: Qty 7, Value $48.97, Std Price $7

## Solution:
To compute the value delta, we don't use the current standard_price (which may be rounded), but the current value_svl.

OPW-3233260

closes odoo/odoo#115574

X-original-commit: 07ad8744a37a3e8d5a665a452f050e0dfacc6917
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Signed-off-by: David <dafr@odoo.com>
This commit is contained in:
David (dafr)
2023-03-17 09:32:48 +01:00
parent 986cba50c4
commit fa7be055dc
2 changed files with 17 additions and 4 deletions
+4 -4
View File
@@ -236,16 +236,16 @@ class ProductProduct(models.Model):
svl_vals_list = []
company_id = self.env.company
price_unit_prec = self.env['decimal.precision'].precision_get('Product Price')
rounded_new_price = float_round(new_price, precision_digits=price_unit_prec)
for product in self:
if product.cost_method not in ('standard', 'average'):
continue
quantity_svl = product.sudo().quantity_svl
if float_compare(quantity_svl, 0.0, precision_rounding=product.uom_id.rounding) <= 0:
continue
digits = self.env['decimal.precision'].precision_get('Product Price')
rounded_new_price = float_round(new_price, precision_digits=digits)
diff = rounded_new_price - product.standard_price
value = company_id.currency_id.round(quantity_svl * diff)
value_svl = product.sudo().value_svl
value = company_id.currency_id.round((rounded_new_price * quantity_svl) - value_svl)
if company_id.currency_id.is_zero(value):
continue
@@ -3968,3 +3968,16 @@ class TestStockValuation(TransactionCase):
self.assertEqual(self.product1.quantity_svl, 12)
move.quantity_done = 2
self.assertEqual(self.product1.quantity_svl, 24)
def test_average_manual_price_change(self):
"""
When doing a Manual Price Change, an SVL is created to update the value_svl.
This test check that the value of this SVL is correct and does result in new_std_price * quantity.
To do so, we create 2 In moves, which result in a standard price rounded at $5.29, the non-rounded value ≃ 5.2857.
Then we update the standard price to $7
"""
self.product1.categ_id.property_cost_method = 'average'
self._make_in_move(self.product1, 5, unit_cost=5)
self._make_in_move(self.product1, 2, unit_cost=6)
self.product1.write({'standard_price': 7})
self.assertEqual(self.product1.value_svl, 49)