From c1d1721b5d8e35fade9cdac8d2241a55d73e5f35 Mon Sep 17 00:00:00 2001 From: Sven Fuehr Date: Mon, 27 Nov 2023 14:28:02 +0100 Subject: [PATCH] [REV] account: "Total" in company currency on invoice analysis Due to performance reasons a previous commit was reverted. This reverts commit 28004b7e92f22cf0f0078d4512f8a5f59c82122c. The reverted commit i.e. converted the "Total" measure to company currency (at the time of the invoice). The query to do this (correctly) had performance issues. task-3613358 X-original-commit: a0121dcc72eb99519ae291e48e4e03a091b234df Part-of: odoo/odoo#144065 --- .../account/report/account_invoice_report.py | 36 ++----------------- .../tests/test_account_invoice_report.py | 29 ++++----------- 2 files changed, 9 insertions(+), 56 deletions(-) diff --git a/addons/account/report/account_invoice_report.py b/addons/account/report/account_invoice_report.py index 44656840d4b..a4f5ee9ba3a 100644 --- a/addons/account/report/account_invoice_report.py +++ b/addons/account/report/account_invoice_report.py @@ -67,21 +67,7 @@ class AccountInvoiceReport(models.Model): @property def _table_query(self): - return '%s %s %s %s' % (self._with(), self._select(), self._from(), self._where()) - - @api.model - def _with(self): - return f''' - WITH company_currencies - AS MATERIALIZED - -- The table res_currency_rate only contains the individual dates where the currency rates changes (start date). - -- The following table is similar but i.e. also contains an end date for each rate (the start date of the next rate - -- or NULL if it is the last rate change). - -- It is used to convert the value line.price_total to currency line.company_currency_id with conversion date line.date - (SELECT * - FROM ({self.env['res.currency']._select_companies_rates()}) AS all_company_currencies - WHERE currency_id IN (SELECT id FROM res_currency currency WHERE currency.active)) - ''' + return '%s %s %s' % (self._select(), self._from(), self._where()) @api.model def _select(self): @@ -109,14 +95,7 @@ class AccountInvoiceReport(models.Model): line.quantity / NULLIF(COALESCE(uom_line.factor, 1) / COALESCE(uom_template.factor, 1), 0.0) * (CASE WHEN move.move_type IN ('in_invoice','out_refund','in_receipt') THEN -1 ELSE 1 END) AS quantity, -line.balance * currency_table.rate AS price_subtotal, - -- line.price_total needs to be converted to line.company_currency_id (using the rate at the time of the invoice), - -- get the correct sign and be converted to the currency of the active company (using the rate from today) - ROUND(line.price_total - * (CASE WHEN move.move_type IN ('in_invoice','out_refund','in_receipt') THEN -1 ELSE 1 END) - * COALESCE(company_currency_conversion.rate, 1.0) - / COALESCE(line_currency_conversion.rate, 1.0) - , company_currency.decimal_places) - * currency_table.rate + line.price_total * (CASE WHEN move.move_type IN ('in_invoice','out_refund','in_receipt') THEN -1 ELSE 1 END) AS price_total, -COALESCE( -- Average line price @@ -140,17 +119,6 @@ class AccountInvoiceReport(models.Model): INNER JOIN account_move move ON move.id = line.move_id LEFT JOIN res_partner commercial_partner ON commercial_partner.id = move.commercial_partner_id JOIN {currency_table} ON currency_table.company_id = line.company_id - LEFT JOIN company_currencies line_currency_conversion ON - line.currency_id = line_currency_conversion.currency_id - AND line.company_id = line_currency_conversion.company_id - AND COALESCE(line.date, NOW()) >= line_currency_conversion.date_start - AND (line_currency_conversion.date_end IS NULL OR line_currency_conversion.date_end > COALESCE(line.date, NOW())) - LEFT JOIN company_currencies company_currency_conversion ON - line.company_currency_id = company_currency_conversion.currency_id - AND line.company_id = company_currency_conversion.company_id - AND COALESCE(line.date, NOW()) >= company_currency_conversion.date_start - AND (company_currency_conversion.date_end IS NULL OR company_currency_conversion.date_end > COALESCE(line.date, NOW())) - LEFT JOIN res_currency company_currency ON company_currency.id = line.company_currency_id '''.format( currency_table=self.env['res.currency']._get_query_currency_table(self.env.companies.ids, fields.Date.today()) ) diff --git a/addons/account/tests/test_account_invoice_report.py b/addons/account/tests/test_account_invoice_report.py index 62d3048a74d..d1458036c9d 100644 --- a/addons/account/tests/test_account_invoice_report.py +++ b/addons/account/tests/test_account_invoice_report.py @@ -94,19 +94,6 @@ class TestAccountInvoiceReport(AccountTestInvoicingCommon): }), ] }, - { - 'move_type': 'out_invoice', - 'partner_id': cls.partner_a.id, - 'invoice_date': fields.Date.from_string('1900-01-01'), # before the first currency rate is set - 'currency_id': cls.currency_data['currency'].id, - 'invoice_line_ids': [ - (0, None, { - 'product_id': cls.product_a.id, - 'quantity': 1, - 'price_unit': 1200, - }), - ] - }, ]) def assertInvoiceReportValues(self, expected_values_list): @@ -115,7 +102,6 @@ class TestAccountInvoiceReport(AccountTestInvoicingCommon): 'price_average': vals[0], 'price_subtotal': vals[1], 'quantity': vals[2], - 'price_total': vals[3], } for vals in expected_values_list] self.assertRecordValues(reports, expected_values_dict) @@ -123,12 +109,11 @@ class TestAccountInvoiceReport(AccountTestInvoicingCommon): def test_invoice_report_multiple_types(self): self.assertInvoiceReportValues([ #price_average price_subtotal quantity - [2000, 2000, 1, 2300], - [1200, 1200, 1, 1380], - [1000, 1000, 1, 1150], - [250, 750, 3, 862.5], - [6, 6, 1, 6.9], - [20, -20, -1, -23], - [20, -20, -1, -23], - [600, -600, -1, -690], + [2000, 2000, 1], + [1000, 1000, 1], + [250, 750, 3], + [6, 6, 1], + [20, -20, -1], + [20, -20, -1], + [600, -600, -1], ])