[FIX] stock_account: SVL unit price precision

Steps to reproduce:
- Increase decimal accuracy of product price (eg: to 4)
- Create a product with fifo automated valuation and price of 280.8475
- Confirm a sale order of that product and Confirm stock picking
- Create a return on the stock picking

Bug:
rounding error on the stock valuation

Fix:
do not round unit price on currency rounding

opw-2988071

closes odoo/odoo#110112

Signed-off-by: William Henrotin (whe) <whe@odoo.com>
This commit is contained in:
Walid HANNICHE (waha)
2023-01-26 10:16:55 +01:00
parent 2a5b80a6d4
commit 7e0e711e31
3 changed files with 18 additions and 3 deletions
+2 -2
View File
@@ -5,7 +5,7 @@ from collections import defaultdict
from odoo import api, fields, models, _
from odoo.exceptions import UserError
from odoo.tools import float_is_zero, OrderedSet
from odoo.tools import float_is_zero, float_round, OrderedSet
import logging
_logger = logging.getLogger(__name__)
@@ -48,7 +48,7 @@ class StockMove(models.Model):
layers = self.origin_returned_move_id.sudo().stock_valuation_layer_ids
layers |= layers.stock_valuation_layer_ids
quantity = sum(layers.mapped("quantity"))
return layers.currency_id.round(sum(layers.mapped("value")) / quantity) if not float_is_zero(quantity, precision_rounding=layers.uom_id.rounding) else 0
return float_round(sum(layers.mapped("value")) / quantity, precision_digits=precision) if not float_is_zero(quantity, precision_rounding=layers.uom_id.rounding) else 0
return price_unit if not float_is_zero(price_unit, precision) or self._should_force_price_unit() else self.product_id.standard_price
@api.model
@@ -21,7 +21,7 @@ class StockValuationLayer(models.Model):
quantity = fields.Float('Quantity', readonly=True, digits='Product Unit of Measure')
uom_id = fields.Many2one(related='product_id.uom_id', readonly=True, required=True)
currency_id = fields.Many2one('res.currency', 'Currency', related='company_id.currency_id', readonly=True, required=True)
unit_cost = fields.Monetary('Unit Value', readonly=True, group_operator=None)
unit_cost = fields.Float('Unit Value', digits='Product Price', readonly=True, group_operator=None)
value = fields.Monetary('Total Value', readonly=True)
remaining_qty = fields.Float(readonly=True, digits='Product Unit of Measure')
remaining_value = fields.Monetary('Remaining Value', readonly=True)
@@ -1000,6 +1000,21 @@ class TestStockValuationChangeValuation(TestStockValuationCommon):
self.assertEqual(len(self.product1.stock_valuation_layer_ids.mapped('account_move_id')), 2)
self.assertEqual(len(self.product1.stock_valuation_layer_ids), 3)
def test_return_delivery_fifo(self):
self.product1.product_tmpl_id.categ_id.property_cost_method = 'fifo'
self.env['decimal.precision'].search([
('name', '=', 'Product Price'),
]).digits = 4
self.product1.standard_price = 280.8475
move1 = self._make_out_move(self.product1, 4, create_picking=True, force_assign=True)
move2 = self._make_return(move1, 4)
for move in [move1, move2]:
self.assertEqual(len(move.stock_valuation_layer_ids), 1)
self.assertAlmostEqual(move.stock_valuation_layer_ids.unit_cost, self.product1.standard_price)
self.assertAlmostEqual(abs(move.stock_valuation_layer_ids.value), 1123.39)
@tagged('post_install', '-at_install')
class TestAngloSaxonAccounting(AccountTestInvoicingCommon):
@classmethod