pep8
parent
e83be45db8
commit
adb4262a09
|
@ -21,6 +21,6 @@
|
||||||
# =
|
# =
|
||||||
#==============================================================================
|
#==============================================================================
|
||||||
|
|
||||||
import models
|
from . import models
|
||||||
from . import wizard
|
from . import wizard
|
||||||
from . import report
|
from . import report
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
'tests/mis.report.csv',
|
'tests/mis.report.csv',
|
||||||
'tests/mis.report.instance.period.csv',
|
'tests/mis.report.instance.period.csv',
|
||||||
'tests/mis.report.instance.csv',
|
'tests/mis.report.instance.csv',
|
||||||
],
|
],
|
||||||
'js': [
|
'js': [
|
||||||
'static/src/js/*.js'
|
'static/src/js/*.js'
|
||||||
],
|
],
|
||||||
|
|
|
@ -21,4 +21,4 @@
|
||||||
# =
|
# =
|
||||||
#==============================================================================
|
#==============================================================================
|
||||||
|
|
||||||
import mis_builder
|
from . import mis_builder
|
||||||
|
|
|
@ -56,7 +56,8 @@ def _utc_midnight(d, tz_name, add_day=0):
|
||||||
utc_tz = pytz.timezone('UTC')
|
utc_tz = pytz.timezone('UTC')
|
||||||
context_tz = pytz.timezone(tz_name)
|
context_tz = pytz.timezone(tz_name)
|
||||||
local_timestamp = context_tz.localize(d, is_dst=False)
|
local_timestamp = context_tz.localize(d, is_dst=False)
|
||||||
return datetime.strftime(local_timestamp.astimezone(utc_tz), tools.DEFAULT_SERVER_DATETIME_FORMAT)
|
return datetime.strftime(local_timestamp.astimezone(utc_tz),
|
||||||
|
tools.DEFAULT_SERVER_DATETIME_FORMAT)
|
||||||
|
|
||||||
|
|
||||||
def _clean(varStr):
|
def _clean(varStr):
|
||||||
|
@ -64,6 +65,7 @@ def _clean(varStr):
|
||||||
|
|
||||||
|
|
||||||
class mis_report_kpi(orm.Model):
|
class mis_report_kpi(orm.Model):
|
||||||
|
|
||||||
""" A KPI is an element of a MIS report.
|
""" A KPI is an element of a MIS report.
|
||||||
|
|
||||||
In addition to a name and description, it has an expression
|
In addition to a name and description, it has an expression
|
||||||
|
@ -132,10 +134,13 @@ class mis_report_kpi(orm.Model):
|
||||||
# check it is a valid python identifier
|
# check it is a valid python identifier
|
||||||
res = {}
|
res = {}
|
||||||
if name and not re.match("[_A-Za-z][_a-zA-Z0-9]*$", name):
|
if name and not re.match("[_A-Za-z][_a-zA-Z0-9]*$", name):
|
||||||
res['warning'] = {'title': 'Invalid name', 'message': 'The name must be a valid python identifier'}
|
res['warning'] = {
|
||||||
|
'title': 'Invalid name',
|
||||||
|
'message': 'The name must be a valid python identifier'}
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def onchange_description(self, cr, uid, ids, description, name, context=None):
|
def onchange_description(self, cr, uid, ids, description, name,
|
||||||
|
context=None):
|
||||||
# construct name from description
|
# construct name from description
|
||||||
res = {}
|
res = {}
|
||||||
if description and not name:
|
if description and not name:
|
||||||
|
@ -155,47 +160,60 @@ class mis_report_kpi(orm.Model):
|
||||||
def _render(self, cr, uid, kpi, value, context=None):
|
def _render(self, cr, uid, kpi, value, context=None):
|
||||||
""" render a KPI value as a unicode string, ready for display """
|
""" render a KPI value as a unicode string, ready for display """
|
||||||
if kpi.type == 'num':
|
if kpi.type == 'num':
|
||||||
return self._render_num(cr, uid, value, kpi.divider, kpi.dp, kpi.suffix, context=context)
|
return self._render_num(cr, uid, value, kpi.divider, kpi.dp,
|
||||||
|
kpi.suffix, context=context)
|
||||||
elif kpi.type == 'pct':
|
elif kpi.type == 'pct':
|
||||||
return self._render_num(cr, uid, value, 0.01, kpi.dp, '%', context=context)
|
return self._render_num(cr, uid, value, 0.01, kpi.dp, '%',
|
||||||
|
context=context)
|
||||||
else:
|
else:
|
||||||
return unicode(value)
|
return unicode(value)
|
||||||
|
|
||||||
def _render_comparison(self, cr, uid, kpi, value, base_value, average_value, average_base_value, context=None):
|
def _render_comparison(self, cr, uid, kpi, value, base_value,
|
||||||
|
average_value, average_base_value, context=None):
|
||||||
""" render the comparison of two KPI values, ready for display """
|
""" render the comparison of two KPI values, ready for display """
|
||||||
if value is None or base_value is None:
|
if value is None or base_value is None:
|
||||||
return ''
|
return ''
|
||||||
if kpi.type == 'pct':
|
if kpi.type == 'pct':
|
||||||
return self._render_num(cr, uid, value - base_value, 0.01, kpi.dp, _('pp'), sign='+', context=context)
|
return self._render_num(cr, uid, value - base_value, 0.01, kpi.dp,
|
||||||
|
_('pp'), sign='+', context=context)
|
||||||
elif kpi.type == 'num':
|
elif kpi.type == 'num':
|
||||||
if average_value:
|
if average_value:
|
||||||
value = value / float(average_value)
|
value = value / float(average_value)
|
||||||
if average_base_value:
|
if average_base_value:
|
||||||
base_value = base_value / float(average_base_value)
|
base_value = base_value / float(average_base_value)
|
||||||
if kpi.compare_method == 'diff':
|
if kpi.compare_method == 'diff':
|
||||||
return self._render_num(cr, uid, value - base_value, kpi.divider,
|
return self._render_num(cr, uid, value - base_value,
|
||||||
kpi.dp, kpi.suffix, sign='+', context=context)
|
kpi.divider,
|
||||||
|
kpi.dp, kpi.suffix, sign='+',
|
||||||
|
context=context)
|
||||||
elif kpi.compare_method == 'pct' and base_value != 0:
|
elif kpi.compare_method == 'pct' and base_value != 0:
|
||||||
return self._render_num(cr, uid, value / base_value - 1,
|
return self._render_num(cr, uid, value / base_value - 1,
|
||||||
0.01, kpi.dp, '%',
|
0.01, kpi.dp, '%',
|
||||||
sign='+', context=context)
|
sign='+', context=context)
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def _render_num(self, cr, uid, value, divider, dp, suffix, sign='-', context=None):
|
def _render_num(self, cr, uid, value, divider, dp, suffix, sign='-',
|
||||||
divider_label = _get_selection_label(self._columns['divider'].selection, divider)
|
context=None):
|
||||||
|
divider_label = _get_selection_label(
|
||||||
|
self._columns['divider'].selection, divider)
|
||||||
if divider_label == '1':
|
if divider_label == '1':
|
||||||
divider_label = ''
|
divider_label = ''
|
||||||
# format number following user language
|
# format number following user language
|
||||||
lang = self.pool['res.users'].read(cr, uid, uid, ['lang'], context=context)['lang']
|
lang = self.pool['res.users'].read(
|
||||||
language_id = self.pool['res.lang'].search(cr, uid, [('code', '=', lang)], context=context)
|
cr, uid, uid, ['lang'], context=context)['lang']
|
||||||
|
language_id = self.pool['res.lang'].search(
|
||||||
|
cr, uid, [('code', '=', lang)], context=context)
|
||||||
value = round(value / float(divider or 1), dp) or 0
|
value = round(value / float(divider or 1), dp) or 0
|
||||||
return '%s %s%s' % (self.pool['res.lang'].format(cr, uid, language_id,
|
return '%s %s%s' % (self.pool['res.lang'].format(cr, uid, language_id,
|
||||||
'%%%s.%df' % (sign, dp),
|
'%%%s.%df' % (
|
||||||
value, context=context),
|
sign, dp),
|
||||||
|
value,
|
||||||
|
context=context),
|
||||||
divider_label, suffix or '')
|
divider_label, suffix or '')
|
||||||
|
|
||||||
|
|
||||||
class mis_report_query(orm.Model):
|
class mis_report_query(orm.Model):
|
||||||
|
|
||||||
""" A query to fetch data for a MIS report.
|
""" A query to fetch data for a MIS report.
|
||||||
|
|
||||||
A query works on a model and has a domain and list of fields to fetch.
|
A query works on a model and has a domain and list of fields to fetch.
|
||||||
|
@ -216,7 +234,10 @@ class mis_report_query(orm.Model):
|
||||||
def onchange_field_ids(self, cr, uid, ids, field_ids, context=None):
|
def onchange_field_ids(self, cr, uid, ids, field_ids, context=None):
|
||||||
# compute field_names
|
# compute field_names
|
||||||
field_name = []
|
field_name = []
|
||||||
for field in self.pool.get('ir.model.fields').read(cr, uid, field_ids[0][2], ['name'], context=context):
|
for field in self.pool.get('ir.model.fields').read(cr, uid,
|
||||||
|
field_ids[0][2],
|
||||||
|
['name'],
|
||||||
|
context=context):
|
||||||
field_name.append(field['name'])
|
field_name.append(field['name'])
|
||||||
return {'value': {'field_name': ', '.join(field_name)}}
|
return {'value': {'field_name': ', '.join(field_name)}}
|
||||||
|
|
||||||
|
@ -227,12 +248,15 @@ class mis_report_query(orm.Model):
|
||||||
string='Model'),
|
string='Model'),
|
||||||
'field_ids': fields.many2many('ir.model.fields', required=True,
|
'field_ids': fields.many2many('ir.model.fields', required=True,
|
||||||
string='Fields to fetch'),
|
string='Fields to fetch'),
|
||||||
'field_name': fields.function(_get_field_names, type='char', string='Fetched fields name',
|
'field_name': fields.function(_get_field_names, type='char',
|
||||||
|
string='Fetched fields name',
|
||||||
store={'mis.report.query':
|
store={'mis.report.query':
|
||||||
(lambda self, cr, uid, ids, c={}: ids, ['field_ids'], 20), }),
|
(lambda self, cr, uid, ids, c={}:
|
||||||
|
ids, ['field_ids'], 20), }),
|
||||||
'date_field': fields.many2one('ir.model.fields', required=True,
|
'date_field': fields.many2one('ir.model.fields', required=True,
|
||||||
string='Date field',
|
string='Date field',
|
||||||
domain=[('ttype', 'in', ('date', 'datetime'))]),
|
domain=[('ttype', 'in', ('date',
|
||||||
|
'datetime'))]),
|
||||||
'domain': fields.char(string='Domain'),
|
'domain': fields.char(string='Domain'),
|
||||||
'report_id': fields.many2one('mis.report', string='Report'),
|
'report_id': fields.many2one('mis.report', string='Report'),
|
||||||
}
|
}
|
||||||
|
@ -251,6 +275,7 @@ class mis_report_query(orm.Model):
|
||||||
|
|
||||||
|
|
||||||
class mis_report(orm.Model):
|
class mis_report(orm.Model):
|
||||||
|
|
||||||
""" A MIS report template (without period information)
|
""" A MIS report template (without period information)
|
||||||
|
|
||||||
The MIS report holds:
|
The MIS report holds:
|
||||||
|
@ -284,19 +309,24 @@ class mis_report(orm.Model):
|
||||||
if line[0] == 0:
|
if line[0] == 0:
|
||||||
line[2]['sequence'] = idx + 1
|
line[2]['sequence'] = idx + 1
|
||||||
else:
|
else:
|
||||||
mis_report_kpi_obj.write(cr, uid, [line[1]], {'sequence': idx + 1}, context=context)
|
mis_report_kpi_obj.write(
|
||||||
|
cr, uid, [line[1]], {'sequence': idx + 1},
|
||||||
|
context=context)
|
||||||
return super(mis_report, self).create(cr, uid, vals, context=context)
|
return super(mis_report, self).create(cr, uid, vals, context=context)
|
||||||
|
|
||||||
def write(self, cr, uid, ids, vals, context=None):
|
def write(self, cr, uid, ids, vals, context=None):
|
||||||
res = super(mis_report, self).write(cr, uid, ids, vals, context=context)
|
res = super(mis_report, self).write(
|
||||||
|
cr, uid, ids, vals, context=context)
|
||||||
mis_report_kpi_obj = self.pool.get('mis.report.kpi')
|
mis_report_kpi_obj = self.pool.get('mis.report.kpi')
|
||||||
for report in self.browse(cr, uid, ids, context):
|
for report in self.browse(cr, uid, ids, context):
|
||||||
for idx, kpi in enumerate(report.kpi_ids):
|
for idx, kpi in enumerate(report.kpi_ids):
|
||||||
mis_report_kpi_obj.write(cr, uid, [kpi.id], {'sequence': idx + 1}, context=context)
|
mis_report_kpi_obj.write(
|
||||||
|
cr, uid, [kpi.id], {'sequence': idx + 1}, context=context)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
class mis_report_instance_period(orm.Model):
|
class mis_report_instance_period(orm.Model):
|
||||||
|
|
||||||
""" A MIS report instance has the logic to compute
|
""" A MIS report instance has the logic to compute
|
||||||
a report template for a give date period.
|
a report template for a give date period.
|
||||||
|
|
||||||
|
@ -313,34 +343,45 @@ class mis_report_instance_period(orm.Model):
|
||||||
if c.type == 'd':
|
if c.type == 'd':
|
||||||
date_from = d + timedelta(days=c.offset)
|
date_from = d + timedelta(days=c.offset)
|
||||||
date_to = date_from + timedelta(days=c.duration - 1)
|
date_to = date_from + timedelta(days=c.duration - 1)
|
||||||
date_from = date_from.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
|
date_from = date_from.strftime(
|
||||||
|
tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||||
date_to = date_to.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
|
date_to = date_to.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||||
period_ids = None
|
period_ids = None
|
||||||
elif c.type == 'w':
|
elif c.type == 'w':
|
||||||
date_from = d - timedelta(d.weekday())
|
date_from = d - timedelta(d.weekday())
|
||||||
date_from = date_from + timedelta(days=c.offset * 7)
|
date_from = date_from + timedelta(days=c.offset * 7)
|
||||||
date_to = date_from + timedelta(days=(7 * c.duration) - 1)
|
date_to = date_from + timedelta(days=(7 * c.duration) - 1)
|
||||||
date_from = date_from.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
|
date_from = date_from.strftime(
|
||||||
|
tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||||
date_to = date_to.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
|
date_to = date_to.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||||
period_ids = None
|
period_ids = None
|
||||||
elif c.type == 'fp':
|
elif c.type == 'fp':
|
||||||
period_obj = self.pool['account.period']
|
period_obj = self.pool['account.period']
|
||||||
all_period_ids = period_obj.search(cr, uid,
|
all_period_ids = period_obj.search(
|
||||||
[('special', '=', False),
|
cr, uid,
|
||||||
'|', ('company_id', '=', False),
|
[('special', '=', False),
|
||||||
('company_id', '=', c.company_id.id)],
|
'|', (
|
||||||
order='date_start',
|
'company_id', '=',
|
||||||
context=context)
|
False),
|
||||||
current_period_ids = period_obj.search(cr, uid,
|
('company_id', '=',
|
||||||
[('special', '=', False),
|
c.company_id.id)],
|
||||||
('date_start', '<=', d),
|
order='date_start',
|
||||||
('date_stop', '>=', d),
|
context=context)
|
||||||
'|', ('company_id', '=', False),
|
current_period_ids = period_obj.search(
|
||||||
('company_id', '=', c.company_id.id)],
|
cr, uid,
|
||||||
context=context)
|
[('special', '=', False),
|
||||||
|
('date_start', '<=', d),
|
||||||
|
('date_stop',
|
||||||
|
'>=', d),
|
||||||
|
'|',
|
||||||
|
('company_id',
|
||||||
|
'=', False),
|
||||||
|
('company_id', '=', c.company_id.id)],
|
||||||
|
context=context)
|
||||||
if not current_period_ids:
|
if not current_period_ids:
|
||||||
raise orm.except_orm(_("Error!"),
|
raise orm.except_orm(_("Error!"),
|
||||||
_("No current fiscal period for %s") % d)
|
_("No current fiscal period for %s")
|
||||||
|
% d)
|
||||||
p = all_period_ids.index(current_period_ids[0]) + c.offset
|
p = all_period_ids.index(current_period_ids[0]) + c.offset
|
||||||
if p < 0 or p >= len(all_period_ids):
|
if p < 0 or p >= len(all_period_ids):
|
||||||
raise orm.except_orm(_("Error!"),
|
raise orm.except_orm(_("Error!"),
|
||||||
|
@ -396,11 +437,16 @@ class mis_report_instance_period(orm.Model):
|
||||||
'sequence': fields.integer(string='Sequence'),
|
'sequence': fields.integer(string='Sequence'),
|
||||||
'report_instance_id': fields.many2one('mis.report.instance',
|
'report_instance_id': fields.many2one('mis.report.instance',
|
||||||
string='Report Instance'),
|
string='Report Instance'),
|
||||||
'comparison_column_ids': fields.many2many('mis.report.instance.period', 'mis_report_instance_period_rel',
|
'comparison_column_ids': fields.many2many(
|
||||||
'period_id', 'compare_period_id', string='Compare with'),
|
'mis.report.instance.period',
|
||||||
|
'mis_report_instance_period_rel',
|
||||||
|
'period_id',
|
||||||
|
'compare_period_id',
|
||||||
|
string='Compare with'),
|
||||||
'company_id': fields.many2one('res.company', 'Company', required=True),
|
'company_id': fields.many2one('res.company', 'Company', required=True),
|
||||||
'normalize_factor': fields.integer(string='Factor',
|
'normalize_factor': fields.integer(
|
||||||
help='Factor to use to normalize the period (used in comparison'),
|
string='Factor',
|
||||||
|
help='Factor to use to normalize the period (used in comparison'),
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
|
@ -408,17 +454,22 @@ class mis_report_instance_period(orm.Model):
|
||||||
'duration': 1,
|
'duration': 1,
|
||||||
'sequence': 100,
|
'sequence': 100,
|
||||||
'normalize_factor': 1,
|
'normalize_factor': 1,
|
||||||
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid,
|
'company_id': lambda s, cr, uid, c:
|
||||||
'mis.report.instance.period',
|
s.pool.get('res.company')._company_default_get(
|
||||||
context=c)
|
cr, uid,
|
||||||
|
'mis.report.instance.period',
|
||||||
|
context=c)
|
||||||
}
|
}
|
||||||
|
|
||||||
_order = 'sequence'
|
_order = 'sequence'
|
||||||
|
|
||||||
_sql_constraints = [
|
_sql_constraints = [
|
||||||
('duration', 'CHECK (duration>0)', 'Wrong duration, it must be positive!'),
|
('duration', 'CHECK (duration>0)',
|
||||||
('normalize_factor', 'CHECK (normalize_factor>0)', 'Wrong normalize factor, it must be positive!'),
|
'Wrong duration, it must be positive!'),
|
||||||
('name_unique', 'unique(name, report_instance_id)', 'Period name should be unique by report'),
|
('normalize_factor', 'CHECK (normalize_factor>0)',
|
||||||
|
'Wrong normalize factor, it must be positive!'),
|
||||||
|
('name_unique', 'unique(name, report_instance_id)',
|
||||||
|
'Period name should be unique by report'),
|
||||||
]
|
]
|
||||||
|
|
||||||
def _fetch_balances(self, cr, uid, c, context=None):
|
def _fetch_balances(self, cr, uid, c, context=None):
|
||||||
|
@ -439,8 +490,11 @@ class mis_report_instance_period(orm.Model):
|
||||||
'date_to': c.date_to})
|
'date_to': c.date_to})
|
||||||
|
|
||||||
# TODO: initial balance?
|
# TODO: initial balance?
|
||||||
account_ids = account_obj.search(cr, uid, ['|', ('company_id', '=', False), ('company_id', '=', c.company_id.id)], context=context)
|
account_ids = account_obj.search(cr, uid, ['|', ('company_id', '=',
|
||||||
account_datas = account_obj.read(cr, uid, account_ids, ['code', 'balance'], context=search_ctx)
|
False), (
|
||||||
|
'company_id', '=', c.company_id.id)], context=context)
|
||||||
|
account_datas = account_obj.read(
|
||||||
|
cr, uid, account_ids, ['code', 'balance'], context=search_ctx)
|
||||||
balances = {}
|
balances = {}
|
||||||
for account_data in account_datas:
|
for account_data in account_datas:
|
||||||
key = 'bal' + _clean(account_data['code'])
|
key = 'bal' + _clean(account_data['code'])
|
||||||
|
@ -460,15 +514,20 @@ class mis_report_instance_period(orm.Model):
|
||||||
domain.extend([(query.date_field.name, '>=', c.date_from),
|
domain.extend([(query.date_field.name, '>=', c.date_from),
|
||||||
(query.date_field.name, '<=', c.date_to)])
|
(query.date_field.name, '<=', c.date_to)])
|
||||||
else:
|
else:
|
||||||
datetime_from = _utc_midnight(c.date_from, context.get('tz', 'UTC'))
|
datetime_from = _utc_midnight(
|
||||||
datetime_to = _utc_midnight(c.date_to, context.get('tz', 'UTC'), add_day=1)
|
c.date_from, context.get('tz', 'UTC'))
|
||||||
|
datetime_to = _utc_midnight(
|
||||||
|
c.date_to, context.get('tz', 'UTC'), add_day=1)
|
||||||
domain.extend([(query.date_field.name, '>=', datetime_from),
|
domain.extend([(query.date_field.name, '>=', datetime_from),
|
||||||
(query.date_field.name, '<', datetime_to)])
|
(query.date_field.name, '<', datetime_to)])
|
||||||
if obj._columns.get('company_id', False):
|
if obj._columns.get('company_id', False):
|
||||||
domain.extend(['|', ('company_id', '=', False), ('company_id', '=', c.company_id.id)])
|
domain.extend(
|
||||||
|
['|', ('company_id', '=', False), ('company_id', '=',
|
||||||
|
c.company_id.id)])
|
||||||
field_names = [field.name for field in query.field_ids]
|
field_names = [field.name for field in query.field_ids]
|
||||||
obj_ids = obj.search(cr, uid, domain, context=context)
|
obj_ids = obj.search(cr, uid, domain, context=context)
|
||||||
obj_datas = obj.read(cr, uid, obj_ids, field_names, context=context)
|
obj_datas = obj.read(
|
||||||
|
cr, uid, obj_ids, field_names, context=context)
|
||||||
res[query.name] = [AutoStruct(**d) for d in obj_datas]
|
res[query.name] = [AutoStruct(**d) for d in obj_datas]
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
@ -504,7 +563,8 @@ class mis_report_instance_period(orm.Model):
|
||||||
kpi_val_rendered = '#ERR'
|
kpi_val_rendered = '#ERR'
|
||||||
kpi_val_comment = traceback.format_exc()
|
kpi_val_comment = traceback.format_exc()
|
||||||
else:
|
else:
|
||||||
kpi_val_rendered = kpi_obj._render(cr, uid, kpi, kpi_val, context=context)
|
kpi_val_rendered = kpi_obj._render(
|
||||||
|
cr, uid, kpi, kpi_val, context=context)
|
||||||
kpi_val_comment = None
|
kpi_val_comment = None
|
||||||
|
|
||||||
localdict[kpi.name] = kpi_val
|
localdict[kpi.name] = kpi_val
|
||||||
|
@ -529,6 +589,7 @@ class mis_report_instance_period(orm.Model):
|
||||||
|
|
||||||
|
|
||||||
class mis_report_instance(orm.Model):
|
class mis_report_instance(orm.Model):
|
||||||
|
|
||||||
""" The MIS report instance combines compute and
|
""" The MIS report instance combines compute and
|
||||||
display a MIS report template for a set of periods """
|
display a MIS report template for a set of periods """
|
||||||
|
|
||||||
|
@ -564,37 +625,51 @@ class mis_report_instance(orm.Model):
|
||||||
string='Periods'),
|
string='Periods'),
|
||||||
'target_move': fields.selection([('posted', 'All Posted Entries'),
|
'target_move': fields.selection([('posted', 'All Posted Entries'),
|
||||||
('all', 'All Entries'),
|
('all', 'All Entries'),
|
||||||
], 'Target Moves', required=True),
|
], 'Target Moves', required=True),
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'target_move': 'posted',
|
'target_move': 'posted',
|
||||||
}
|
}
|
||||||
|
|
||||||
def create(self, cr, uid, vals, context=None):
|
def create(self, cr, uid, vals, context=None):
|
||||||
if 'period_ids' in vals:
|
if 'period_ids' in vals:
|
||||||
mis_report_instance_period_obj = self.pool.get('mis.report.instance.period')
|
mis_report_instance_period_obj = self.pool.get(
|
||||||
|
'mis.report.instance.period')
|
||||||
for idx, line in enumerate(vals['period_ids']):
|
for idx, line in enumerate(vals['period_ids']):
|
||||||
if line[0] == 0:
|
if line[0] == 0:
|
||||||
line[2]['sequence'] = idx + 1
|
line[2]['sequence'] = idx + 1
|
||||||
else:
|
else:
|
||||||
mis_report_instance_period_obj.write(cr, uid, [line[1]], {'sequence': idx + 1}, context=context)
|
mis_report_instance_period_obj.write(
|
||||||
return super(mis_report_instance, self).create(cr, uid, vals, context=context)
|
cr, uid, [line[1]], {'sequence': idx + 1},
|
||||||
|
context=context)
|
||||||
|
return super(mis_report_instance, self).create(cr, uid, vals,
|
||||||
|
context=context)
|
||||||
|
|
||||||
def write(self, cr, uid, ids, vals, context=None):
|
def write(self, cr, uid, ids, vals, context=None):
|
||||||
res = super(mis_report_instance, self).write(cr, uid, ids, vals, context=context)
|
res = super(mis_report_instance, self).write(
|
||||||
mis_report_instance_period_obj = self.pool.get('mis.report.instance.period')
|
cr, uid, ids, vals, context=context)
|
||||||
|
mis_report_instance_period_obj = self.pool.get(
|
||||||
|
'mis.report.instance.period')
|
||||||
for instance in self.browse(cr, uid, ids, context):
|
for instance in self.browse(cr, uid, ids, context):
|
||||||
for idx, period in enumerate(instance.period_ids):
|
for idx, period in enumerate(instance.period_ids):
|
||||||
mis_report_instance_period_obj.write(cr, uid, [period.id], {'sequence': idx + 1}, context=context)
|
mis_report_instance_period_obj.write(
|
||||||
|
cr, uid, [period.id], {'sequence': idx + 1},
|
||||||
|
context=context)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _format_date(self, cr, uid, date, context=None):
|
def _format_date(self, cr, uid, date, context=None):
|
||||||
# format date following user language
|
# format date following user language
|
||||||
lang = self.pool['res.users'].read(cr, uid, uid, ['lang'], context=context)['lang']
|
lang = self.pool['res.users'].read(
|
||||||
language_id = self.pool['res.lang'].search(cr, uid, [('code', '=', lang)], context=context)[0]
|
cr, uid, uid, ['lang'], context=context)['lang']
|
||||||
tformat = self.pool['res.lang'].read(cr, uid, language_id, ['date_format'])['date_format']
|
language_id = self.pool['res.lang'].search(
|
||||||
return datetime.strftime(datetime.strptime(date, tools.DEFAULT_SERVER_DATE_FORMAT), tformat)
|
cr, uid, [('code', '=', lang)], context=context)[0]
|
||||||
|
tformat = self.pool['res.lang'].read(
|
||||||
|
cr, uid, language_id, ['date_format'])['date_format']
|
||||||
|
return datetime.strftime(datetime.strptime(
|
||||||
|
date,
|
||||||
|
tools.DEFAULT_SERVER_DATE_FORMAT),
|
||||||
|
tformat)
|
||||||
|
|
||||||
def compute(self, cr, uid, _ids, context=None):
|
def compute(self, cr, uid, _ids, context=None):
|
||||||
assert isinstance(_ids, (int, long))
|
assert isinstance(_ids, (int, long))
|
||||||
|
@ -604,31 +679,37 @@ class mis_report_instance(orm.Model):
|
||||||
context['state'] = r.target_move
|
context['state'] = r.target_move
|
||||||
|
|
||||||
content = OrderedDict()
|
content = OrderedDict()
|
||||||
#empty line name for header
|
# empty line name for header
|
||||||
header = OrderedDict()
|
header = OrderedDict()
|
||||||
header[''] = {'kpi_name': '', 'cols': []}
|
header[''] = {'kpi_name': '', 'cols': []}
|
||||||
|
|
||||||
#initialize lines with kpi
|
# initialize lines with kpi
|
||||||
for kpi in r.report_id.kpi_ids:
|
for kpi in r.report_id.kpi_ids:
|
||||||
content[kpi.name] = {'kpi_name': kpi.description, 'cols': []}
|
content[kpi.name] = {'kpi_name': kpi.description, 'cols': []}
|
||||||
|
|
||||||
report_instance_period_obj = self.pool.get('mis.report.instance.period')
|
report_instance_period_obj = self.pool.get(
|
||||||
|
'mis.report.instance.period')
|
||||||
kpi_obj = self.pool.get('mis.report.kpi')
|
kpi_obj = self.pool.get('mis.report.kpi')
|
||||||
|
|
||||||
period_values = {}
|
period_values = {}
|
||||||
|
|
||||||
for period in r.period_ids:
|
for period in r.period_ids:
|
||||||
# add the column header
|
# add the column header
|
||||||
header['']['cols'].append(dict(name=period.name,
|
header['']['cols'].append(dict(
|
||||||
date=(period.duration > 1 or period.type == 'w') and
|
name=period.name,
|
||||||
_('from %s to %s' %
|
date=(period.duration > 1 or period.type == 'w') and
|
||||||
(period.period_from and period.period_from.name
|
_('from %s to %s' %
|
||||||
or self._format_date(cr, uid, period.date_from, context=context),
|
(period.period_from and period.period_from.name
|
||||||
period.period_to and period.period_to.name
|
or self._format_date(cr, uid, period.date_from,
|
||||||
or self._format_date(cr, uid, period.date_to, context=context)))
|
context=context),
|
||||||
or period.period_from and period.period_from.name or period.date_from))
|
period.period_to and period.period_to.name
|
||||||
|
or self._format_date(cr, uid, period.date_to,
|
||||||
|
context=context)))
|
||||||
|
or period.period_from and period.period_from.name or
|
||||||
|
period.date_from))
|
||||||
# compute kpi values
|
# compute kpi values
|
||||||
values = report_instance_period_obj._compute(cr, uid, period, context=context)
|
values = report_instance_period_obj._compute(
|
||||||
|
cr, uid, period, context=context)
|
||||||
period_values[period.name] = values
|
period_values[period.name] = values
|
||||||
for key in values:
|
for key in values:
|
||||||
content[key]['cols'].append(values[key])
|
content[key]['cols'].append(values[key])
|
||||||
|
@ -637,14 +718,22 @@ class mis_report_instance(orm.Model):
|
||||||
for period in r.period_ids:
|
for period in r.period_ids:
|
||||||
for compare_col in period.comparison_column_ids:
|
for compare_col in period.comparison_column_ids:
|
||||||
# add the column header
|
# add the column header
|
||||||
header['']['cols'].append(dict(name='%s - %s' % (period.name, compare_col.name), date=''))
|
header['']['cols'].append(
|
||||||
|
dict(name='%s - %s' % (period.name, compare_col.name),
|
||||||
|
date=''))
|
||||||
column1_values = period_values[period.name]
|
column1_values = period_values[period.name]
|
||||||
column2_values = period_values[compare_col.name]
|
column2_values = period_values[compare_col.name]
|
||||||
for kpi in r.report_id.kpi_ids:
|
for kpi in r.report_id.kpi_ids:
|
||||||
content[kpi.name]['cols'].append({'val_r': kpi_obj._render_comparison(cr, uid, kpi,
|
content[kpi.name]['cols'].append(
|
||||||
column1_values[kpi.name]['val'],
|
{'val_r': kpi_obj._render_comparison(
|
||||||
column2_values[kpi.name]['val'],
|
cr,
|
||||||
period.normalize_factor, compare_col.normalize_factor, context=context)})
|
uid,
|
||||||
|
kpi,
|
||||||
|
column1_values[kpi.name]['val'],
|
||||||
|
column2_values[kpi.name]['val'],
|
||||||
|
period.normalize_factor,
|
||||||
|
compare_col.normalize_factor,
|
||||||
|
context=context)})
|
||||||
|
|
||||||
return {'header': header,
|
return {'header': header,
|
||||||
'content': content}
|
'content': content}
|
||||||
|
|
|
@ -31,23 +31,29 @@ _logger = logging.getLogger(__name__)
|
||||||
class mis_builder_xls_parser(report_sxw.rml_parse):
|
class mis_builder_xls_parser(report_sxw.rml_parse):
|
||||||
|
|
||||||
def __init__(self, cr, uid, name, context):
|
def __init__(self, cr, uid, name, context):
|
||||||
super(mis_builder_xls_parser, self).__init__(cr, uid, name, context=context)
|
super(mis_builder_xls_parser, self).__init__(
|
||||||
|
cr, uid, name, context=context)
|
||||||
self.context = context
|
self.context = context
|
||||||
|
|
||||||
|
|
||||||
class mis_builder_xls(report_xls):
|
class mis_builder_xls(report_xls):
|
||||||
|
|
||||||
def __init__(self, name, table, rml=False, parser=False, header=True, store=False):
|
def __init__(self, name, table, rml=False, parser=False, header=True,
|
||||||
super(mis_builder_xls, self).__init__(name, table, rml, parser, header, store)
|
store=False):
|
||||||
|
super(mis_builder_xls, self).__init__(
|
||||||
|
name, table, rml, parser, header, store)
|
||||||
|
|
||||||
# Cell Styles
|
# Cell Styles
|
||||||
_xs = self.xls_styles
|
_xs = self.xls_styles
|
||||||
# header
|
# header
|
||||||
rh_cell_format = _xs['bold'] + _xs['fill'] + _xs['borders_all'] + _xs['right']
|
rh_cell_format = _xs['bold'] + _xs['fill'] + \
|
||||||
|
_xs['borders_all'] + _xs['right']
|
||||||
self.rh_cell_style = xlwt.easyxf(rh_cell_format)
|
self.rh_cell_style = xlwt.easyxf(rh_cell_format)
|
||||||
self.rh_cell_style_date = xlwt.easyxf(rh_cell_format, num_format_str=report_xls.date_format)
|
self.rh_cell_style_date = xlwt.easyxf(
|
||||||
|
rh_cell_format, num_format_str=report_xls.date_format)
|
||||||
# lines
|
# lines
|
||||||
self.mis_rh_cell_style = xlwt.easyxf(_xs['borders_all'] + _xs['bold'] + _xs['fill'])
|
self.mis_rh_cell_style = xlwt.easyxf(
|
||||||
|
_xs['borders_all'] + _xs['bold'] + _xs['fill'])
|
||||||
|
|
||||||
def generate_xls_report(self, _p, _xs, data, objects, wb):
|
def generate_xls_report(self, _p, _xs, data, objects, wb):
|
||||||
|
|
||||||
|
@ -68,26 +74,36 @@ class mis_builder_xls(report_xls):
|
||||||
('report_name', 1, 0, 'text', report_name),
|
('report_name', 1, 0, 'text', report_name),
|
||||||
]
|
]
|
||||||
row_data = self.xls_row_template(c_specs, ['report_name'])
|
row_data = self.xls_row_template(c_specs, ['report_name'])
|
||||||
row_pos = self.xls_write_row(ws, row_pos, row_data, row_style=xlwt.easyxf(_xs['xls_title']))
|
row_pos = self.xls_write_row(
|
||||||
|
ws, row_pos, row_data, row_style=xlwt.easyxf(_xs['xls_title']))
|
||||||
row_pos += 1
|
row_pos += 1
|
||||||
|
|
||||||
# get the computed result of the report
|
# get the computed result of the report
|
||||||
data = self.pool.get('mis.report.instance').compute(self.cr, self.uid, objects[0].id)
|
data = self.pool.get('mis.report.instance').compute(
|
||||||
|
self.cr, self.uid, objects[0].id)
|
||||||
|
|
||||||
# Column headers
|
# Column headers
|
||||||
header_name_list = ['']
|
header_name_list = ['']
|
||||||
col_specs_template = {'': {'header': [1, 30, 'text', ''],
|
col_specs_template = {'': {'header': [1, 30, 'text', ''],
|
||||||
'header_date': [1, 1, 'text', '']}}
|
'header_date': [1, 1, 'text', '']}}
|
||||||
for col in data['header']['']['cols']:
|
for col in data['header']['']['cols']:
|
||||||
col_specs_template[col['name']] = {'header': [1, 30, 'text', col['name']],
|
col_specs_template[col['name']] = {'header': [1, 30, 'text',
|
||||||
'header_date': [1, 1, 'text', col['date']]}
|
col['name']],
|
||||||
|
'header_date': [1, 1, 'text',
|
||||||
|
col['date']]}
|
||||||
header_name_list.append(col['name'])
|
header_name_list.append(col['name'])
|
||||||
c_specs = map(lambda x: self.render(x, col_specs_template, 'header'), header_name_list)
|
c_specs = map(
|
||||||
|
lambda x: self.render(x, col_specs_template, 'header'),
|
||||||
|
header_name_list)
|
||||||
row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
|
row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
|
||||||
row_pos = self.xls_write_row(ws, row_pos, row_data, row_style=self.rh_cell_style, set_column_size=True)
|
row_pos = self.xls_write_row(
|
||||||
c_specs = map(lambda x: self.render(x, col_specs_template, 'header_date'), header_name_list)
|
ws, row_pos, row_data, row_style=self.rh_cell_style,
|
||||||
|
set_column_size=True)
|
||||||
|
c_specs = map(lambda x: self.render(
|
||||||
|
x, col_specs_template, 'header_date'), header_name_list)
|
||||||
row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
|
row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
|
||||||
row_pos = self.xls_write_row(ws, row_pos, row_data, row_style=self.rh_cell_style_date)
|
row_pos = self.xls_write_row(
|
||||||
|
ws, row_pos, row_data, row_style=self.rh_cell_style_date)
|
||||||
|
|
||||||
ws.set_horz_split_pos(row_pos)
|
ws.set_horz_split_pos(row_pos)
|
||||||
ws.set_vert_split_pos(1)
|
ws.set_vert_split_pos(1)
|
||||||
|
@ -104,7 +120,9 @@ class mis_builder_xls(report_xls):
|
||||||
num_format_str += '0' * int(value['dp'])
|
num_format_str += '0' * int(value['dp'])
|
||||||
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_cell_style = xlwt.easyxf(_xs['borders_all'] + _xs['right'], num_format_str=num_format_str)
|
kpi_cell_style = xlwt.easyxf(
|
||||||
|
_xs['borders_all'] + _xs['right'],
|
||||||
|
num_format_str=num_format_str)
|
||||||
if value.get('val'):
|
if value.get('val'):
|
||||||
val = value['val']
|
val = value['val']
|
||||||
if value.get('is_percentage'):
|
if value.get('is_percentage'):
|
||||||
|
@ -116,7 +134,7 @@ class mis_builder_xls(report_xls):
|
||||||
|
|
||||||
|
|
||||||
mis_builder_xls('report.mis.report.instance.xls',
|
mis_builder_xls('report.mis.report.instance.xls',
|
||||||
'mis.report.instance',
|
'mis.report.instance',
|
||||||
parser=mis_builder_xls_parser)
|
parser=mis_builder_xls_parser)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -37,29 +37,42 @@ class mis_builder_test(common.TransactionCase):
|
||||||
|
|
||||||
def test_datetime_conversion(self):
|
def test_datetime_conversion(self):
|
||||||
date_to_convert = '2014-07-05'
|
date_to_convert = '2014-07-05'
|
||||||
date_time_convert = models.mis_builder._utc_midnight(date_to_convert, 'Europe/Brussels')
|
date_time_convert = models.mis_builder._utc_midnight(
|
||||||
self.assertEqual(date_time_convert, '2014-07-04 22:00:00', 'The converted date time convert must contains hour')
|
date_to_convert, 'Europe/Brussels')
|
||||||
date_time_convert = models.mis_builder._utc_midnight(date_to_convert, 'Europe/Brussels', add_day=1)
|
self.assertEqual(date_time_convert, '2014-07-04 22:00:00',
|
||||||
self.assertEqual(date_time_convert, '2014-07-05 22:00:00', 'The converted date time convert must contains hour')
|
'The converted date time convert must contains hour')
|
||||||
date_time_convert = models.mis_builder._utc_midnight(date_to_convert, 'US/Pacific')
|
date_time_convert = models.mis_builder._utc_midnight(
|
||||||
self.assertEqual(date_time_convert, '2014-07-05 07:00:00', 'The converted date time convert must contains hour')
|
date_to_convert, 'Europe/Brussels', add_day=1)
|
||||||
date_time_convert = models.mis_builder._utc_midnight(date_to_convert, 'US/Pacific', add_day=1)
|
self.assertEqual(date_time_convert, '2014-07-05 22:00:00',
|
||||||
self.assertEqual(date_time_convert, '2014-07-06 07:00:00', 'The converted date time convert must contains hour')
|
'The converted date time convert must contains hour')
|
||||||
|
date_time_convert = models.mis_builder._utc_midnight(
|
||||||
|
date_to_convert, 'US/Pacific')
|
||||||
|
self.assertEqual(date_time_convert, '2014-07-05 07:00:00',
|
||||||
|
'The converted date time convert must contains hour')
|
||||||
|
date_time_convert = models.mis_builder._utc_midnight(
|
||||||
|
date_to_convert, 'US/Pacific', add_day=1)
|
||||||
|
self.assertEqual(date_time_convert, '2014-07-06 07:00:00',
|
||||||
|
'The converted date time convert must contains hour')
|
||||||
|
|
||||||
def test_fetch_query(self):
|
def test_fetch_query(self):
|
||||||
# create a report on a model without company_id field : account.analytic.balance
|
# create a report on a model without company_id field :
|
||||||
data = self.registry('mis.report.instance').compute(self.cr, self.uid, self.ref('mis_builder.mis_report_instance_test'))
|
# account.analytic.balance
|
||||||
self.assertDictContainsSubset({'content': OrderedDict([(u'total_test',
|
data = self.registry('mis.report.instance').compute(
|
||||||
{'kpi_name': u'total test',
|
self.cr, self.uid,
|
||||||
'cols': [{'style': None,
|
self.ref('mis_builder.mis_report_instance_test'))
|
||||||
'val_c': None,
|
self.assertDictContainsSubset(
|
||||||
'val': 0,
|
{'content':
|
||||||
'val_r': '0 '}]})]),
|
OrderedDict([(u'total_test',
|
||||||
'header': OrderedDict([('',
|
{'kpi_name': u'total test',
|
||||||
{'kpi_name': '',
|
'cols': [{'style': None,
|
||||||
'cols': [{'date': '2014-07-31',
|
'val_c': None,
|
||||||
'name': u'today'}]
|
'val': 0,
|
||||||
})])
|
'val_r': '0 '}]})]),
|
||||||
}, data)
|
'header': OrderedDict([('',
|
||||||
|
{'kpi_name': '',
|
||||||
|
'cols': [{'date': '2014-07-31',
|
||||||
|
'name': u'today'}]
|
||||||
|
})])
|
||||||
|
}, data)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
Binary file not shown.
|
@ -29,17 +29,21 @@ class add_mis_report_instance_dashboard(orm.TransientModel):
|
||||||
_name = "add.mis.report.instance.dashboard.wizard"
|
_name = "add.mis.report.instance.dashboard.wizard"
|
||||||
|
|
||||||
_columns = {'name': fields.char('Name', size=32, required=True),
|
_columns = {'name': fields.char('Name', size=32, required=True),
|
||||||
'dashboard_id': fields.many2one('ir.actions.act_window', string="Dashboard", required=True,
|
'dashboard_id': fields.many2one(
|
||||||
domain="[('res_model', '=', 'board.board')]"),
|
'ir.actions.act_window',
|
||||||
|
string="Dashboard", required=True,
|
||||||
|
domain="[('res_model', '=', 'board.board')]"),
|
||||||
}
|
}
|
||||||
|
|
||||||
def default_get(self, cr, uid, fields, context=None):
|
def default_get(self, cr, uid, fields, context=None):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
if context.get('active_id'):
|
if context.get('active_id'):
|
||||||
res = super(add_mis_report_instance_dashboard, self).default_get(cr, uid, fields, context=context)
|
res = super(add_mis_report_instance_dashboard, self).default_get(
|
||||||
|
cr, uid, fields, context=context)
|
||||||
# get report instance name
|
# get report instance name
|
||||||
res['name'] = self.pool['mis.report.instance'].read(cr, uid, context['active_id'], ['name'])['name']
|
res['name'] = self.pool['mis.report.instance'].read(
|
||||||
|
cr, uid, context['active_id'], ['name'])['name']
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def action_add_to_dashboard(self, cr, uid, ids, context=None):
|
def action_add_to_dashboard(self, cr, uid, ids, context=None):
|
||||||
|
@ -48,28 +52,36 @@ class add_mis_report_instance_dashboard(orm.TransientModel):
|
||||||
assert 'active_id' in context, "active_id missing in context"
|
assert 'active_id' in context, "active_id missing in context"
|
||||||
wizard_data = self.browse(cr, uid, ids, context=context)[0]
|
wizard_data = self.browse(cr, uid, ids, context=context)[0]
|
||||||
# create the act_window corresponding to this report
|
# create the act_window corresponding to this report
|
||||||
view_id = self.pool['ir.model.data'].get_object_reference(cr, uid, 'mis_builder', 'mis_report_instance_result_view_form')[1]
|
view_id = self.pool['ir.model.data'].get_object_reference(
|
||||||
report_result = self.pool['ir.actions.act_window'].create(cr, uid, {'name': 'mis.report.instance.result.view.action.%d' % context['active_id'],
|
cr, uid, 'mis_builder', 'mis_report_instance_result_view_form')[1]
|
||||||
'res_model': 'mis.report.instance',
|
report_result = self.pool['ir.actions.act_window'].create(
|
||||||
'res_id': context['active_id'],
|
cr, uid,
|
||||||
'target': 'current',
|
{'name': 'mis.report.instance.result.view.action.%d'
|
||||||
'view_mode': 'form',
|
% context['active_id'],
|
||||||
'view_id': view_id})
|
'res_model': 'mis.report.instance',
|
||||||
|
'res_id': context['active_id'],
|
||||||
|
'target': 'current',
|
||||||
|
'view_mode': 'form',
|
||||||
|
'view_id': view_id})
|
||||||
# add this result in the selected dashboard
|
# add this result in the selected dashboard
|
||||||
last_customization = self.pool['ir.ui.view.custom'].search(cr, uid, [('user_id', '=', uid),
|
last_customization = self.pool['ir.ui.view.custom'].search(
|
||||||
('ref_id', '=', wizard_data.dashboard_id.view_id.id)], limit=1)
|
cr, uid,
|
||||||
|
[('user_id', '=', uid),
|
||||||
|
('ref_id', '=', wizard_data.dashboard_id.view_id.id)], limit=1)
|
||||||
arch = wizard_data.dashboard_id.view_id.arch
|
arch = wizard_data.dashboard_id.view_id.arch
|
||||||
if last_customization:
|
if last_customization:
|
||||||
arch = self.pool['ir.ui.view.custom'].read(cr, uid, last_customization[0], ['arch'])['arch']
|
arch = self.pool['ir.ui.view.custom'].read(
|
||||||
|
cr, uid, last_customization[0], ['arch'])['arch']
|
||||||
new_arch = etree.fromstring(arch)
|
new_arch = etree.fromstring(arch)
|
||||||
column = new_arch.xpath("//column")[0]
|
column = new_arch.xpath("//column")[0]
|
||||||
column.append(etree.Element('action', {'context': str(context),
|
column.append(etree.Element('action', {'context': str(context),
|
||||||
'name': str(report_result),
|
'name': str(report_result),
|
||||||
'string': wizard_data.name,
|
'string': wizard_data.name,
|
||||||
'view_mode': 'form'}))
|
'view_mode': 'form'}))
|
||||||
self.pool['ir.ui.view.custom'].create(cr, uid, {'user_id': uid,
|
self.pool['ir.ui.view.custom'].create(
|
||||||
'ref_id': wizard_data.dashboard_id.view_id.id,
|
cr, uid, {'user_id': uid,
|
||||||
'arch': etree.tostring(new_arch, pretty_print=True)})
|
'ref_id': wizard_data.dashboard_id.view_id.id,
|
||||||
|
'arch': etree.tostring(new_arch, pretty_print=True)})
|
||||||
|
|
||||||
return {'type': 'ir.actions.act_window_close', }
|
return {'type': 'ir.actions.act_window_close', }
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
'mis.report.csv',
|
'mis.report.csv',
|
||||||
'mis.report.instance.period.csv',
|
'mis.report.instance.period.csv',
|
||||||
'mis.report.instance.csv',
|
'mis.report.instance.csv',
|
||||||
],
|
],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'application': True,
|
'application': True,
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
|
|
Loading…
Reference in New Issue