diff --git a/addons/stock_landed_costs/models/stock_landed_cost.py b/addons/stock_landed_costs/models/stock_landed_cost.py index 563b8cf0239..a125f85fdff 100644 --- a/addons/stock_landed_costs/models/stock_landed_cost.py +++ b/addons/stock_landed_costs/models/stock_landed_cost.py @@ -205,9 +205,9 @@ class StockLandedCost(models.Model): AdjustementLines = self.env['stock.valuation.adjustment.lines'] AdjustementLines.search([('cost_id', 'in', self.ids)]).unlink() - digits = self.env['decimal.precision'].precision_get('Product Price') towrite_dict = {} for cost in self.filtered(lambda cost: cost._get_targeted_move_ids()): + rounding = cost.currency_id.rounding total_qty = 0.0 total_cost = 0.0 total_weight = 0.0 @@ -224,7 +224,7 @@ class StockLandedCost(models.Model): former_cost = val_line_values.get('former_cost', 0.0) # round this because former_cost on the valuation lines is also rounded - total_cost += tools.float_round(former_cost, precision_digits=digits) if digits else former_cost + total_cost += cost.currency_id.round(former_cost) total_line += 1 @@ -250,8 +250,8 @@ class StockLandedCost(models.Model): else: value = (line.price_unit / total_line) - if digits: - value = tools.float_round(value, precision_digits=digits, rounding_method='UP') + if rounding: + value = tools.float_round(value, precision_rounding=rounding, rounding_method='UP') fnc = min if line.price_unit > 0 else max value = fnc(value, line.price_unit - value_split) value_split += value diff --git a/addons/stock_landed_costs/tests/test_stock_landed_costs_rounding.py b/addons/stock_landed_costs/tests/test_stock_landed_costs_rounding.py index 1ec148c2c3a..9ced6d0976c 100644 --- a/addons/stock_landed_costs/tests/test_stock_landed_costs_rounding.py +++ b/addons/stock_landed_costs/tests/test_stock_landed_costs_rounding.py @@ -2,7 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo.addons.stock_landed_costs.tests.common import TestStockLandedCostsCommon -from odoo.tests import tagged +from odoo.tests import tagged, Form @tagged('post_install', '-at_install') @@ -152,3 +152,53 @@ class TestStockLandedCostsRounding(TestStockLandedCostsCommon): # I check that the landed cost is now "Closed" and that it has an accounting entry self.assertEqual(stock_landed_cost_3.state, 'done') self.assertTrue(stock_landed_cost_3.account_move_id) + + def test_stock_landed_costs_rounding_02(self): + """ The landed costs should be correctly computed, even when the decimal accuracy + of the deciaml price is increased. """ + self.env.ref("product.decimal_price").digits = 4 + + fifo_pc = self.env['product.category'].create({ + 'name': 'Fifo Category', + 'parent_id': self.env.ref("product.product_category_all").id, + 'property_valuation': 'real_time', + 'property_cost_method': 'fifo', + }) + + products = self.Product.create([{ + 'name': 'Super Product %s' % price, + 'categ_id': fifo_pc.id, + 'type': 'product', + 'standard_price': price, + } for price in [0.91, 0.93, 75.17, 20.54]]) + + landed_product = self.Product.create({ + 'name': 'Landed Costs', + 'type': 'service', + 'landed_cost_ok': True, + 'split_method_landed_cost': 'by_quantity', + 'standard_price': 1000.0, + }) + + po = self.env['purchase.order'].create({ + 'partner_id': self.partner_a.id, + 'order_line': [(0, 0, { + 'product_id': product.id, + 'product_qty': qty, + 'price_unit': product.standard_price, + }) for product, qty in zip(products, [6, 6, 3, 6])] + }) + po.button_confirm() + + res_dict = po.picking_ids.button_validate() + validate_wizard = Form(self.env[(res_dict.get('res_model'))].with_context(res_dict.get('context'))).save() + validate_wizard.process() + + lc_form = Form(self.LandedCost) + lc_form.picking_ids.add(po.picking_ids) + with lc_form.cost_lines.new() as line: + line.product_id = landed_product + lc = lc_form.save() + lc.compute_landed_cost() + + self.assertEqual(sum(lc.valuation_adjustment_lines.mapped('additional_landed_cost')), 1000.0)