From 4432ce5f7fec50a5c4f0c2614edf095ca3ba015c Mon Sep 17 00:00:00 2001 From: "Guillaume (guva)" Date: Thu, 31 Mar 2022 11:25:46 +0000 Subject: [PATCH] [FIX] purchase_stock: price diff on vendor bill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Steps to reproduce: • Create Record: Product Category - Costing Method: Average - Inventory Valuation: Automated - Specify a price difference account (may create new account). - Ensure Stock Interim (Received) account is reconcilable. • Create Record: Product - Product Type: Storable - Cost Price: 1.01 - Product Category: New Product Category • Create bill with this product, for a quantity of 10.5 -> The is price difference of 0.1 Issue comes from this commit 286ea6b681e9ba77357f91b546052449f6342f20 which doesn't round if there is a discount. With this commit we isolate the latter case in order to keep the price unit rounded if there is no discount. closes odoo/odoo#88734 X-original-commit: 643d91ef5ebfb29fde142294ced82c470d42c136 Signed-off-by: Florian Gilbert --- .../purchase_stock/models/account_invoice.py | 24 ++++++++++-------- .../tests/test_stockvaluation.py | 25 +++++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/addons/purchase_stock/models/account_invoice.py b/addons/purchase_stock/models/account_invoice.py index 11379d07eb6..10d59919286 100644 --- a/addons/purchase_stock/models/account_invoice.py +++ b/addons/purchase_stock/models/account_invoice.py @@ -99,16 +99,20 @@ class AccountMove(models.Model): price_unit = line.price_unit * (1 - (line.discount or 0.0) / 100.0) - if line.tax_ids 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 + 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'] 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 bfac6f40052..92de86ffb1c 100644 --- a/addons/purchase_stock/tests/test_stockvaluation.py +++ b/addons/purchase_stock/tests/test_stockvaluation.py @@ -1276,3 +1276,28 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon): self.assertEqual(len(input_aml), 2, "Only two lines should have been generated in stock input account: one when receiving the product, one when making the invoice.") self.assertAlmostEqual(sum(input_aml.mapped('debit')), 90, "Total debit value on stock input account should be equal to the original PO price of the product.") self.assertAlmostEqual(sum(input_aml.mapped('credit')), 90, "Total credit value on stock input account should be equal to the original PO price of the product.") + + def test_anglosaxon_valuation_price_unit_diff_avco(self): + """ + Inv: price unit: 100 + """ + self.env.company.anglo_saxon_accounting = True + self.product1.categ_id.property_cost_method = 'average' + 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 = 1.01 + + 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': 10.50, 'price_unit': 1.01, '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), 0, "No line should have been generated in the price difference account.")