From 2f4ad25f03033ed3e888e954b8283bc380036f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Sat, 6 Jun 2015 17:44:15 +0200 Subject: [PATCH] [IMP] mis_builder: improve docstrings --- mis_builder/models/aep.py | 24 ++++++++++++++++-------- mis_builder/models/mis_builder.py | 26 +++++++++++++------------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/mis_builder/models/aep.py b/mis_builder/models/aep.py index 09729401..cd491f74 100644 --- a/mis_builder/models/aep.py +++ b/mis_builder/models/aep.py @@ -50,7 +50,7 @@ class AccountingExpressionProcessor(object): Examples: * bal[70]: variation of the balance of moves on account 70 over the period (it is the same as balp[70]); - * bali[70,60]: initial balance of accounts 70 and 60; + * bali[70,60]: balance of accounts 70 and 60 at the start of period; * bale[1%]: balance of accounts starting with 1 at end of period. How to use: @@ -85,7 +85,7 @@ class AccountingExpressionProcessor(object): def __init__(self, env): self.env = env # before done_parsing: {(domain, mode): set(account_codes)} - # after done_parsing: {(domain, mode): set(account_ids)} + # after done_parsing: {(domain, mode): list(account_ids)} self._map_account_ids = defaultdict(set) self._account_ids_by_code = defaultdict(set) @@ -140,7 +140,7 @@ class AccountingExpressionProcessor(object): def _parse_match_object(self, mo): """Split a match object corresponding to an accounting variable - Returns field, mode, [account codes], [domain expression]. + Returns field, mode, [account codes], (domain expression). """ field, mode, account_codes, domain = mo.groups() if not mode: @@ -163,7 +163,8 @@ class AccountingExpressionProcessor(object): """Parse an expression, extracting accounting variables. Domains and accounts are extracted and stored in the map - so when all expressions have been parsed, we know what to query. + so when all expressions have been parsed, we know which + account codes to query for each domain and mode. """ for mo in self.ACC_RE.finditer(expr): _, mode, account_codes, domain = self._parse_match_object(mo) @@ -171,7 +172,8 @@ class AccountingExpressionProcessor(object): self._map_account_ids[key].update(account_codes) def done_parsing(self, root_account): - # load account codes and replace account codes by account ids in _map + """Load account codes and replace account codes by + account ids in map.""" for key, account_codes in self._map_account_ids.items(): self._load_account_codes(account_codes, root_account) account_ids = set() @@ -180,8 +182,9 @@ class AccountingExpressionProcessor(object): self._map_account_ids[key] = list(account_ids) @classmethod - def has_account_var(self, expr): - return bool(self.ACC_RE.search(expr)) + def has_account_var(cls, expr): + """Test if an string contains an accounting variable.""" + return bool(cls.ACC_RE.search(expr)) def get_aml_domain_for_expr(self, expr, date_from, date_to, @@ -328,6 +331,11 @@ class AccountingExpressionProcessor(object): def do_queries(self, date_from, date_to, period_from, period_to, target_move): + """Query sums of debit and credit for all accounts and domains + used in expressions. + + This method must be executed after done_parsing(). + """ aml_model = self.env['account.move.line'] # {(domain, mode): {account_id: (debit, credit)}} self._data = defaultdict(dict) @@ -352,7 +360,7 @@ class AccountingExpressionProcessor(object): def replace_expr(self, expr): """Replace accounting variables in an expression by their amount. - Returns a new expression. + Returns a new expression string. This method must be executed after do_queries(). """ diff --git a/mis_builder/models/mis_builder.py b/mis_builder/models/mis_builder.py index 251ed2c9..d440d5f9 100644 --- a/mis_builder/models/mis_builder.py +++ b/mis_builder/models/mis_builder.py @@ -72,7 +72,6 @@ def _is_valid_python_var(name): class mis_report_kpi(orm.Model): - """ A KPI is an element (ie a line) of a MIS report. In addition to a name and description, it has an expression @@ -80,6 +79,7 @@ class mis_report_kpi(orm.Model): It also has various informations defining how to render it (numeric or percentage or a string, a suffix, divider) and how to render comparison of two values of the KPI. + KPI's have a sequence and are ordered inside the MIS report. """ _name = 'mis.report.kpi' @@ -166,7 +166,9 @@ class mis_report_kpi(orm.Model): def _render(self, cr, uid, lang_id, kpi, value, context=None): """ render a KPI value as a unicode string, ready for display """ - if kpi.type == 'num': + if value is None: + return '#N/A' + elif kpi.type == 'num': return self._render_num(cr, uid, lang_id, value, kpi.divider, kpi.dp, kpi.suffix, context=context) elif kpi.type == 'pct': @@ -227,8 +229,7 @@ class mis_report_kpi(orm.Model): class mis_report_query(orm.Model): - - """ A query to fetch data for a MIS report. + """ A query to fetch arbitrary data for a MIS report. A query works on a model and has a domain and list of fields to fetch. At runtime, the domain is expanded with a "and" on the date/datetime field. @@ -302,11 +303,11 @@ class mis_report(orm.Model): * a list of explicit queries; the result of each query is stored in a variable with same name as a query, containing as list of data structures populated with attributes for each fields to fetch; - when queries have the group by flag and no fields to group, it returns - a data structure with the summed fields + when queries have an aggregate method and no fields to group, it returns + a data structure with the aggregated fields * a list of KPI to be evaluated based on the variables resulting - from the balance and queries (KPI expressions can references queries - and accounting expression - see AccoutingExpressionProcessor) + from the accounting data and queries (KPI expressions can references + queries and accounting expression - see AccoutingExpressionProcessor) """ _name = 'mis.report' @@ -326,7 +327,6 @@ class mis_report(orm.Model): class mis_report_instance_period(orm.Model): - """ A MIS report instance has the logic to compute a report template for a given date period. @@ -518,7 +518,8 @@ class mis_report_instance_period(orm.Model): cr, uid, domain, field_names, [], context=context) s = AutoStruct(count=obj_datas[0]['__count']) for field_name in field_names: - setattr(s, field_name, obj_datas[0][field_name]) + v = obj_datas[0][field_name] + setattr(s, field_name, v) res[query.name] = s else: obj_ids = obj.search(cr, uid, domain, context=context) @@ -625,9 +626,8 @@ class mis_report_instance_period(orm.Model): class mis_report_instance(orm.Model): - - """ The MIS report instance combines compute and - display a MIS report template for a set of periods """ + """The MIS report instance combines everything to compute + a MIS report template for a set of periods.""" def _get_pivot_date(self, cr, uid, ids, field_name, arg, context=None): res = {}