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)