Browse Source

[IMP] Refactor code and implement styling in xlsx

pull/189/head
Laurent Mignon 9 years ago
committed by Stéphane Bidoul
parent
commit
1e10841aa3
  1. 44
      mis_builder/models/mis_builder.py
  2. 75
      mis_builder/models/mis_builder_style.py
  3. 19
      mis_builder/report/mis_builder_xlsx.py
  4. 8
      mis_builder/views/mis_builder.xml

44
mis_builder/models/mis_builder.py

@ -194,8 +194,14 @@ class MisReportKpi(models.Model):
inverse='_inverse_expression') inverse='_inverse_expression')
expression_ids = fields.One2many('mis.report.kpi.expression', 'kpi_id') expression_ids = fields.One2many('mis.report.kpi.expression', 'kpi_id')
auto_expand_accounts = fields.Boolean(string='Display details by account') auto_expand_accounts = fields.Boolean(string='Display details by account')
default_css_style = fields.Char(string='Default CSS style')
css_style = fields.Char(string='CSS style expression')
style = fields.Many2one(
string="Default style for KPI",
comodel_name="mis.report.kpi.style",
required=False
)
style_expression = fields.Char(
string='Style expression',
help='An expression that returns a style name for the kpi style')
type = fields.Selection([('num', _('Numeric')), type = fields.Selection([('num', _('Numeric')),
('pct', _('Percentage')), ('pct', _('Percentage')),
('str', _('String'))], ('str', _('String'))],
@ -950,28 +956,38 @@ class MisReportInstancePeriod(models.Model):
) )
# second, render it to something that can be used by the widget # second, render it to something that can be used by the widget
res = {} res = {}
mis_report_kpi_style = self.env['mis.report.kpi.style']
for kpi_name, kpi, vals in kpi_matrix.iter_kpi_vals(self): for kpi_name, kpi, vals in kpi_matrix.iter_kpi_vals(self):
res[kpi_name] = [] res[kpi_name] = []
try: try:
# TODO FIXME check css_style evaluation wrt subkpis
# TODO FIXME check style_expression evaluation wrt subkpis
kpi_style = None kpi_style = None
if kpi.css_style:
kpi_style = safe_eval(kpi.css_style,
if kpi.style_expression:
style_name = safe_eval(kpi.style_expression,
kpi_matrix.get_localdict(self)) kpi_matrix.get_localdict(self))
styles = mis_report_kpi_style.search(
[('name', '=', style_name)])
kpi_style = styles and styles[0]
except: except:
_logger.warning("error evaluating css stype expression %s", _logger.warning("error evaluating css stype expression %s",
kpi.css_style, exc_info=True)
kpi_style = None
kpi.style, exc_info=True)
default_vals = { default_vals = {
'style': kpi_style,
'prefix': kpi.prefix, 'prefix': kpi.prefix,
'suffix': kpi.suffix, 'suffix': kpi.suffix,
'dp': kpi.dp, 'dp': kpi.dp,
'is_percentage': kpi.type == 'pct', 'is_percentage': kpi.type == 'pct',
'period_id': self.id, 'period_id': self.id,
'expr': kpi.expression, # TODO FIXME 'expr': kpi.expression, # TODO FIXME
'style': '',
'xlsx_style': {},
} }
if kpi_style:
default_vals.update({
'style': kpi_style.to_css_style(),
'xlsx_style': kpi_style.to_xlsx_forma_properties(),
})
for idx, subkpi_val in enumerate(vals): for idx, subkpi_val in enumerate(vals):
vals = default_vals.copy() vals = default_vals.copy()
if isinstance(subkpi_val, DataError): if isinstance(subkpi_val, DataError):
@ -1203,11 +1219,19 @@ class MisReportInstance(models.Model):
content = [] content = []
rows_by_kpi_name = {} rows_by_kpi_name = {}
for kpi_name, kpi_description, kpi in kpi_matrix.iter_kpis(): for kpi_name, kpi_description, kpi in kpi_matrix.iter_kpis():
rows_by_kpi_name[kpi_name] = {
props = {
'kpi_name': kpi_description, 'kpi_name': kpi_description,
'cols': [], 'cols': [],
'default_style': kpi.default_css_style
'default_style': '',
'default_xlsx_style': {},
} }
rows_by_kpi_name[kpi_name] = props
if kpi.style:
props.update({
'default_style': kpi.style.to_css_style(),
'default_xlsx_style': kpi.style.to_xlsx_format_properties()
})
content.append(rows_by_kpi_name[kpi_name]) content.append(rows_by_kpi_name[kpi_name])
# populate header and content # populate header and content

75
mis_builder/models/mis_builder_style.py

