diff --git a/kpi/__manifest__.py b/kpi/__manifest__.py index ad7cd1a94..e52019c92 100644 --- a/kpi/__manifest__.py +++ b/kpi/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Key Performance Indicator", - "version": "11.0.1.1.0", + "version": "11.0.1.0.0", "author": "Savoir-faire Linux,Odoo Community Association (OCA)", "website": "http://www.savoirfairelinux.com", "license": "AGPL-3", diff --git a/kpi/models/kpi.py b/kpi/models/kpi.py index adffe7d4c..7c2459625 100644 --- a/kpi/models/kpi.py +++ b/kpi/models/kpi.py @@ -1,7 +1,8 @@ # Copyright 2012 - Now Savoir-faire Linux # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from datetime import datetime, timedelta +from datetime import datetime +from dateutil.relativedelta import relativedelta from odoo import fields, models, api from odoo.tools.safe_eval import safe_eval from odoo.tools import ( @@ -122,48 +123,56 @@ class KPI(models.Model): obj.last_execution = False @api.multi - def compute_kpi_value(self): - for obj in self: - kpi_value = 0 - if obj.kpi_code: - if obj.kpi_type == 'local' and is_sql_or_ddl_statement( - obj.kpi_code): - self.env.cr.execute(obj.kpi_code) - dic = self.env.cr.dictfetchall() - if is_one_value(dic): - kpi_value = dic[0]['value'] - elif (obj.kpi_type == 'external' and obj.dbsource_id.id and - is_sql_or_ddl_statement(obj.kpi_code)): - dbsrc_obj = obj.dbsource_id - res = dbsrc_obj.execute(obj.kpi_code) - if is_one_value(res): - kpi_value = res[0]['value'] - elif obj.kpi_type == 'python': - kpi_value = safe_eval(obj.kpi_code, {'self': obj}) - - threshold_obj = obj.threshold_id - values = { - 'kpi_id': obj.id, + def _get_kpi_value(self): + self.ensure_one() + kpi_value = 0 + if self.kpi_code: + if self.kpi_type == 'local' and is_sql_or_ddl_statement( + self.kpi_code): + self.env.cr.execute(self.kpi_code) + dic = self.env.cr.dictfetchall() + if is_one_value(dic): + kpi_value = dic[0]['value'] + elif (self.kpi_type == 'external' and self.dbsource_id.id and + is_sql_or_ddl_statement(self.kpi_code)): + dbsrc_obj = self.dbsource_id + res = dbsrc_obj.execute(self.kpi_code) + if is_one_value(res): + kpi_value = res[0]['value'] + elif self.kpi_type == 'python': + kpi_value = safe_eval(self.kpi_code, {'self': self}) + if isinstance(kpi_value, dict): + res = kpi_value + else: + threshold_obj = self.threshold_id + res = { 'value': kpi_value, 'color': threshold_obj.get_color(kpi_value), } + res.update({'kpi_id': self.id}) + return res + + @api.multi + def compute_kpi_value(self): + for obj in self: + history_vals = obj._get_kpi_value() history_obj = self.env['kpi.history'] - history_obj.create(values) + history_obj.create(history_vals) return True @api.multi def update_next_execution_date(self): for obj in self: if obj.periodicity_uom == 'hour': - delta = timedelta(hours=obj.periodicity) + delta = relativedelta(hours=obj.periodicity) elif obj.periodicity_uom == 'day': - delta = timedelta(days=obj.periodicity) + delta = relativedelta(days=obj.periodicity) elif obj.periodicity_uom == 'week': - delta = timedelta(weeks=obj.periodicity) + delta = relativedelta(weeks=obj.periodicity) elif obj.periodicity_uom == 'month': - delta = timedelta(months=obj.periodicity) + delta = relativedelta(months=obj.periodicity) else: - delta = timedelta() + delta = relativedelta() new_date = datetime.now() + delta obj.next_execution_date = new_date.strftime(DATETIME_FORMAT) diff --git a/kpi/readme/CONTRIBUTORS.rst b/kpi/readme/CONTRIBUTORS.rst index 6aed435ce..1cdac40a3 100644 --- a/kpi/readme/CONTRIBUTORS.rst +++ b/kpi/readme/CONTRIBUTORS.rst @@ -3,4 +3,5 @@ * Loic Lacroix * Sandy Carter * Gervais Naoussi -* Iván Todorovich \ No newline at end of file +* Iván Todorovich +* Adrià Gil diff --git a/kpi/tests/test_kpi.py b/kpi/tests/test_kpi.py index c01ca423e..9bfcb2455 100644 --- a/kpi/tests/test_kpi.py +++ b/kpi/tests/test_kpi.py @@ -84,3 +84,33 @@ class TestKPI(TransactionCase): 'max_fixed_value': 1, }) self.assertFalse(range_error.valid) + + def test_kpi_python(self): + kpi_category = self.env['kpi.category'].create({ + 'name': 'Dynamic KPIs' + }) + kpi_threshold = self.env['kpi.threshold'].create({ + 'name': 'KPI Threshold for dynamic KPIs' + }) + kpi_code = """ + { + 'value': 1.0, + 'color': '#00FF00' + } + """ + kpi = self.env['kpi'].create({ + 'name': 'Dynamic python kpi', + 'description': 'Dynamic python kpi', + 'category_id': kpi_category.id, + 'threshold_id': kpi_threshold.id, + 'periodicity': 1, + 'periodicity_uom': 'day', + 'kpi_type': 'python', + 'kpi_code': kpi_code, + }) + kpi.update_kpi_value() + kpi_history = self.env['kpi.history'].search( + [('kpi_id', '=', kpi.id)]) + self.assertEqual(len(kpi_history), 1) + self.assertEqual(kpi_history.color, '#00FF00') + self.assertEqual(kpi_history.value, 1.0)