Browse Source

[12.0][IMP] kpi_dashboard: Allow to use formula

myc-14.0-py3o
Enric Tobella 5 years ago
parent
commit
3ca213d3e0
  1. 15
      kpi_dashboard/models/kpi_kpi.py
  2. 3
      kpi_dashboard/readme/CONFIGURE.rst
  3. 1
      kpi_dashboard/tests/__init__.py
  4. 31
      kpi_dashboard/tests/test_formula.py
  5. 5
      kpi_dashboard/views/kpi_kpi.xml

15
kpi_dashboard/models/kpi_kpi.py

@ -3,6 +3,7 @@
from odoo import api, fields, models from odoo import api, fields, models
import ast import ast
from odoo.tools.safe_eval import safe_eval
class KpiKpi(models.Model): class KpiKpi(models.Model):
@ -13,7 +14,7 @@ class KpiKpi(models.Model):
active = fields.Boolean(default=True) active = fields.Boolean(default=True)
cron_id = fields.Many2one("ir.cron", readonly=True, copy=False) cron_id = fields.Many2one("ir.cron", readonly=True, copy=False)
computation_method = fields.Selection( computation_method = fields.Selection(
[("function", "Function")], required=True
[("function", "Function"), ("code", "Code")], required=True
) )
value = fields.Serialized() value = fields.Serialized()
dashboard_item_ids = fields.One2many("kpi.dashboard.item", inverse_name="kpi_id") dashboard_item_ids = fields.One2many("kpi.dashboard.item", inverse_name="kpi_id")
@ -34,6 +35,7 @@ class KpiKpi(models.Model):
inverse_name='kpi_id', inverse_name='kpi_id',
help="Actions that can be opened from the KPI" help="Actions that can be opened from the KPI"
) )
code = fields.Text("Code")
def _cron_vals(self): def _cron_vals(self):
return { return {
@ -84,6 +86,17 @@ class KpiKpi(models.Model):
vals["value_last_update"] = fields.Datetime.now() vals["value_last_update"] = fields.Datetime.now()
return super().write(vals) return super().write(vals)
def _get_code_input_dict(self):
return {
"self": self,
"model": self,
}
def _compute_value_code(self):
results = self._get_code_input_dict()
safe_eval(self.code or "", results, mode="exec", nocopy=True)
return results.get("result", {})
class KpiKpiAction(models.Model): class KpiKpiAction(models.Model):
_name = 'kpi.kpi.action' _name = 'kpi.kpi.action'

3
kpi_dashboard/readme/CONFIGURE.rst

@ -8,6 +8,9 @@ Configure KPIs
#. Meter: result must contain `value`, `min` and `max` #. Meter: result must contain `value`, `min` and `max`
#. Graph: result must contain a list on `graphs` containing `values`, `title` and `key` #. Graph: result must contain a list on `graphs` containing `values`, `title` and `key`
#. In order to compute the KPI you can use a predefined function from a model or
use the code to directly compute it.
Configure dashboards Configure dashboards
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~

1
kpi_dashboard/tests/__init__.py

@ -0,0 +1 @@
from . import test_formula

31
kpi_dashboard/tests/test_formula.py

@ -0,0 +1,31 @@
# Copyright 2020 Creu Blanca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.tests.common import TransactionCase
class TestFormula(TransactionCase):
def test_computation(self):
kpi = self.env["kpi.kpi"].create(
{
"name": "DEMO KPI",
"widget": "number",
"computation_method": "code",
}
)
self.assertFalse(kpi.value)
kpi.compute()
self.assertEqual(kpi.value, {})
kpi.code = """
result = {}
result['value'] = len(model.search([('id', '=', %s)]))
result['previous'] = len(model.search([('id', '!=', %s)]))
""" % (
kpi.id,
kpi.id,
)
kpi.compute()
value = kpi.value
self.assertTrue(value.get("value"))
self.assertEqual(value.get("value"), 1)
self.assertEqual(value.get("previous"), kpi.search_count([]) - 1)

5
kpi_dashboard/views/kpi_kpi.xml

@ -45,6 +45,11 @@
</tree> </tree>
</field> </field>
</page> </page>
<page name="code" string="Code" attrs="{'invisible': [('computation_method', '!=', 'code')]}">
<field name="code" widget="ace"
options="{'mode': 'python'}"
placeholder="Enter Python code here."/>
</page>
</notebook> </notebook>
</sheet> </sheet>
</form> </form>

Loading…
Cancel
Save