From f4fbab3c1e2cefc37426c2126451009ca6945209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Tue, 27 Oct 2015 21:31:26 +0100 Subject: [PATCH 1/2] [ADD] mis_builder: hooks for analytic filtering --- mis_builder/README.rst | 16 +++++++++------ mis_builder/models/aep.py | 4 +++- mis_builder/models/mis_builder.py | 33 ++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/mis_builder/README.rst b/mis_builder/README.rst index 23e34ce8..a9cbf083 100644 --- a/mis_builder/README.rst +++ b/mis_builder/README.rst @@ -50,6 +50,16 @@ For further information, please visit: * https://www.odoo.com/forum/help-1 +Developer notes +=============== + +A typical extension is to provide a mechanism to filter reports on analytic dimensions +or operational units. To implement this, you can override _get_additional_move_line_filter +and _get_additional_filter to further filter move lines or queries based on a user +selection. A typical use case could be to add an analytic account field on mis.report.instance, +or even on mis.report.instance.period if you want different columns to show different +analytic accounts. + Known issues / Roadmap ====================== @@ -60,12 +70,6 @@ Known issues / Roadmap but would be more efficient if one could write balp[user_type=...], as it would involve much less queries to the database. -* A mechanism to have a global move line filter at the level of the report template, - report instance, or even column. Such a domain filter would be ANDed with the - other filters and would allow to easily create reports filtered on analytic axis - or business unit. To be complete such a mechanism should allow implementing similar - filters on non accounting queries. - * More tests should be added. The first part is creating test data, then it will be easier. At the minimum, We need the following test data: diff --git a/mis_builder/models/aep.py b/mis_builder/models/aep.py index b8d3664e..740a58ec 100644 --- a/mis_builder/models/aep.py +++ b/mis_builder/models/aep.py @@ -328,7 +328,7 @@ class AccountingExpressionProcessor(object): return expression.normalize_domain(domain) def do_queries(self, date_from, date_to, period_from, period_to, - target_move): + target_move, additional_move_line_filter=None): """Query sums of debit and credit for all accounts and domains used in expressions. @@ -347,6 +347,8 @@ class AccountingExpressionProcessor(object): mode, target_move) domain = list(domain) + domain_by_mode[mode] domain.append(('account_id', 'in', self._map_account_ids[key])) + if additional_move_line_filter: + domain.extend(additional_move_line_filter) # fetch sum of debit/credit, grouped by account_id accs = aml_model.read_group(domain, ['debit', 'credit', 'account_id'], diff --git a/mis_builder/models/mis_builder.py b/mis_builder/models/mis_builder.py index bb3f676d..c2170618 100644 --- a/mis_builder/models/mis_builder.py +++ b/mis_builder/models/mis_builder.py @@ -260,6 +260,20 @@ class MisReportQuery(models.Model): def _check_name(self): return _is_valid_python_var(self.name) + @api.multi + def _get_additional_filter(self): + """ Prepare an additional filter to apply on the query + + This filter is combined to the query domain with a AND + operator. This hook is intended + to be inherited, and is useful to implement filtering + on analytic dimensions or operational units. + + Returns an Odoo domain expression (a python list) + compatible with the model of the query.""" + self.ensure_one() + return [] + class MisReport(models.Model): """ A MIS report template (without period information) @@ -398,6 +412,20 @@ class MisReportInstancePeriod(models.Model): 'Period name should be unique by report'), ] + @api.multi + def _get_additional_move_line_filter(self): + """ Prepare a filter to apply on all move lines + + This filter is applied with a AND operator on all + accounting expression domains. This hook is intended + to be inherited, and is useful to implement filtering + on analytic dimensions or operational units. + + Returns an Odoo domain expression (a python list) + compatible with account.move.line.""" + self.ensure_one() + return [] + @api.multi def drilldown(self, expr): assert len(self) == 1 @@ -410,6 +438,7 @@ class MisReportInstancePeriod(models.Model): self.date_from, self.date_to, self.period_from, self.period_to, self.report_instance_id.target_move) + domain.extend(self._get_additional_move_line_filter()) return { 'name': expr + ' - ' + self.name, 'domain': domain, @@ -439,6 +468,7 @@ class MisReportInstancePeriod(models.Model): } domain = query.domain and \ safe_eval(query.domain, eval_context) or [] + domain.extend(query._get_additional_filter()) if query.date_field.ttype == 'date': domain.extend([(query.date_field.name, '>=', self.date_from), (query.date_field.name, '<=', self.date_to)]) @@ -492,7 +522,8 @@ class MisReportInstancePeriod(models.Model): aep.do_queries(self.date_from, self.date_to, self.period_from, self.period_to, - self.report_instance_id.target_move) + self.report_instance_id.target_move, + self._get_additional_move_line_filter()) compute_queue = self.report_instance_id.report_id.kpi_ids recompute_queue = [] From cb17def7be5b662026468b99a02e257b3a899722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Thu, 29 Oct 2015 18:28:04 +0100 Subject: [PATCH 2/2] [IMP] mis_builder: _get_additional_query_filter on period model This is more consistent in case we want to have an analytic filter on the columns. --- mis_builder/models/mis_builder.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/mis_builder/models/mis_builder.py b/mis_builder/models/mis_builder.py index c2170618..7e4a7964 100644 --- a/mis_builder/models/mis_builder.py +++ b/mis_builder/models/mis_builder.py @@ -260,20 +260,6 @@ class MisReportQuery(models.Model): def _check_name(self): return _is_valid_python_var(self.name) - @api.multi - def _get_additional_filter(self): - """ Prepare an additional filter to apply on the query - - This filter is combined to the query domain with a AND - operator. This hook is intended - to be inherited, and is useful to implement filtering - on analytic dimensions or operational units. - - Returns an Odoo domain expression (a python list) - compatible with the model of the query.""" - self.ensure_one() - return [] - class MisReport(models.Model): """ A MIS report template (without period information) @@ -426,6 +412,20 @@ class MisReportInstancePeriod(models.Model): self.ensure_one() return [] + @api.multi + def _get_additional_query_filter(self, query): + """ Prepare an additional filter to apply on the query + + This filter is combined to the query domain with a AND + operator. This hook is intended + to be inherited, and is useful to implement filtering + on analytic dimensions or operational units. + + Returns an Odoo domain expression (a python list) + compatible with the model of the query.""" + self.ensure_one() + return [] + @api.multi def drilldown(self, expr): assert len(self) == 1 @@ -468,7 +468,7 @@ class MisReportInstancePeriod(models.Model): } domain = query.domain and \ safe_eval(query.domain, eval_context) or [] - domain.extend(query._get_additional_filter()) + domain.extend(self._get_additional_query_filter(query)) if query.date_field.ttype == 'date': domain.extend([(query.date_field.name, '>=', self.date_from), (query.date_field.name, '<=', self.date_to)])