From 75245f476537c2b8f00f25264a7a9df77201065d Mon Sep 17 00:00:00 2001 From: "Andrea Grazioso (agr-odoo)" Date: Tue, 17 May 2022 15:11:40 +0000 Subject: [PATCH] [FIX] purchase_stock: wrong amount in price difference account 1. Activate anglo saxon accounting 2. Create product with automated inventory valuation and standard pricing 3. Set decimal accuracy to 6 4. Set product cost price to 0,01719 5. Create PO for 30.000 items -> price = 0,01782 -> total = 534,6 6. Receive goods -> stock journal entry = 515,7 (based on the cost, ok) 7. Create vendor bill Price difference is incorrect if you have a tax rate in the vendor bill `price_unit_val_dif` will be rounded to 0.02 Multiplied by a great quantity the result will be wrong (84.30) Without using the tax rate the price difference amount is the expected one This commit partially revert 643d91ef5ebfb29fde142294ced82c470d42c136 to improve the original fix. opw-2849074 closes odoo/odoo#94346 X-original-commit: 315a18f12f9d67284bbd8b027ca652db17aae9d2 Signed-off-by: Laurent Smet Signed-off-by: Grazioso Andrea (agr) --- .../purchase_stock/models/account_invoice.py | 23 +++++++--------- .../tests/test_stockvaluation.py | 27 +++++++++++++++++++ 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/addons/purchase_stock/models/account_invoice.py b/addons/purchase_stock/models/account_invoice.py index 10d59919286..a64176b4b8d 100644 --- a/addons/purchase_stock/models/account_invoice.py +++ b/addons/purchase_stock/models/account_invoice.py @@ -100,19 +100,16 @@ class AccountMove(models.Model): price_unit = line.price_unit * (1 - (line.discount or 0.0) / 100.0) if line.tax_ids: - if line.discount and line.quantity: - # We do not want to round the price unit since : - # - It does not follow the currency precision - # - It may include a discount - # Since compute_all still rounds the total, we use an ugly workaround: - # multiply then divide the price unit. - price_unit *= line.quantity - price_unit = line.tax_ids.with_context(round=False, force_sign=move._get_tax_force_sign()).compute_all( - price_unit, currency=move.currency_id, quantity=1.0, is_refund=move.move_type == 'in_refund')['total_excluded'] - price_unit /= line.quantity - else: - price_unit = line.tax_ids.compute_all( - price_unit, currency=move.currency_id, quantity=1.0, is_refund=move.move_type == 'in_refund')['total_excluded'] + # We do not want to round the price unit since : + # - It does not follow the currency precision + # - It may include a discount + # Since compute_all still rounds the total, we use an ugly workaround: + # shift the decimal part using a fixed quantity to avoid rounding issues + prec = 1e+6 + price_unit *= prec + price_unit = line.tax_ids.with_context(round=False, force_sign=move._get_tax_force_sign()).compute_all( + price_unit, currency=move.currency_id, quantity=1.0, is_refund=move.move_type == 'in_refund')['total_excluded'] + price_unit /= prec price_unit_val_dif = price_unit - valuation_price_unit price_subtotal = line.quantity * price_unit_val_dif diff --git a/addons/purchase_stock/tests/test_stockvaluation.py b/addons/purchase_stock/tests/test_stockvaluation.py index 799ab741855..83b7e43725b 100644 --- a/addons/purchase_stock/tests/test_stockvaluation.py +++ b/addons/purchase_stock/tests/test_stockvaluation.py @@ -1299,3 +1299,30 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon): # Check if something was posted in the price difference account price_diff_aml = invoice.line_ids.filtered(lambda l: l.account_id == self.price_diff_account) self.assertEqual(len(price_diff_aml), 0, "No line should have been generated in the price difference account.") + + def test_anglosaxon_valuation_price_unit_diff_standard(self): + """ + Check the price unit difference account is hit with the correct amount + """ + self.env.ref("product.decimal_price").digits = 6 + self.env.company.anglo_saxon_accounting = True + self.product1.categ_id.property_cost_method = 'standard' + self.product1.categ_id.property_valuation = 'real_time' + self.product1.categ_id.property_account_creditor_price_difference_categ = self.price_diff_account + self.product1.standard_price = 0.01719 + + invoice = self.env['account.move'].create({ + 'move_type': 'in_invoice', + 'invoice_date': '2022-03-31', + 'partner_id': self.partner_id.id, + 'invoice_line_ids': [ + (0, 0, {'product_id': self.product1.id, 'quantity': 30000, 'price_unit': 0.01782, 'tax_ids': self.tax_purchase_a.ids}) + ] + }) + + invoice.action_post() + + # Check if something was posted in the price difference account + price_diff_aml = invoice.line_ids.filtered(lambda l: l.account_id == self.price_diff_account) + self.assertEqual(len(price_diff_aml), 1, "A line should have been generated in the price difference account.") + self.assertAlmostEqual(price_diff_aml.balance, 18.90)