@ -24,35 +24,6 @@
from openerp import api, fields, models, exceptions from openerp import api, fields, models, exceptions
class MisReportKpi(models.Model):
_inherit='mis.report.kpi'
@api.depends('kpi_style')
def calc_css_style(self):
css_attributes = [
('font-style', self.kpi_style.font_style),
('font-weight', self.kpi_style.font_weight),
('font-size', self.kpi_style.font_size),
('color', self.kpi_style.color),
('background-color', self.kpi_style.background_color),
('indent-level', str(self.kpi_style.indent_level))
]
css_list = [
x[0] + ':' + x[1] for x in css_attributes if x[1]
]
self.default_css_style = ';'.join(css_item for css_item in css_list)
# Adding Attributes to default_css_style
default_css_style = fields.Char(compute=calc_css_style, store=True)
kpi_style = fields.Many2one(
string="Default CSS style for KPI",
comodel_name="mis.report.kpi.style",
required=True
)
class MisReportKpiStyle(models.Model): class MisReportKpiStyle(models.Model):
@ -61,12 +32,10 @@ class MisReportKpiStyle(models.Model):
# TODO use WEB WIdget color picker # TODO use WEB WIdget color picker
name = fields.Char(string='style name', required=True) name = fields.Char(string='style name', required=True)
@api.depends('indent_level') @api.depends('indent_level')
def check_positive_val(self): def check_positive_val(self):
return self.indent_level > 0 return self.indent_level > 0
_font_style_selection = [ _font_style_selection = [
('normal', 'Normal'), ('normal', 'Normal'),
('italic', 'Italic'), ('italic', 'Italic'),
@ -87,6 +56,15 @@ class MisReportKpiStyle(models.Model):
('xx-large', 'xx-large'), ('xx-large', 'xx-large'),
] ]
_font_size_to_size = {
'medium': 11,
'xx-small': 5,
'x-small': 7,
'small': 9,
'large': 13,
'x-large': 15,
'xx-large': 17
}
color = fields.Char( color = fields.Char(
required=True, required=True,
@ -106,3 +84,38 @@ class MisReportKpiStyle(models.Model):
selection=_font_size_selection selection=_font_size_selection
) )
indent_level = fields.Integer() indent_level = fields.Integer()
@api.multi
def font_size_to_size(self):
self.ensure_one()
return self._font_size_to_size.get(self.font_size, 11)
@api.multi
def to_xlsx_format_properties(self):
self.ensure_one()
props = {
'italic': self.font_style == 'italic',
'bold': self.font_weight == 'bold',
'font_color': self.color,
'bg_color': self.background_color,
'indent': self.indent_level,
'size': self.font_size_to_size()
}
return props
@api.multi
def to_css_style(self):
self.ensure_one()
css_attributes = [
('font-style', self.font_style),
('font-weight', self.font_weight),
('font-size', self.font_size),
('color', self.color),
('background-color', self.background_color),
('indent-level', str(self.indent_level))
]
css_list = [
x[0] + ':' + x[1] for x in css_attributes if x[1]
]
return ';'.join(css_item for css_item in css_list)

19
mis_builder/report/mis_builder_xlsx.py

@ -46,11 +46,7 @@ class MisBuilderXslx(ReportXlsx):
bold = workbook.add_format({'bold': True}) bold = workbook.add_format({'bold': True})
header_format = workbook.add_format({'bold': True, header_format = workbook.add_format({'bold': True,
'align': 'center', 'align': 'center',
'border': True,
'bg_color': '#FFFFCC'})
kpi_name_format = workbook.add_format({'bold': True,
'border': True,
'bg_color': '#FFFFCC'})
'bg_color': '#F0EEEE'})
sheet.write(row_pos, 0, report_name, bold) sheet.write(row_pos, 0, report_name, bold)
row_pos += 1 row_pos += 1
col_pos += 1 col_pos += 1
@ -86,8 +82,10 @@ class MisBuilderXslx(ReportXlsx):
if has_col_date: if has_col_date:
row_pos += 1 row_pos += 1
for line in data['content']: for line in data['content']:
row_xlsx_syle = line.get('default_xlsx_style', {})
row_format = workbook.add_format(row_xlsx_syle)
col = 0 col = 0
sheet.write(row_pos, col, line['kpi_name'], kpi_name_format)
sheet.write(row_pos, col, line['kpi_name'], row_format)
for value in line['cols']: for value in line['cols']:
col += 1 col += 1
num_format_str = '#' num_format_str = '#'
@ -98,9 +96,12 @@ class MisBuilderXslx(ReportXlsx):
num_format_str = '"%s"' % value['prefix'] + num_format_str num_format_str = '"%s"' % value['prefix'] + num_format_str
if value.get('suffix'): if value.get('suffix'):
num_format_str = num_format_str + ' "%s"' % value['suffix'] num_format_str = num_format_str + ' "%s"' % value['suffix']
kpi_format = workbook.add_format({'num_format': num_format_str,
'border': 1,
'align': 'right'})
kpi_xlsx_syle = value.get('xlsx_style', {}) or row_xlsx_syle
kpi_xlsx_syle.update({
'num_format': num_format_str,
'align': 'right'
})
kpi_format = workbook.add_format(kpi_xlsx_syle)
if value.get('val'): if value.get('val'):
val = value['val'] val = value['val']
if value.get('is_percentage'): if value.get('is_percentage'):

8
mis_builder/views/mis_builder.xml

@ -135,11 +135,8 @@
attrs="{'invisible': [('type', '=', 'str')]}"/> attrs="{'invisible': [('type', '=', 'str')]}"/>
<field name="prefix"/> <field name="prefix"/>
<field name="suffix"/> <field name="suffix"/>
<field name="default_css_style"
colspan="4"
readonly="1"
/>
<field name="css_style" colspan="4"/>
<field name="style" colspan="4"/>
<field name="style_expression" colspan="4"/>
<!--<field name="sequence" />--> <!--<field name="sequence" />-->
</group> </group>
<group string="Expression"> <group string="Expression">
@ -155,7 +152,6 @@
<field name="expression" colspan="4" nolabel="1" <field name="expression" colspan="4" nolabel="1"
attrs="{'invisible': [('multi', '=', True)], attrs="{'invisible': [('multi', '=', True)],
'readonly': [('multi', '=', True)]}"/> 'readonly': [('multi', '=', True)]}"/>
<field name="kpi_style"/>
</group> </group>
<group string="Auto expand"> <group string="Auto expand">
<field name="auto_expand_accounts"/> <field name="auto_expand_accounts"/>

Loading…
Cancel
Save