Skip to content

Commit

Permalink
automation: Add graphs
Browse files Browse the repository at this point in the history
  • Loading branch information
etobella committed Mar 10, 2024
1 parent ea50d16 commit 9fc70c9
Show file tree
Hide file tree
Showing 7 changed files with 229 additions and 3 deletions.
1 change: 1 addition & 0 deletions automation_oca/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"assets": {
"web.assets_backend": [
"automation_oca/static/src/**/*.js",
"automation_oca/static/src/**/*.xml",
"automation_oca/static/src/**/*.scss",
],
},
Expand Down
81 changes: 81 additions & 0 deletions automation_oca/models/automation_configuration_activity.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# Copyright 2024 Dixmit
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from collections import defaultdict

import babel.dates
from dateutil.relativedelta import relativedelta

from odoo import api, fields, models
from odoo.osv import expression
from odoo.tools import get_lang
from odoo.tools.safe_eval import safe_eval


Expand Down Expand Up @@ -77,6 +81,83 @@ class AutomationConfigurationActivity(models.Model):
parent_position = fields.Integer(
compute="_compute_parent_position", recursive=True, store=True
)
graph_data = fields.Json(compute="_compute_graph_data")
graph_done = fields.Integer(compute="_compute_total_graph_data")
graph_error = fields.Integer(compute="_compute_total_graph_data")

@api.depends()
def _compute_graph_data(self):
total = self.env["automation.record.activity"].read_group(

Check warning on line 90 in automation_oca/models/automation_configuration_activity.py

View check run for this annotation

Codecov / codecov/patch

automation_oca/models/automation_configuration_activity.py#L90

Added line #L90 was not covered by tests
[
("configuration_activity_id", "in", self.ids),
("processed_on", ">=", fields.Date.today() + relativedelta(days=-14)),
],
["configuration_activity_id"],
["configuration_activity_id", "processed_on:day"],
lazy=False,
)
done = self.env["automation.record.activity"].read_group(

Check warning on line 99 in automation_oca/models/automation_configuration_activity.py

View check run for this annotation

Codecov / codecov/patch

automation_oca/models/automation_configuration_activity.py#L99

Added line #L99 was not covered by tests
[
("configuration_activity_id", "in", self.ids),
("processed_on", ">=", fields.Date.today() + relativedelta(days=-14)),
("state", "=", "done"),
],
["configuration_activity_id"],
["configuration_activity_id", "processed_on:day"],
lazy=False,
)
now = fields.Datetime.now()

Check warning on line 109 in automation_oca/models/automation_configuration_activity.py

View check run for this annotation

Codecov / codecov/patch

automation_oca/models/automation_configuration_activity.py#L109

Added line #L109 was not covered by tests
date_map = {
babel.dates.format_datetime(
now + relativedelta(days=i - 14),
format="dd MMM yyy",
tzinfo=self._context.get("tz", None),
locale=get_lang(self.env).code,
): 0
for i in range(0, 15)
}
result = defaultdict(
lambda: {"done": date_map.copy(), "error": date_map.copy()}
)
for line in total:
result[line["configuration_activity_id"][0]]["error"][

Check warning on line 123 in automation_oca/models/automation_configuration_activity.py

View check run for this annotation

Codecov / codecov/patch

automation_oca/models/automation_configuration_activity.py#L123

Added line #L123 was not covered by tests
line["processed_on:day"]
] += line["__count"]
for line in done:
result[line["configuration_activity_id"][0]]["done"][

Check warning on line 127 in automation_oca/models/automation_configuration_activity.py

View check run for this annotation

Codecov / codecov/patch

automation_oca/models/automation_configuration_activity.py#L127

Added line #L127 was not covered by tests
line["processed_on:day"]
] += line["__count"]
result[line["configuration_activity_id"][0]]["error"][

Check warning on line 130 in automation_oca/models/automation_configuration_activity.py

View check run for this annotation

Codecov / codecov/patch

automation_oca/models/automation_configuration_activity.py#L130

Added line #L130 was not covered by tests
line["processed_on:day"]
] -= line["__count"]
for record in self:
graph_info = dict(result[record.id])

Check warning on line 134 in automation_oca/models/automation_configuration_activity.py

View check run for this annotation

Codecov / codecov/patch

automation_oca/models/automation_configuration_activity.py#L134

Added line #L134 was not covered by tests
record.graph_data = {
"error": [
{"x": key[:-5], "y": value, "name": key}
for (key, value) in graph_info["error"].items()
],
"done": [
{"x": key[:-5], "y": value, "name": key}
for (key, value) in graph_info["done"].items()
],
}

