|
|
@ -1,6 +1,6 @@ |
|
|
|
# -*- encoding: utf-8 -*- |
|
|
|
############################################################################## |
|
|
|
# |
|
|
|
# |
|
|
|
# OpenERP, Open Source Management Solution |
|
|
|
# Copyright (C) 2012 Savoir-faire Linux (<http://www.savoirfairelinux.com>). |
|
|
|
# |
|
|
@ -15,19 +15,19 @@ |
|
|
|
# GNU Affero General Public License for more details. |
|
|
|
# |
|
|
|
# You should have received a copy of the GNU Affero General Public License |
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
# |
|
|
|
############################################################################## |
|
|
|
|
|
|
|
from dateutil.relativedelta import relativedelta |
|
|
|
from datetime import datetime |
|
|
|
from osv import fields, osv |
|
|
|
from osv import fields, orm, osv |
|
|
|
from openerp.tools.translate import _ |
|
|
|
import openerp.tools as tools |
|
|
|
import time |
|
|
|
import logging |
|
|
|
_logger = logging.getLogger(__name__) |
|
|
|
|
|
|
|
|
|
|
|
def is_one_value(result): |
|
|
|
# check if sql query returns only one value |
|
|
|
if type(result) is dict and 'value' in result.dictfetchone(): |
|
|
@ -37,6 +37,7 @@ def is_one_value(result): |
|
|
|
else: |
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
def is_select_query(query): |
|
|
|
# check if sql query is a SELECT statement |
|
|
|
|
|
|
@ -45,7 +46,8 @@ def is_select_query(query): |
|
|
|
return False |
|
|
|
return True |
|
|
|
|
|
|
|
class mgmtsystem_kpi_category(osv.osv): |
|
|
|
|
|
|
|
class mgmtsystem_kpi_category(orm.Model): |
|
|
|
""" |
|
|
|
KPI Category |
|
|
|
""" |
|
|
@ -56,9 +58,8 @@ class mgmtsystem_kpi_category(osv.osv): |
|
|
|
'description': fields.text('Description') |
|
|
|
} |
|
|
|
|
|
|
|
mgmtsystem_kpi_category() |
|
|
|
|
|
|
|
class mgmtsystem_kpi_threshold_range(osv.osv): |
|
|
|
class mgmtsystem_kpi_threshold_range(orm.Model): |
|
|
|
""" |
|
|
|
KPI Threshold Range |
|
|
|
""" |
|
|
@ -70,7 +71,7 @@ class mgmtsystem_kpi_threshold_range(osv.osv): |
|
|
|
context = {} |
|
|
|
result = {} |
|
|
|
for obj in self.browse(cr, uid, ids): |
|
|
|
value = None |
|
|
|
value = None |
|
|
|
if obj.min_type == 'local' and is_select_query(obj.min_code): |
|
|
|
cr.execute(obj.min_code) |
|
|
|
dic = cr.dictfetchall() |
|
|
@ -119,7 +120,7 @@ class mgmtsystem_kpi_threshold_range(osv.osv): |
|
|
|
if obj.max_value < obj.min_value: |
|
|
|
result[obj.id] = False |
|
|
|
else: |
|
|
|
result[obj.id] = True |
|
|
|
result[obj.id] = True |
|
|
|
return result |
|
|
|
|
|
|
|
def _generate_invalid_message(self, cr, uid, ids, field_name, arg, context=None): |
|
|
@ -137,18 +138,18 @@ class mgmtsystem_kpi_threshold_range(osv.osv): |
|
|
|
'name': fields.char('Name', size=50, required=True), |
|
|
|
'valid': fields.function(_is_valid_range, string='Valid', type='boolean', required=True), |
|
|
|
'invalid_message': fields.function(_generate_invalid_message, string='Message', type='char', size=100), |
|
|
|
'min_type': fields.selection((('static','Fixed value'), ('python','Python Code'), ('local', 'SQL - Local DB'), ('external', 'SQL - Externa DB')), 'Min Type', required=True), |
|
|
|
'min_type': fields.selection((('static', 'Fixed value'), ('python', 'Python Code'), ('local', 'SQL - Local DB'), ('external', 'SQL - Externa DB')), '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'), |
|
|
|
'min_dbsource_id': fields.many2one('base.external.dbsource','External DB Source'), |
|
|
|
'max_type': fields.selection((('static','Fixed value'), ('python','Python Code'), ('local', 'SQL - Local DB'), ('external', 'SQL - External DB')), 'Max Type', required=True), |
|
|
|
'min_dbsource_id': fields.many2one('base.external.dbsource', 'External DB Source'), |
|
|
|
'max_type': fields.selection((('static', 'Fixed value'), ('python', 'Python Code'), ('local', 'SQL - Local DB'), ('external', 'SQL - External DB')), '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'), |
|
|
|
'max_dbsource_id': fields.many2one('base.external.dbsource','External DB Source'), |
|
|
|
'max_dbsource_id': fields.many2one('base.external.dbsource', 'External DB Source'), |
|
|
|
'color': fields.char('Color', help='RGB code with #', size=7, required=True), |
|
|
|
'threshold_ids': fields.many2many('mgmtsystem.kpi.threshold','mgmtsystem_kpi_threshold_range_rel', 'range_id', 'threshold_id', 'Thresholds'), |
|
|
|
'threshold_ids': fields.many2many('mgmtsystem.kpi.threshold', 'mgmtsystem_kpi_threshold_range_rel', 'range_id', 'threshold_id', 'Thresholds'), |
|
|
|
'company_id': fields.many2one('res.company', 'Company') |
|
|
|
} |
|
|
|
|
|
|
@ -157,9 +158,8 @@ class mgmtsystem_kpi_threshold_range(osv.osv): |
|
|
|
'valid': True, |
|
|
|
} |
|
|
|
|
|
|
|
mgmtsystem_kpi_threshold_range() |
|
|
|
|
|
|
|
class mgmtsystem_kpi_threshold(osv.osv): |
|
|
|
class mgmtsystem_kpi_threshold(orm.Model): |
|
|
|
""" |
|
|
|
KPI Threshold |
|
|
|
""" |
|
|
@ -194,7 +194,7 @@ class mgmtsystem_kpi_threshold(osv.osv): |
|
|
|
|
|
|
|
_columns = { |
|
|
|
'name': fields.char('Name', size=50, required=True), |
|
|
|
'range_ids': fields.many2many('mgmtsystem.kpi.threshold.range','mgmtsystem_kpi_threshold_range_rel', 'threshold_id', 'range_id', 'Ranges'), |
|
|
|
'range_ids': fields.many2many('mgmtsystem.kpi.threshold.range', 'mgmtsystem_kpi_threshold_range_rel', 'threshold_id', 'range_id', 'Ranges'), |
|
|
|
'valid': fields.function(_is_valid_threshold, string='Valid', type='boolean', required=True), |
|
|
|
'invalid_message': fields.function(_generate_invalid_message, string='Message', type='char', size=100), |
|
|
|
'kpi_ids': fields.one2many('mgmtsystem.kpi', 'threshold_id', 'KPIs'), |
|
|
@ -231,14 +231,13 @@ class mgmtsystem_kpi_threshold(osv.osv): |
|
|
|
color = '#FFFFFF' |
|
|
|
for obj in self.browse(cr, uid, ids, context): |
|
|
|
for range_id in obj.range_ids: |
|
|
|
range_obj = self.pool.get('mgmtsystem.kpi.threshold.range').browse(cr, uid, range_id.id, context) |
|
|
|
if range_obj.min_value <= kpi_value <= range_obj.max_value and range_obj.valid: |
|
|
|
color = range_obj.color |
|
|
|
range_obj = self.pool.get('mgmtsystem.kpi.threshold.range').browse(cr, uid, range_id.id, context) |
|
|
|
if range_obj.min_value <= kpi_value <= range_obj.max_value and range_obj.valid: |
|
|
|
color = range_obj.color |
|
|
|
return color |
|
|
|
|
|
|
|
mgmtsystem_kpi_threshold() |
|
|
|
|
|
|
|
class mgmtsystem_kpi_history(osv.osv): |
|
|
|
class mgmtsystem_kpi_history(orm.Model): |
|
|
|
""" |
|
|
|
History of the KPI |
|
|
|
""" |
|
|
@ -261,11 +260,10 @@ class mgmtsystem_kpi_history(osv.osv): |
|
|
|
'color': '#FFFFFF', |
|
|
|
} |
|
|
|
|
|
|
|
_order = "date desc" |
|
|
|
_order = "date desc" |
|
|
|
|
|
|
|
mgmtsystem_kpi_threshold() |
|
|
|
|
|
|
|
class mgmtsystem_kpi(osv.osv): |
|
|
|
class mgmtsystem_kpi(orm.Model): |
|
|
|
""" |
|
|
|
Key Performance Indicators |
|
|
|
""" |
|
|
@ -275,7 +273,7 @@ class mgmtsystem_kpi(osv.osv): |
|
|
|
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: |
|
|
@ -288,8 +286,8 @@ class mgmtsystem_kpi(osv.osv): |
|
|
|
def compute_kpi_value(self, cr, uid, ids, context=None): |
|
|
|
if context is None: |
|
|
|
context = {} |
|
|
|
for obj in self.browse(cr, uid, ids): |
|
|
|
kpi_value = 0 |
|
|
|
for obj in self.browse(cr, uid, ids): |
|
|
|
kpi_value = 0 |
|
|
|
if obj.kpi_type == 'local' and is_select_query(obj.kpi_code): |
|
|
|
cr.execute(obj.kpi_code) |
|
|
|
dic = cr.dictfetchall() |
|
|
@ -305,10 +303,10 @@ class mgmtsystem_kpi(osv.osv): |
|
|
|
|
|
|
|
threshold_obj = self.pool.get('mgmtsystem.kpi.threshold').browse(cr, uid, obj.threshold_id.id, context) |
|
|
|
values = { |
|
|
|
'kpi_id': obj.id, |
|
|
|
'kpi_id': obj.id, |
|
|
|
'value': kpi_value, |
|
|
|
'color': threshold_obj.get_color(kpi_value), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
history_obj = self.pool.get('mgmtsystem.kpi.history') |
|
|
|
history_id = history_obj.create(cr, uid, values, context=context) |
|
|
@ -322,13 +320,13 @@ class mgmtsystem_kpi(osv.osv): |
|
|
|
|
|
|
|
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 ) |
|
|
|
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'), |
|
|
@ -354,20 +352,20 @@ class mgmtsystem_kpi(osv.osv): |
|
|
|
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), |
|
|
|
'description': fields.text('Description'), |
|
|
|
'category_id': fields.many2one('mgmtsystem.kpi.category','Category', required=True), |
|
|
|
'threshold_id': fields.many2one('mgmtsystem.kpi.threshold','Threshold', required=True), |
|
|
|
'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.selection((('hour','Hour'), ('day','Day'), ('week','Week'), ('month','Month')), '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_type': fields.selection((('python','Python'), ('local','SQL - Local DB'), ('external','SQL - External DB')),'KPI Computation Type'), |
|
|
|
'dbsource_id': fields.many2one('base.external.dbsource','External DB Source'), |
|
|
|
'kpi_type': fields.selection((('python', 'Python'), ('local', 'SQL - Local DB'), ('external', 'SQL - External DB')), 'KPI Computation Type'), |
|
|
|
'dbsource_id': fields.many2one('base.external.dbsource', 'External DB Source'), |
|
|
|
'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."), |
|
|
@ -381,6 +379,4 @@ class mgmtsystem_kpi(osv.osv): |
|
|
|
'periodicity_uom': 'day', |
|
|
|
} |
|
|
|
|
|
|
|
mgmtsystem_kpi() |
|
|
|
|
|
|
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |