[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#93257 X-original-commit: deb26bb1182682a5071287ae313064801d080607 Signed-off-by: William Henrotin (whe) <whe@odoo.com> Signed-off-by: Yolann Sabaux (yosa) <yosa@odoo.com>
This commit is contained in:
@@ -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 = {
|
||||
|
||||
Reference in New Issue
Block a user