@api.depends()
def _compute_total_graph_data(self):
for record in self:
record.graph_done = self.env["automation.record.activity"].search_count(

Check warning on line 149 in automation_oca/models/automation_configuration_activity.py

View check run for this annotation

Codecov / codecov/patch

automation_oca/models/automation_configuration_activity.py#L149

Added line #L149 was not covered by tests
[
("configuration_activity_id", "in", self.ids),
("state", "=", "done"),
]
)
record.graph_error = self.env["automation.record.activity"].search_count(

Check warning on line 155 in automation_oca/models/automation_configuration_activity.py

View check run for this annotation

Codecov / codecov/patch

automation_oca/models/automation_configuration_activity.py#L155

Added line #L155 was not covered by tests
[
("configuration_activity_id", "in", self.ids),
("state", "in", ["expired", "rejected", "error", "cancel"]),
]
)

@api.depends("trigger_interval", "trigger_interval_type")
def _compute_trigger_interval_hours(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @odoo-module **/
import {useOpenX2ManyRecord, useX2ManyCrud} from "@web/views/fields/relational_utils";

import {AutomationKanbanRenderer} from "../views/automation_kanban/automation_kanban_renderer.esm";
import {AutomationKanbanRenderer} from "../../views/automation_kanban/automation_kanban_renderer.esm";
import {X2ManyField} from "@web/views/fields/x2many/x2many_field";
import {registry} from "@web/core/registry";

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/** @odoo-module **/
/* global Chart*/

import {loadJS} from "@web/core/assets";
import {registry} from "@web/core/registry";
import {standardFieldProps} from "@web/views/fields/standard_field_props";

const {Component, onWillStart, useEffect, useRef} = owl;

export class AutomationGraph extends Component {
setup() {
this.chart = null;
this.canvasRef = useRef("canvas");
onWillStart(() => loadJS("/web/static/lib/Chart/Chart.js"));
useEffect(() => {
this.renderChart();
return () => {
if (this.chart) {
this.chart.destroy();
}
};
});
}
_getChartConfig() {
return {
type: "line",
data: {
labels: this.props.value.done.map(function (pt) {
return pt.x;
}),
datasets: [
{
backgroundColor: "#4CAF5080",
borderColor: "#4CAF50",
data: this.props.value.done,
fill: "start",
label: this.env._t("Done"),
borderWidth: 2,
},
{
backgroundColor: "#F4433680",
borderColor: "#F44336",
data: this.props.value.error,
fill: "start",
label: this.env._t("Error"),
borderWidth: 2,
},
],
},
options: {
legend: {display: false},

layout: {
padding: {left: 10, right: 10, top: 10, bottom: 10},
},
scales: {
yAxes: [
{
type: "linear",
display: false,
ticks: {
beginAtZero: true,
},
},
],
xAxes: [
{
ticks: {
maxRotation: 0,
},
},
],
},
maintainAspectRatio: false,
elements: {
line: {
tension: 0.000001,
},
},
tooltips: {
intersect: false,
position: "nearest",
caretSize: 0,
borderWidth: 2,
},
},
};
}
renderChart() {
if (this.chart) {
this.chart.destroy();
}
var config = this._getChartConfig();
this.chart = new Chart(this.canvasRef.el, config);
Chart.animationService.advance();
}
}

AutomationGraph.template = "automation_oca.AutomationGraph";
AutomationGraph.props = {
...standardFieldProps,
};

registry.category("fields").add("automation_graph", AutomationGraph);
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates id="template" xml:space="preserve">

<t t-name="automation_oca.AutomationGraph" owl="1">
<div class="o_automation_graph w-100" t-att-class="props.className">
<canvas t-ref="canvas" />
</div>
</t>

</templates>
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@
right: 0px;
}
}
.o_automation_kanban_graph {
.o_automation_kpi_processed {
color: #4caf50;
}
.o_automation_kpi_error {
color: #f44336;
}
}
.o_automation_kanban_child_add {
.o_automation_kanban_child_add_title {
padding: 2px;
Expand Down Expand Up @@ -107,3 +115,6 @@
}
}
}
.o_field_automation_graph {
width: 100%;
}
23 changes: 21 additions & 2 deletions automation_oca/views/automation_configuration.xml
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,27 @@
</div>
</div>
</div>
<div class="o_automation_kanban_graph">
<span>TO BE FILLED</span>
<div class="o_automation_kanban_graph row">
<div class="col-8">
<field
name="graph_data"
widget="automation_graph"
/>
</div>
<div class="col-4 text-center pt-2">
<h2 class="o_automation_kpi_processed">
<field name="graph_done" />
</h2>
<div
class="o_automation_kpi_processed pb-3"
> Processed</div>
<h2 class="o_automation_kpi_error">
<field name="graph_error" />
</h2>
<div
class="o_automation_kpi_error"
> Error</div>
</div>
</div>

<div
Expand Down

0 comments on commit 9fc70c9

Please sign in to comment.