diff --git a/account_financial_report_qweb/report/general_ledger.py b/account_financial_report_qweb/report/general_ledger.py index 33824bf0..a9a79fd3 100644 --- a/account_financial_report_qweb/report/general_ledger.py +++ b/account_financial_report_qweb/report/general_ledger.py @@ -31,6 +31,7 @@ class GeneralLedgerReport(models.TransientModel): only_posted_moves = fields.Boolean() hide_account_balance_at_0 = fields.Boolean() foreign_currency = fields.Boolean() + show_analytic_tags = fields.Boolean() company_id = fields.Many2one(comodel_name='res.company') filter_account_ids = fields.Many2many(comodel_name='account.account') filter_partner_ids = fields.Many2many(comodel_name='res.partner') @@ -38,6 +39,9 @@ class GeneralLedgerReport(models.TransientModel): filter_cost_center_ids = fields.Many2many( comodel_name='account.analytic.account' ) + filter_analytic_tag_ids = fields.Many2many( + comodel_name='account.analytic.tag', + ) centralize = fields.Boolean() # Flag fields, used for report display @@ -192,6 +196,7 @@ class GeneralLedgerReportMoveLine(models.TransientModel): partner = fields.Char() label = fields.Char() cost_center = fields.Char() + tags = fields.Char() matching_number = fields.Char() debit = fields.Float(digits=(16, 2)) credit = fields.Float(digits=(16, 2)) @@ -275,6 +280,10 @@ class GeneralLedgerReportCompute(models.TransientModel): if self.centralize: self._inject_line_centralized_values() + if self.show_analytic_tags: + # Compute analytic tags + self._compute_analytic_tags() + # Refresh cache because all data are computed with SQL requests self.invalidate_cache() @@ -333,6 +342,11 @@ class GeneralLedgerReportCompute(models.TransientModel): ml.analytic_account_id = aa.id AND aa.id IN %s """ + if self.filter_analytic_tag_ids: + sub_subquery_sum_amounts += """ + INNER JOIN + move_lines_on_tags ON ml.id = move_lines_on_tags.ml_id + """ sub_subquery_sum_amounts += """ LEFT JOIN res_currency c ON a.currency_id = c.id @@ -389,7 +403,11 @@ WITH FROM account_account a """ - if self.filter_partner_ids or self.filter_cost_center_ids: + if ( + self.filter_partner_ids or + self.filter_cost_center_ids or + self.filter_analytic_tag_ids + ): query_inject_account += """ INNER JOIN account_move_line ml ON a.id = ml.account_id @@ -407,6 +425,17 @@ WITH ml.analytic_account_id = aa.id AND aa.id IN %s """ + if self.filter_analytic_tag_ids: + query_inject_account += """ + INNER JOIN + account_analytic_tag_account_move_line_rel atml + ON atml.account_move_line_id = ml.id + INNER JOIN + account_analytic_tag aat + ON + atml.account_analytic_tag_id = aat.id + AND aat.id IN %s + """ query_inject_account += """ WHERE a.company_id = %s @@ -422,11 +451,41 @@ WITH AND p.id IN %s """ - if self.filter_partner_ids or self.filter_cost_center_ids: + if ( + self.filter_partner_ids or + self.filter_cost_center_ids or + self.filter_analytic_tag_ids + ): query_inject_account += """ GROUP BY a.id """ + query_inject_account += """ + ), + """ + + if self.filter_analytic_tag_ids: + query_inject_account += """ + move_lines_on_tags AS + ( + SELECT + DISTINCT ml.id AS ml_id + FROM + accounts a + INNER JOIN + account_move_line ml + ON a.id = ml.account_id + INNER JOIN + account_analytic_tag_account_move_line_rel atml + ON atml.account_move_line_id = ml.id + INNER JOIN + account_analytic_tag aat + ON + atml.account_analytic_tag_id = aat.id + WHERE + aat.id IN %s + ), + """ init_subquery = self._get_final_account_sub_subquery_sum_amounts( date_included=False @@ -436,7 +495,6 @@ WITH ) query_inject_account += """ - ), initial_sum_amounts AS ( """ + init_subquery + """ ), final_sum_amounts AS ( """ + final_subquery + """ ) INSERT INTO @@ -504,6 +562,10 @@ AND query_inject_account_params += ( tuple(self.filter_cost_center_ids.ids), ) + if self.filter_analytic_tag_ids: + query_inject_account_params += ( + tuple(self.filter_analytic_tag_ids.ids), + ) query_inject_account_params += ( self.company_id.id, self.unaffected_earnings_account.id, @@ -516,6 +578,10 @@ AND query_inject_account_params += ( tuple(self.filter_partner_ids.ids), ) + if self.filter_analytic_tag_ids: + query_inject_account_params += ( + tuple(self.filter_analytic_tag_ids.ids), + ) query_inject_account_params += ( self.date_from, self.fy_start_date, @@ -616,6 +682,11 @@ AND ml.analytic_account_id = aa.id AND aa.id IN %s """ + if self.filter_analytic_tag_ids: + sub_subquery_sum_amounts += """ + INNER JOIN + move_lines_on_tags ON ml.id = move_lines_on_tags.ml_id + """ sub_subquery_sum_amounts += """ GROUP BY ap.account_id, ap.partner_id, c.id @@ -703,6 +774,17 @@ WITH ml.analytic_account_id = aa.id AND aa.id IN %s """ + if self.filter_analytic_tag_ids: + query_inject_partner += """ + INNER JOIN + account_analytic_tag_account_move_line_rel atml + ON atml.account_move_line_id = ml.id + INNER JOIN + account_analytic_tag aat + ON + atml.account_analytic_tag_id = aat.id + AND aat.id IN %s + """ query_inject_partner += """ WHERE ra.report_id = %s @@ -747,6 +829,32 @@ WITH p.id, at.include_initial_balance ), + """ + + if self.filter_analytic_tag_ids: + query_inject_partner += """ + move_lines_on_tags AS + ( + SELECT + DISTINCT ml.id AS ml_id + FROM + accounts_partners ap + INNER JOIN + account_move_line ml + ON ap.account_id = ml.account_id + INNER JOIN + account_analytic_tag_account_move_line_rel atml + ON atml.account_move_line_id = ml.id + INNER JOIN + account_analytic_tag aat + ON + atml.account_analytic_tag_id = aat.id + WHERE + aat.id IN %s + ), + """ + + query_inject_partner += """ initial_sum_amounts AS ( """ + init_subquery + """ ), final_sum_amounts AS ( """ + final_subquery + """ ) INSERT INTO @@ -836,6 +944,10 @@ AND query_inject_partner_params += ( tuple(self.filter_cost_center_ids.ids), ) + if self.filter_analytic_tag_ids: + query_inject_partner_params += ( + tuple(self.filter_analytic_tag_ids.ids), + ) query_inject_partner_params += ( self.id, ) @@ -843,6 +955,10 @@ AND query_inject_partner_params += ( tuple(self.filter_partner_ids.ids), ) + if self.filter_analytic_tag_ids: + query_inject_partner_params += ( + tuple(self.filter_analytic_tag_ids.ids), + ) query_inject_partner_params += ( self.date_from, self.fy_start_date, @@ -895,7 +1011,46 @@ AND The "only_empty_partner_line" value is used to compute data without partner. """ - query_inject_move_line = """ + + query_inject_move_line = "" + if self.filter_analytic_tag_ids: + query_inject_move_line += """ +WITH + move_lines_on_tags AS + ( + SELECT + DISTINCT ml.id AS ml_id + FROM + """ + if is_account_line: + query_inject_move_line += """ + report_general_ledger_qweb_account ra + """ + elif is_partner_line: + query_inject_move_line += """ + report_general_ledger_qweb_partner rp + INNER JOIN + report_general_ledger_qweb_account ra + ON rp.report_account_id = ra.id + """ + query_inject_move_line += """ + INNER JOIN + account_move_line ml + ON ra.account_id = ml.account_id + INNER JOIN + account_analytic_tag_account_move_line_rel atml + ON atml.account_move_line_id = ml.id + INNER JOIN + account_analytic_tag aat + ON + atml.account_analytic_tag_id = aat.id + WHERE + ra.report_id = %s + AND + aat.id IN %s + ) + """ + query_inject_move_line += """ INSERT INTO report_general_ledger_qweb_move_line ( @@ -1069,6 +1224,11 @@ INNER JOIN LEFT JOIN account_analytic_account aa ON ml.analytic_account_id = aa.id """ + if self.filter_analytic_tag_ids: + query_inject_move_line += """ +INNER JOIN + move_lines_on_tags ON ml.id = move_lines_on_tags.ml_id + """ query_inject_move_line += """ WHERE ra.report_id = %s @@ -1129,7 +1289,13 @@ ORDER BY a.code, ml.date, ml.id """ - query_inject_move_line_params = ( + query_inject_move_line_params = () + if self.filter_analytic_tag_ids: + query_inject_move_line_params += ( + self.id, + tuple(self.filter_analytic_tag_ids.ids), + ) + query_inject_move_line_params += ( self.env.uid, ) if self.filter_cost_center_ids: @@ -1161,8 +1327,37 @@ ORDER BY Only centralized accounts are computed. """ - query_inject_move_line_centralized = """ + + if self.filter_analytic_tag_ids: + query_inject_move_line_centralized = """ +WITH + move_lines_on_tags AS + ( + SELECT + DISTINCT ml.id AS ml_id + FROM + report_general_ledger_qweb_account ra + INNER JOIN + account_move_line ml + ON ra.account_id = ml.account_id + INNER JOIN + account_analytic_tag_account_move_line_rel atml + ON atml.account_move_line_id = ml.id + INNER JOIN + account_analytic_tag aat + ON + atml.account_analytic_tag_id = aat.id + WHERE + ra.report_id = %s + AND + aat.id IN %s + ), + """ + else: + query_inject_move_line_centralized = """ WITH + """ + query_inject_move_line_centralized += """ move_lines AS ( SELECT @@ -1193,6 +1388,11 @@ WITH ml.analytic_account_id = aa.id AND aa.id IN %s """ + if self.filter_analytic_tag_ids: + query_inject_move_line_centralized += """ + INNER JOIN + move_lines_on_tags ON ml.id = move_lines_on_tags.ml_id + """ query_inject_move_line_centralized += """ WHERE ra.report_id = %s @@ -1264,6 +1464,11 @@ ORDER BY """ query_inject_move_line_centralized_params = () + if self.filter_analytic_tag_ids: + query_inject_move_line_centralized_params += ( + self.id, + tuple(self.filter_analytic_tag_ids.ids), + ) if self.filter_cost_center_ids: query_inject_move_line_centralized_params += ( tuple(self.filter_cost_center_ids.ids), @@ -1284,6 +1489,76 @@ ORDER BY query_inject_move_line_centralized_params ) + def _compute_analytic_tags(self): + """ Compute "tags" column""" + query_update_analytic_tags = """ +UPDATE + report_general_ledger_qweb_move_line +SET + tags = tags_values.tags +FROM + ( + ( + SELECT + rml.id AS report_id, + array_to_string(array_agg(t.name ORDER BY t.name), ',') AS tags + FROM + account_move_line ml + INNER JOIN + report_general_ledger_qweb_move_line rml + ON ml.id = rml.move_line_id + INNER JOIN + report_general_ledger_qweb_account ra + ON rml.report_account_id = ra.id + INNER JOIN + account_analytic_tag_account_move_line_rel tml + ON ml.id = tml.account_move_line_id + INNER JOIN + account_analytic_tag t + ON tml.account_analytic_tag_id = t.id + WHERE + ra.report_id = %(report_id)s + GROUP BY + rml.id, + ml.id + ) + UNION + ( + SELECT + rml.id AS report_id, + array_to_string(array_agg(t.name ORDER BY t.name), ',') AS tags + FROM + account_move_line ml + INNER JOIN + report_general_ledger_qweb_move_line rml + ON ml.id = rml.move_line_id + INNER JOIN + report_general_ledger_qweb_partner rp + ON rml.report_partner_id = rp.id + INNER JOIN + report_general_ledger_qweb_account ra + ON rp.report_account_id = ra.id + INNER JOIN + account_analytic_tag_account_move_line_rel tml + ON ml.id = tml.account_move_line_id + INNER JOIN + account_analytic_tag t + ON tml.account_analytic_tag_id = t.id + WHERE + ra.report_id = %(report_id)s + GROUP BY + rml.id, + ml.id + ) + ) AS tags_values +WHERE + report_general_ledger_qweb_move_line.id = tags_values.report_id + """ + params = { + 'report_id': self.id, + } + self.env.cr.execute(query_update_analytic_tags, params) + def _get_unaffected_earnings_account_sub_subquery_sum_initial( self ): @@ -1315,6 +1590,11 @@ ORDER BY ml.analytic_account_id = aa.id AND aa.id IN %(cost_center_ids)s """ + if self.filter_analytic_tag_ids: + sub_subquery_sum_amounts += """ + INNER JOIN + move_lines_on_tags ON ml.id = move_lines_on_tags.ml_id + """ sub_subquery_sum_amounts += """ WHERE a.company_id = %(company_id)s @@ -1359,6 +1639,11 @@ ORDER BY ml.analytic_account_id = aa.id AND aa.id IN %(cost_center_ids)s """ + if self.filter_analytic_tag_ids: + sub_subquery_sum_amounts += """ + INNER JOIN + move_lines_on_tags ON ml.id = move_lines_on_tags.ml_id + """ sub_subquery_sum_amounts += """ WHERE a.company_id = %(company_id)s @@ -1396,6 +1681,32 @@ ORDER BY # pylint: disable=sql-injection query_inject_account = """ WITH + """ + + if self.filter_analytic_tag_ids: + query_inject_account += """ + move_lines_on_tags AS + ( + SELECT + DISTINCT ml.id AS ml_id + FROM + account_account a + INNER JOIN + account_move_line ml + ON a.id = ml.account_id + INNER JOIN + account_analytic_tag_account_move_line_rel atml + ON atml.account_move_line_id = ml.id + INNER JOIN + account_analytic_tag aat + ON + atml.account_analytic_tag_id = aat.id + WHERE + aat.id IN %(analytic_tag_ids)s + ), + """ + + query_inject_account += """ sum_amounts AS ( """ + subquery_sum_amounts + """ ) INSERT INTO report_general_ledger_qweb_account @@ -1431,11 +1742,15 @@ ORDER BY a.company_id = %(company_id)s AND a.id = %(unaffected_earnings_account_id)s """ - query_inject_account_params = { + query_inject_account_params = {} + if self.filter_analytic_tag_ids: + query_inject_account_params['analytic_tag_ids'] = \ + tuple(self.filter_analytic_tag_ids.ids) + query_inject_account_params.update({ 'date_from': self.date_from, 'date_to': self.date_to, 'fy_start_date': self.fy_start_date, - } + }) if self.filter_cost_center_ids: query_inject_account_params['cost_center_ids'] = \ tuple(self.filter_cost_center_ids.ids) diff --git a/account_financial_report_qweb/report/general_ledger_xlsx.py b/account_financial_report_qweb/report/general_ledger_xlsx.py index 2b7ac916..314c88c3 100644 --- a/account_financial_report_qweb/report/general_ledger_xlsx.py +++ b/account_financial_report_qweb/report/general_ledger_xlsx.py @@ -33,14 +33,17 @@ class GeneralLedgerXslx(abstract_report_xlsx.AbstractReportXslx): 7: {'header': _('Cost center'), 'field': 'cost_center', 'width': 15}, - 8: {'header': _('Rec.'), 'field': 'matching_number', 'width': 5}, - 9: {'header': _('Debit'), - 'field': 'debit', - 'field_initial_balance': 'initial_debit', - 'field_final_balance': 'final_debit', - 'type': 'amount', - 'width': 14}, - 10: { + 8: {'header': _('Tags'), + 'field': 'tags', + 'width': 10}, + 9: {'header': _('Rec.'), 'field': 'matching_number', 'width': 5}, + 10: {'header': _('Debit'), + 'field': 'debit', + 'field_initial_balance': 'initial_debit', + 'field_final_balance': 'final_debit', + 'type': 'amount', + 'width': 14}, + 11: { 'header': _('Credit'), 'field': 'credit', 'field_initial_balance': 'initial_credit', @@ -48,7 +51,7 @@ class GeneralLedgerXslx(abstract_report_xlsx.AbstractReportXslx): 'type': 'amount', 'width': 14 }, - 11: {'header': _('Cumul. Bal.'), + 12: {'header': _('Cumul. Bal.'), 'field': 'cumul_balance', 'field_initial_balance': 'initial_balance', 'field_final_balance': 'final_balance', @@ -57,12 +60,12 @@ class GeneralLedgerXslx(abstract_report_xlsx.AbstractReportXslx): } if report.foreign_currency: foreign_currency = { - 12: {'header': _('Cur.'), + 13: {'header': _('Cur.'), 'field': 'currency_id', 'field_currency_balance': 'currency_id', 'type': 'many2one', 'width': 7}, - 13: {'header': _('Amount cur.'), + 14: {'header': _('Amount cur.'), 'field': 'amount_currency', 'field_initial_balance': 'initial_balance_foreign_currency', @@ -75,17 +78,31 @@ class GeneralLedgerXslx(abstract_report_xlsx.AbstractReportXslx): def _get_report_filters(self, report): return [ - [_('Date range filter'), - _('From: %s To: %s') % (report.date_from, report.date_to)], - [_('Target moves filter'), - _('All posted entries') if report.only_posted_moves else _( - 'All entries')], - [_('Account balance at 0 filter'), - _('Hide') if report.hide_account_balance_at_0 else _('Show')], - [_('Centralize filter'), - _('Yes') if report.centralize else _('No')], - [_('Show foreign currency'), - _('Yes') if report.foreign_currency else _('No')], + [ + _('Date range filter'), + _('From: %s To: %s') % (report.date_from, report.date_to), + ], + [ + _('Target moves filter'), + _('All posted entries') if report.only_posted_moves + else _('All entries'), + ], + [ + _('Account balance at 0 filter'), + _('Hide') if report.hide_account_balance_at_0 else _('Show'), + ], + [ + _('Centralize filter'), + _('Yes') if report.centralize else _('No'), + ], + [ + _('Show analytic tags'), + _('Yes') if report.show_analytic_tags else _('No'), + ], + [ + _('Show foreign currency'), + _('Yes') if report.foreign_currency else _('No') + ], ] def _get_col_count_filter_name(self): diff --git a/account_financial_report_qweb/report/templates/general_ledger.xml b/account_financial_report_qweb/report/templates/general_ledger.xml index dfa5839f..0cf55978 100644 --- a/account_financial_report_qweb/report/templates/general_ledger.xml +++ b/account_financial_report_qweb/report/templates/general_ledger.xml @@ -4,6 +4,8 @@ @@ -129,6 +136,10 @@
Cost center
+ + +
Tags
+
Rec.
@@ -166,6 +177,10 @@
+ + +
+
@@ -379,6 +394,10 @@
+ + +
+
@@ -473,6 +492,10 @@
+ + +
+
diff --git a/account_financial_report_qweb/tests/test_general_ledger.py b/account_financial_report_qweb/tests/test_general_ledger.py index 17332f1f..127af587 100644 --- a/account_financial_report_qweb/tests/test_general_ledger.py +++ b/account_financial_report_qweb/tests/test_general_ledger.py @@ -40,7 +40,7 @@ class TestGeneralLedger(a_t_f_c.AbstractTestForeignCurrency): } def _getAdditionalFiltersToBeTested(self): - return [ + additional_filters = [ {'only_posted_moves': True}, {'hide_account_balance_at_0': True}, {'centralize': True}, @@ -54,6 +54,37 @@ class TestGeneralLedger(a_t_f_c.AbstractTestForeignCurrency): }, ] + # Add `show_analytic_tags` filter on each cases + additional_filters_with_show_tags = [] + for additional_filter in additional_filters: + additional_filter['show_analytic_tags'] = True + additional_filters_with_show_tags.append( + additional_filter + ) + additional_filters += additional_filters_with_show_tags + + # Add `filter_analytic_tag_ids` filter on each cases + analytic_tag = self.env['account.analytic.tag'].create({ + 'name': 'TEST tag' + }) + # Define all move lines on this tag + # (this test just check with the all filters, all works technically) + move_lines = self.env['account.move.line'].search([]) + move_lines.write({ + 'analytic_tag_ids': [(6, False, analytic_tag.ids)], + }) + additional_filters_with_filter_tags = [] + for additional_filter in additional_filters: + additional_filter['filter_analytic_tag_ids'] = [ + (6, False, analytic_tag.ids) + ] + additional_filters_with_filter_tags.append( + additional_filter + ) + additional_filters += additional_filters_with_filter_tags + + return additional_filters + @common.at_install(False) @common.post_install(True) diff --git a/account_financial_report_qweb/wizard/general_ledger_wizard.py b/account_financial_report_qweb/wizard/general_ledger_wizard.py index fc659204..cbbe0a7a 100644 --- a/account_financial_report_qweb/wizard/general_ledger_wizard.py +++ b/account_financial_report_qweb/wizard/general_ledger_wizard.py @@ -45,6 +45,9 @@ class GeneralLedgerReportWizard(models.TransientModel): 'If partners are filtered, ' 'debits and credits totals will not match the trial balance.' ) + show_analytic_tags = fields.Boolean( + string='Show analytic tags', + ) receivable_accounts_only = fields.Boolean() payable_accounts_only = fields.Boolean() partner_ids = fields.Many2many( @@ -70,6 +73,10 @@ class GeneralLedgerReportWizard(models.TransientModel): 'account currency is not setup through chart of accounts ' 'will display initial and final balance in that currency.' ) + analytic_tag_ids = fields.Many2many( + comodel_name='account.analytic.tag', + string='Filter accounts', + ) @api.depends('date_from') def _compute_fy_start_date(self): @@ -176,11 +183,13 @@ class GeneralLedgerReportWizard(models.TransientModel): 'only_posted_moves': self.target_move == 'posted', 'hide_account_balance_at_0': self.hide_account_balance_at_0, 'foreign_currency': self.foreign_currency, + 'show_analytic_tags': self.show_analytic_tags, 'company_id': self.company_id.id, 'filter_account_ids': [(6, 0, self.account_ids.ids)], 'filter_partner_ids': [(6, 0, self.partner_ids.ids)], 'filter_journal_ids': [(6, 0, self.journal_ids.ids)], 'filter_cost_center_ids': [(6, 0, self.cost_center_ids.ids)], + 'filter_analytic_tag_ids': [(6, 0, self.analytic_tag_ids.ids)], 'centralize': self.centralize, 'fy_start_date': self.fy_start_date, } diff --git a/account_financial_report_qweb/wizard/general_ledger_wizard_view.xml b/account_financial_report_qweb/wizard/general_ledger_wizard_view.xml index 212ea804..b6dba065 100644 --- a/account_financial_report_qweb/wizard/general_ledger_wizard_view.xml +++ b/account_financial_report_qweb/wizard/general_ledger_wizard_view.xml @@ -24,22 +24,27 @@ + - - - - -