Browse Source

[IMP] Complete methods. Add cron. Improve views.

Needs color and gauge web widget to complete module:
http://www.openerp.com/forum/topic33798.html
pull/510/head^2
Maxime Chambreuil 12 years ago
parent
commit
ffbb291606
  1. 138
      mgmtsystem_kpi/mgmtsystem_kpi.py
  2. 149
      mgmtsystem_kpi/mgmtsystem_kpi.xml

138
mgmtsystem_kpi/mgmtsystem_kpi.py

@ -19,6 +19,8 @@
#
##############################################################################
from dateutil.relativedelta import relativedelta
from datetime import datetime
from osv import fields, osv
import time
@ -43,22 +45,50 @@ class mgmtsystem_kpi_threshold_range(osv.osv):
_description = "KPI Threshold Range"
def _compute_min_value(self, cr, uid, ids, field_name, arg, context=None):
if context is None:
context = {}
result = {}
for obj in self.browse(cr, uid, ids):
value = 0
if obj.min_type == 'sql':
cr.execute(obj.min_code)
value = cr.dictfetchone()['value']
elif obj.min_type == 'python':
value = eval(obj.min_code)
else:
value = obj.min_fixed_value
result[obj.id] = value
return result
def _compute_max_value(self, cr, uid, ids, field_name, arg, context=None):
if context is None:
context = {}
result = {}
for obj in self.browse(cr, uid, ids):
value = 0
if obj.max_type == 'sql':
cr.execute(obj.max_code)
value = cr.dictfetchone()['value']
elif obj.max_type == 'python':
value = eval(obj.max_code)
else:
value = obj.max_fixed_value
result[obj.id] = value
return result
_columns = {
'name': fields.char('Name', size=50, required=True),
'min_type': fields.selection((('static','Fixed value'), ('dynamic','Computed value')), 'Min Type', required=True),
'min_type': fields.selection((('static','Fixed value'), ('python','Python Code'), ('sql', 'SQL Query')), 'Min Type', required=True),
'min_value': fields.function(_compute_min_value, string='Minimum', type='float'),
'min_fixed_value': fields.float('Minimum'),
'min_code': fields.text('Minimum Computation Code'),
'max_type': fields.selection((('static','Fixed value'), ('dynamic','Computed value')), 'Max Type', required=True),
'max_type': fields.selection((('static','Fixed value'), ('python','Python Code'), ('sql', 'SQL Query')), 'Max Type', required=True),
'max_value': fields.function(_compute_max_value, string='Maximum', type='float'),
'max_fixed_value': fields.float('Maximum'),
'max_code': fields.text('Maximum Computation Code'),
@ -81,19 +111,6 @@ class mgmtsystem_kpi_threshold(osv.osv):
mgmtsystem_kpi_threshold()
class mgmtsystem_kpi_periodicity_uom(osv.osv):
"""
Unit of Measure for Periodicity
"""
_name = "mgmtsystem.kpi.periodicity.uom"
_description = "Periodicity Unit of Measure"
_columns = {
'name': fields.char('Name', size=10, required=True),
}
mgmtsystem_kpi_threshold()
class mgmtsystem_kpi_history(osv.osv):
"""
History of the KPI
@ -113,6 +130,8 @@ class mgmtsystem_kpi_history(osv.osv):
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
}
_order = "date desc"
mgmtsystem_kpi_threshold()
class mgmtsystem_kpi(osv.osv):
@ -123,14 +142,82 @@ class mgmtsystem_kpi(osv.osv):
_description = "Key Performance Indicator"
def _display_last_kpi_value(self, cr, uid, ids, field_name, arg, context=None):
if context is None:
context = {}
result = {}
for obj in self.browse(cr, uid, ids):
if obj.history_ids:
result[obj.id] = obj.history_ids[0].value
else:
result[obj.id] = 0
return result
def _compute_kpi_value(self, cr, uid, ids, field_name, arg, context=None):
result = {}
def compute_kpi_value(self, cr, uid, ids, context=None):
if context is None:
context = {}
kpi_value = 0
for obj in self.browse(cr, uid, ids):
kpi_value = 0
if obj.kpi_type == 'sql':
cr.execute(obj.kpi_code)
kpi_value = cr.dictfetchone()['value']
elif obj.kpi_type == 'python':
kpi_value = eval(obj.kpi_code)
values = {
'kpi_id': obj.id,
'value': kpi_value,
}
return result
history_obj = self.pool.get('mgmtsystem.kpi.history')
history_id = history_obj.create(cr, uid, values, context=context)
obj.history_ids.append(history_id)
return True
def update_next_execution_date(self, cr, uid, ids, context=None):
if context is None:
context = {}
for obj in self.browse(cr, uid, ids):
if obj.periodicity_uom == 'hour':
new_date = datetime.now() + relativedelta( hours = +obj.periodicity )
elif obj.periodicity_uom == 'day':
new_date = datetime.now() + relativedelta( days = +obj.periodicity )
elif obj.periodicity_uom == 'week':
new_date = datetime.now() + relativedelta( weeks = +obj.periodicity )
elif obj.periodicity_uom == 'month':
new_date = datetime.now() + relativedelta( months = +obj.periodicity )
values = {
'next_execution_date': new_date.strftime('%Y-%m-%d %H:%M:%S'),
}
obj.write(values)
return True
# Method called by the scheduler
def update_kpi_value(self, cr, uid, ids=None, context=None):
if context is None:
context = {}
if not ids:
filters = ['&', '|', ('active', '=', True), ('next_execution_date', '<=', datetime.now().strftime('%Y-%m-%d %H:%M:%S')), ('next_execution_date', '=', False)]
if 'filters' in context:
filters.extend(context['filters'])
ids = self.search(cr, uid, filters, context=context)
res = None
try:
res = self.compute_kpi_value(cr, uid, ids, context=context)
self.update_next_execution_date(cr, uid, ids, context=context)
except Exception:
_logger.exception("Failed updating KPI values")
return res
_columns = {
'name': fields.char('Name', size=50, required=True),
@ -138,10 +225,19 @@ class mgmtsystem_kpi(osv.osv):
'category_id': fields.many2one('mgmtsystem.kpi.category','Category', required=True),
'threshold_id': fields.many2one('mgmtsystem.kpi.threshold','Threshold', required=True),
'periodicity': fields.integer('Periodicity'),
'periodicity_uom': fields.many2one('mgmtsystem.kpi.periodicity.uom','Periodicity UoM', required=True),
'periodicity_uom': fields.selection((('hour','Hour'), ('day','Day'), ('week','Week'), ('month','Month')), 'Periodicity UoM', required=True),
'next_execution_date': fields.datetime('Next execution date', readonly=True),
'value': fields.function(_display_last_kpi_value, string='Value', type='float'),
'kpi_code': fields.text('KPI Computation Code'),
'history_ids': fields.one2many('mgmtsystem.kpi.history', 'kpi_id', 'History')
'kpi_type': fields.selection((('sql','SQL'), ('python','Python')),'KPI Computation Type'),
'kpi_code': fields.text('KPI Code', help='SQL code must return the result as \'value\' (i.e. \'SELECT 5 AS value\').'),
'history_ids': fields.one2many('mgmtsystem.kpi.history', 'kpi_id', 'History'),
'active': fields.boolean('Active', help="Only active KPIs will be updated by the scheduler based on the periodicity configuration."),
}
_defaults = {
'active': True,
'periodicity': 1,
'periodicity_uom': 'day',
}
mgmtsystem_kpi()

149
mgmtsystem_kpi/mgmtsystem_kpi.xml

@ -11,35 +11,67 @@
<field name="arch" type="xml">
<tree string="Key Performance Indicators">
<field name="name"/>
<field name="value" widget="progressbar"/>
<field name="category_id"/>
<field name="threshold_id"/>
<field name="value"/>
</tree>
</field>
</record>
<record id="view_mgmtsystem_kpi_filter" model="ir.ui.view">
<field name="name">mgmtsystem.kpi.filter</field>
<field name="model">mgmtsystem.kpi</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="KPI">
<group>
<filter name="active" icon="terp-document-new" domain="[('active','=',True)]" string="Active" help="Only active KPIs are computed by the scheduler based on the periodicity configuration."/>
<separator orientation="vertical"/>
<field name="name"/>
<field name="category_id"/>
</group>
<newline />
<group expand="0" string="Group By...">
<filter string="Category" context="{'group_by':'category_id'}"/>
</group>
</search>
</field>
</record>
<record id="view_mgmtsystem_kpi_form" model="ir.ui.view">
<field name="name">mgmtsystem.kpi.form</field>
<field name="model">mgmtsystem.kpi</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Key Performance Indicator">
<field name="name"/>
<field name="category_id"/>
<newline/>
<field name="threshold_id"/>
<group col="6" colspan="6">
<field name="name" colspan="2"/>
<field name="threshold_id" colspan="2"/>
<field name="category_id" colspan="2"/>
<newline/>
<field name="value"/>
<button name="_compute_kpi_value" string="Compute KPI Now" colspan="2"/>
<newline/>
<field name="periodicity"/>
<field name="periodicity_uom"/>
<field name="value" colspan="2"/>
<button name="compute_kpi_value" string="Compute KPI Now" colspan="2" type="object"/>
<field name="active" colspan="2"/>
</group>
<notebook colspan="6">
<page string="History">
<field name="history_ids" readonly="1" nolabel="1"/>
</page>
<page string="Computation">
<group col="6">
<field name="periodicity" colspan="2"/>
<field name="periodicity_uom" colspan="2"/>
<field name="next_execution_date" colspan="2"/>
<separator string="KPI Computation" colspan="6"/>
<newline/>
<field name="kpi_code" colspan="4"/>
<newline/>
<field name="description" colspan="4"/>
<field name="kpi_type" colspan="2"/>
<newline/>
<field name="history_ids" colspan="4" readonly="1"/>
<field name="kpi_code" colspan="6"/>
</group>
</page>
<page string="Description">
<field name="description" nolabel="1"/>
</page>
</notebook>
</form>
</field>
</record>
@ -50,6 +82,7 @@
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_mgmtsystem_kpi_tree"/>
<field name="search_view_id" ref="view_mgmtsystem_kpi_filter"/>
</record>
<menuitem id="menu_mgmtsystem_kpi"
@ -74,6 +107,55 @@
</field>
</record>
<!-- Configuration menu -->
<menuitem id="menu_mgmtsystem_configuration_kpi"
name="KPI"
parent="mgmtsystem.menu_mgmtsystem_configuration"
groups="base.group_mgmtsystem_manager"
sequence="20"/>
<!-- Categories -->
<record id="view_mgmtsystem_kpi_category_tree" model="ir.ui.view">
<field name="name">mgmtsystem.kpi.category.tree</field>
<field name="model">mgmtsystem.kpi.category</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Categories">
<field name="name"/>
</tree>
</field>
</record>
<record id="view_mgmtsystem_kpi_category_form" model="ir.ui.view">
<field name="name">mgmtsystem.kpi.category.form</field>
<field name="model">mgmtsystem.kpi.category</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Category">
<field name="name"/>
<newline/>
<field name="description" colspan="4"/>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="open_mgmtsystem_category_list">
<field name="name">Categories</field>
<field name="res_model">mgmtsystem.kpi.category</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_mgmtsystem_kpi_category_tree"/>
</record>
<menuitem id="menu_mgmtsystem_configuration_kpi_category"
name="Categories"
action="open_mgmtsystem_category_list"
parent="menu_mgmtsystem_configuration_kpi"
groups="base.group_mgmtsystem_manager"
sequence="10"/>
<!-- Thresholds -->
<record id="view_mgmtsystem_kpi_threshold_tree" model="ir.ui.view">
@ -100,18 +182,13 @@
<field name="name"/>
<field name="min_value"/>
<field name="max_value"/>
<field name="color"/>
</tree>
</field>
</form>
</field>
</record>
<menuitem id="menu_mgmtsystem_configuration_kpi"
name="KPI"
parent="mgmtsystem.menu_mgmtsystem_configuration"
groups="base.group_mgmtsystem_manager"
sequence="20"/>
<record model="ir.actions.act_window" id="open_mgmtsystem_threshold_list">
<field name="name">Thresholds</field>
<field name="res_model">mgmtsystem.kpi.threshold</field>
@ -157,14 +234,14 @@
<field name="min_type"/>
<field name="min_fixed_value" attrs="{'invisible' : [('min_type', '!=', 'static')]}"/>
<newline/>
<field name="min_code" colspan="4" attrs="{'invisible' : [('min_type', '!=', 'dynamic')]}"/>
<field name="min_code" colspan="4" attrs="{'invisible' : [('min_type', 'NOT IN', ('sql','python'))]}"/>
<newline/>
<separator string="Maximum" colspan="4"/>
<newline/>
<field name="max_type"/>
<field name="max_fixed_value" attrs="{'invisible' : [('max_type', '!=', 'static')]}"/>
<newline/>
<field name="max_code" colspan="4" attrs="{'invisible' : [('max_type', '!=', 'dynamic')]}"/>
<field name="max_code" colspan="4" attrs="{'invisible' : [('max_type', 'NOT IN', ('sql','python'))]}"/>
</form>
</field>
</record>
@ -184,22 +261,20 @@
groups="base.group_mgmtsystem_manager"
sequence="20"/>
<!-- data -->
<record model="mgmtsystem.kpi.periodicity.uom" id="hour">
<field name="name">Hour</field>
</record>
<record model="mgmtsystem.kpi.periodicity.uom" id="day">
<field name="name">Day</field>
</record>
</data>
<record model="mgmtsystem.kpi.periodicity.uom" id="week">
<field name="name">Week</field>
</record>
<data noupdate="1">
<record model="mgmtsystem.kpi.periodicity.uom" id="month">
<field name="name">Month</field>
<record forcecreate="True" id="ir_cron_mgmtsystem_kpi_action" model="ir.cron">
<field name="name">Update KPI values</field>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">hours</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
<field eval="'mgmtsystem.kpi'" name="model"/>
<field eval="'update_kpi_value'" name="function"/>
<field eval="'()'" name="args"/>
</record>
</data>

Loading…
Cancel
Save