[12.0][IMP] kpi_dashboard: Allow to use formula
parent
5b3aeed911
commit
3ca213d3e0
|
@ -3,6 +3,7 @@
|
|||
|
||||
from odoo import api, fields, models
|
||||
import ast
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
|
||||
class KpiKpi(models.Model):
|
||||
|
@ -13,7 +14,7 @@ class KpiKpi(models.Model):
|
|||
active = fields.Boolean(default=True)
|
||||
cron_id = fields.Many2one("ir.cron", readonly=True, copy=False)
|
||||
computation_method = fields.Selection(
|
||||
[("function", "Function")], required=True
|
||||
[("function", "Function"), ("code", "Code")], required=True
|
||||
)
|
||||
value = fields.Serialized()
|
||||
dashboard_item_ids = fields.One2many("kpi.dashboard.item", inverse_name="kpi_id")
|
||||
|
@ -34,6 +35,7 @@ class KpiKpi(models.Model):
|
|||
inverse_name='kpi_id',
|
||||
help="Actions that can be opened from the KPI"
|
||||
)
|
||||
code = fields.Text("Code")
|
||||
|
||||
def _cron_vals(self):
|
||||
return {
|
||||
|
@ -84,6 +86,17 @@ class KpiKpi(models.Model):
|
|||
vals["value_last_update"] = fields.Datetime.now()
|
||||
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):
|
||||
_name = 'kpi.kpi.action'
|
||||
|
|
|
@ -8,6 +8,9 @@ Configure KPIs
|
|||
#. Meter: result must contain `value`, `min` and `max`
|
||||
#. 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
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
from . import test_formula
|
|
@ -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)
|
|
@ -44,7 +44,12 @@
|
|||
<field name="action"/>
|
||||
</tree>
|
||||
</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>
|
||||
</sheet>
|
||||
</form>
|
||||
|
|
Loading…
Reference in New Issue