Skip to content
Snippets Groups Projects
Commit deb26bb1 authored by Yolann Sabaux's avatar Yolann Sabaux
Browse files

[FIX] stock_account: fix rounding error

Steps to reproduce:
- Define the decimal accuracy for the "Product Price" to 5
- Create a product with "cost = 0.00875"
- On-hand product = 10'000
- Change the cost to "0.00975"

Issue:
In Inventory valuation, for the product you will have two layers valued at:
- 87.5
- 12.5
Instead of:
- 87.5
- 10

Cause:
We round with currency precision

Solution:
Use the "Product Price" decimal precision as it is the case when we define a "standard_price"
https://github.com/odoo/odoo/blob/4c7ef5673b8fc28bf7fe2bc36fe2450987f15a28/addons/product/models/product.py#L110-L112



opw-2724975

closes odoo/odoo#93192

Signed-off-by: default avatarWilliam Henrotin (whe) <whe@odoo.com>
parent 530fbad5
No related branches found
No related tags found
No related merge requests found
......@@ -3,7 +3,7 @@
from odoo import api, fields, models, _
from odoo.exceptions import UserError
from odoo.tools import float_is_zero, float_repr, float_compare
from odoo.tools import float_is_zero, float_repr, float_round, float_compare
from odoo.exceptions import ValidationError
from collections import defaultdict
......@@ -227,7 +227,8 @@ class ProductProduct(models.Model):
quantity_svl = product.sudo().quantity_svl
if float_compare(quantity_svl, 0.0, precision_rounding=product.uom_id.rounding) <= 0:
continue
rounded_new_price = company_id.currency_id.round(new_price)
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)
if company_id.currency_id.is_zero(value):
......
......@@ -158,6 +158,38 @@ class TestStockValuationLayerRevaluation(TestStockValuationCommon):
self.assertEqual(layers[0].value, 200)
self.assertEqual(layers[1].value, 300)
def test_stock_valuation_layer_revaluation_avco_rounding_5_digits(self):
"""
Check that the rounding of the new price (cost) is equivalent to the rounding of the standard price (cost)
The check is done indirectly via the layers valuations.
If correct => rounding method is correct too
"""
self.product1.categ_id.property_cost_method = 'average'
self.env['decimal.precision'].search([
('name', '=', 'Product Price'),
]).digits = 5
# First Move
self.product1.write({'standard_price': 0.00875})
self._make_in_move(self.product1, 10000)
self.assertEqual(self.product1.standard_price, 0.00875)
self.assertEqual(self.product1.quantity_svl, 10000)
layer = self.product1.stock_valuation_layer_ids
self.assertEqual(layer.value, 87.5)
# Second Move
self.product1.write({'standard_price': 0.00975})
self.assertEqual(self.product1.standard_price, 0.00975)
self.assertEqual(self.product1.quantity_svl, 10000)
layers = self.product1.stock_valuation_layer_ids
self.assertEqual(layers[0].value, 87.5)
self.assertEqual(layers[1].value, 10)
def test_stock_valuation_layer_revaluation_fifo(self):
self.product1.categ_id.property_cost_method = 'fifo'
context = {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment