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)