Browse Source

[IMP] mis_builder: some doc, minor refactoring and pep8 stuff around subkpis

pull/189/head
Stéphane Bidoul 8 years ago
parent
commit
66220451c4
  1. 108
      mis_builder/models/mis_builder.py

108
mis_builder/models/mis_builder.py

@ -462,32 +462,16 @@ class MisReport(models.Model):
date_from, date_to, date_from, date_to,
target_move, target_move,
company, company,
subkpi_ids,
get_additional_move_line_filter=None, get_additional_move_line_filter=None,
get_additional_query_filter=None,
period_id=None):
""" Evaluate a report for a given period.
It returns a dictionary keyed on kpi.name with the following values:
* val: the evaluated kpi, or None if there is no data or an error
* val_r: the rendered kpi as a string, or #ERR, #DIV
* val_c: a comment (explaining the error, typically)
* style: the css style of the kpi
(may change in the future!)
* prefix: a prefix to display in front of the rendered value
* suffix: a prefix to display after rendered value
* dp: the decimal precision of the kpi
* is_percentage: true if the kpi is of percentage type
(may change in the future!)
* expr: the kpi expression
* drilldown: true if the drilldown method of
mis.report.instance.period is going to do something
useful in this kpi
get_additional_query_filter=None):
""" Compute
:param lang_id: id of a res.lang object :param lang_id: id of a res.lang object
:param aep: an AccountingExpressionProcessor instance created :param aep: an AccountingExpressionProcessor instance created
using _prepare_aep() using _prepare_aep()
:param date_from, date_to: the starting and ending date :param date_from, date_to: the starting and ending date
:param target_move: all|posted :param target_move: all|posted
:param company:
:param get_additional_move_line_filter: a bound method that takes :param get_additional_move_line_filter: a bound method that takes
no arguments and returns no arguments and returns
a domain compatible with a domain compatible with
@ -496,9 +480,6 @@ class MisReport(models.Model):
query argument and returns a query argument and returns a
domain compatible with the query domain compatible with the query
underlying model underlying model
:param period_id: an optional opaque value that is returned as
query_id field in the result (may change in the
future!)
""" """
self.ensure_one() self.ensure_one()
res = {} res = {}
@ -526,14 +507,13 @@ class MisReport(models.Model):
compute_queue = self.kpi_ids compute_queue = self.kpi_ids
recompute_queue = [] recompute_queue = []
period = self.env['mis.report.instance.period'].browse(period_id)
while True: while True:
for kpi in compute_queue: for kpi in compute_queue:
vals = [] vals = []
has_error = False has_error = False
for expression in kpi.expression_ids: for expression in kpi.expression_ids:
if expression.subkpi_id \ if expression.subkpi_id \
and expression.subkpi_id not in period.subkpi_ids:
and expression.subkpi_id not in subkpi_ids:
continue continue
try: try:
kpi_eval_expression = aep.replace_expr(expression.name) kpi_eval_expression = aep.replace_expr(expression.name)
@ -575,7 +555,7 @@ class MisReport(models.Model):
# try again # try again
compute_queue = recompute_queue compute_queue = recompute_queue
recompute_queue = [] recompute_queue = []
return res
return res, localdict
class MisReportInstancePeriod(models.Model): class MisReportInstancePeriod(models.Model):
@ -736,20 +716,42 @@ class MisReportInstancePeriod(models.Model):
return False return False
@api.multi @api.multi
def _render(self, data, lang_id):
def _compute(self, lang_id, aep):
""" Compute and render a mis report instance period
It returns a dictionary keyed on kpi.name with a list of dictionaries
with the following values (one item in the list for each subkpi):
* val: the evaluated kpi, or None if there is no data or an error
* val_r: the rendered kpi as a string, or #ERR, #DIV
* val_c: a comment (explaining the error, typically)
* style: the css style of the kpi
(may change in the future!)
* prefix: a prefix to display in front of the rendered value
* suffix: a prefix to display after rendered value
* dp: the decimal precision of the kpi
* is_percentage: true if the kpi is of percentage type
(may change in the future!)
* expr: the kpi expression
* drilldown: true if the drilldown method of
mis.report.instance.period is going to do something
useful in this kpi
"""
self.ensure_one() self.ensure_one()
# first invoke the compute method on the mis report template
# passing it all the information regarding period and filters
data, localdict = self.report_instance_id.report_id._compute(
lang_id, aep,
self.date_from, self.date_to,
self.report_instance_id.target_move,
self.report_instance_id.company_id,
self.subkpi_ids,
self._get_additional_move_line_filter,
self._get_additional_query_filter,
)
# second, render it to something that can be used by the widget
res = {} res = {}
if self.subkpi_ids:
index2subkpi = {
idx: subkpi.name
for idx, subkpi in enumerate(self.subkpi_ids)
}
else:
index2subkpi = {0: 'default'}
for kpi, vals in data.items(): for kpi, vals in data.items():
res[kpi.name] = [] res[kpi.name] = []
# TODO FIXME localdict
try: try:
kpi_style = None kpi_style = None
if kpi.css_style: if kpi.css_style:
@ -775,10 +777,11 @@ class MisReportInstancePeriod(models.Model):
'val': subkpi_val.name, 'val': subkpi_val.name,
'val_r': subkpi_val.name, 'val_r': subkpi_val.name,
'val_c': subkpi_val.msg, 'val_c': subkpi_val.msg,
'drilldown': None,
'drilldown': False,
}) })
else: else:
drilldown = (subkpi_val is not None and
# TODO FIXME: has_account_var on each subkpi expression?
drilldown = (subkpi_val is not AccountingNone and
AEP.has_account_var(kpi.expression)) AEP.has_account_var(kpi.expression))
if kpi.multi: if kpi.multi:
expression = kpi.expression_ids[idx].name expression = kpi.expression_ids[idx].name
@ -786,8 +789,9 @@ class MisReportInstancePeriod(models.Model):
expression = kpi.expression expression = kpi.expression
comment = kpi.name + " = " + expression comment = kpi.name + " = " + expression
vals.update({ vals.update({
'val': None if subkpi_val is AccountingNone
else subkpi_val,
'val': (None
if subkpi_val is AccountingNone
else subkpi_val),
'val_r': kpi.render(lang_id, subkpi_val), 'val_r': kpi.render(lang_id, subkpi_val),
'val_c': comment, 'val_c': comment,
'drilldown': drilldown, 'drilldown': drilldown,
@ -795,20 +799,6 @@ class MisReportInstancePeriod(models.Model):
res[kpi.name].append(vals) res[kpi.name].append(vals)
return res return res
@api.multi
def _compute(self, lang_id, aep):
self.ensure_one()
data = self.report_instance_id.report_id._compute(
lang_id, aep,
self.date_from, self.date_to,
self.report_instance_id.target_move,
self.report_instance_id.company_id,
self._get_additional_move_line_filter,
self._get_additional_query_filter,
period_id=self.id,
)
return self._render(data, lang_id)
class MisReportInstance(models.Model): class MisReportInstance(models.Model):
"""The MIS report instance combines everything to compute """The MIS report instance combines everything to compute
@ -947,10 +937,10 @@ class MisReportInstance(models.Model):
header = [{ header = [{
'kpi_name': '', 'kpi_name': '',
'cols': [] 'cols': []
},{
}, {
'kpi_name': '', 'kpi_name': '',
'cols': [] 'cols': []
}]
}]
content = [] content = []
rows_by_kpi_name = {} rows_by_kpi_name = {}
for kpi in self.report_id.kpi_ids: for kpi in self.report_id.kpi_ids:
@ -976,17 +966,17 @@ class MisReportInstance(models.Model):
header[0]['cols'].append(dict( header[0]['cols'].append(dict(
name=period.name, name=period.name,
date=header_date, date=header_date,
colspan = len(period.subkpi_ids) or 1,
colspan=len(period.subkpi_ids) or 1,
)) ))
for subkpi in period.subkpi_ids: for subkpi in period.subkpi_ids:
header[1]['cols'].append(dict( header[1]['cols'].append(dict(
name=subkpi.name, name=subkpi.name,
colspan = 1,
colspan=1,
)) ))
if not period.subkpi_ids: if not period.subkpi_ids:
header[1]['cols'].append(dict( header[1]['cols'].append(dict(
name="", name="",
colspan = 1,
colspan=1,
)) ))
# add kpi values # add kpi values
kpi_values = kpi_values_by_period_ids[period.id] kpi_values = kpi_values_by_period_ids[period.id]

Loading…
Cancel
Save