Sélectionner une révision Git
Bifurcation depuis
Le Filament / Opération Auto-Consommation Collective / oacc_portal_overview_cdc
84 validations de retard le dépôt en amont.

Rémi - Le Filament authored
canvas.js 30,40 Kio
odoo.define("oacc_portal_overview_cdc.canvas", function (require) {
"use strict";
var publicWidget = require("web.public.widget");
publicWidget.registry.oaccPortalOverviewCdc = publicWidget.Widget.extend({
jsLibs: [
"/web/static/lib/Chart/Chart.js",
"/oacc_portal_overview_cdc/static/src/js/lib/chartjs-plugin-datalabels.min.js",
],
selector: ".oe_website_canvas",
events: {
"click .btn-period": "_onBtnPeriodClick",
"click #previous-period": "_onPreviousPeriod",
"click #next-period": "_onNextPeriod",
"change select[name='endpoint']": "_onChangePrm",
},
/**
* @class
*/
init: function () {
this._super.apply(this, arguments);
this.operation = $(".oe_website_canvas").data("id");
this.scale = null;
this.minDate = null;
this.maxDate = null;
this.partner_id = null;
this.title_name = null;
this.prm_id = null;
this.data_type = null;
// Init chart
this.chart_line_conso = null;
this.chart_pie_conso = null;
this.chart_histo_conso = null;
this.chart_line_prod = null;
this.chart_pie_prod = null;
this.chart_histo_prod = null;
this.date_range_picker = null;
this.chartData = null;
},
/**
* @override
*/
willStart: function () {
var self = this;
var def = this._rpc({
model: "acc.operation",
method: "get_date_min_max",
args: [self.operation],
}).then(function (data) {
self.minDate = data.date_min;
self.maxDate = data.date_max;
});
return Promise.all([this._super.apply(this, arguments), def]);
},
/**
* @override
*/
start: function () {
var self = this;
$('select[name="endpoint"]').select2({
placeholder: "Sélectionner",
});
$('button[id="next-period"]').prop("disabled", true);
return this._super().then(function () {
// Récupération des dates de début et fin
var $btnWeekVal = $('button[name="month"]').val();
var objquote = $btnWeekVal.replaceAll("'", '"');
const obj = JSON.parse(objquote);
self.first_day = obj.first_day;
self.last_day = obj.last_day;
self.data_type = self.$el.data("name");
if (self.data_type == "cons") {
self.title_name = "Consommation globale";
}
if (self.data_type == "prod") {
self.title_name = "Production globale";
}
self.render_daterangepicker();
self.render_data();
});
},
render_data: function () {
var self = this;
self.render_graph();
},
render_graph: function () {
var self = this;
var ctx_line_conso = self.$(".line_chart_conso");
var ctx_line_prod = self.$(".line_chart_prod");
var ctx_pie_conso = self.$(".pie_chart_conso");
var ctx_pie_prod = self.$(".pie_chart_prod");
var ctx_histo_conso = self.$(".histo_chart_conso");
var ctx_histo_prod = self.$(".histo_chart_prod");
this._rpc({
model: "acc.operation",
method: "graph_view_global",
args: [
self.operation,
self.first_day,
self.last_day,
self.partner_id,
self.prm_id,
self.data_type,
],
}).then(function (data) {
self.scale = data.scale;
self.chartData = data.chart_data;
if (ctx_line_conso.length > 0) {
self.chart_line_conso = new Chart(
ctx_line_conso,
self._getLineChartConfig("cons")
);
}
if (ctx_pie_conso.length > 0) {
self.chart_pie_conso = new Chart(
ctx_pie_conso,
self._getPieChartConfig("cons")
);
}
if (ctx_histo_conso.length > 0) {
self.chart_histo_conso = new Chart(
ctx_histo_conso,
self._getBarChartConfig("cons")
);
}
if (ctx_line_prod.length > 0) {
self.chart_line_prod = new Chart(
ctx_line_prod,
self._getLineChartConfig("prod")
);
}
if (ctx_pie_prod.length > 0) {
self.chart_pie_prod = new Chart(
ctx_pie_prod,
self._getPieChartConfig("prod")
);
}
if (ctx_histo_prod.length > 0) {
self.chart_histo_prod = new Chart(
ctx_histo_prod,
self._getBarChartConfig("prod")
);
}
});
},
render_daterangepicker: function () {
var self = this;
this.date_range_picker = this.$(
'input[name="daterange"]'
).daterangepicker(
{
showDropdowns: true,
startDate: self.first_day,
endDate: self.last_day,
minDate: self.minDate,
maxDate: self.maxDate,
autoApply: true,
alwaysShowCalendars: true,
autoUpdateInput: true,
linkedCalendars: true,
},
function (start, end, label) {
self.first_day = start.format("DD/MM/YYYY");
self.last_day = end.format("DD/MM/YYYY");
self._rpc({
route: "/chart/update_json",
params: {
operation_id: self.operation,
date_start: self.first_day,
date_end: self.last_day,
partner_id: self.partner_id,
prm_id: self.prm_id,
data_type: self.data_type,
},
}).then(function (data) {
self._updateDataTemplate(data);
});
}
);
},
/**
* Returns a bar chart configuration.
*
* @private
*/
_getBarChartData: function (typeData) {
var data, data_autocons, data_allocons, data_label, data_surplus;
if (typeData === "cons") {
if (this.scale === "day") {
data_autocons = this.chartData.autocons_histo;
data_allocons = this.chartData.allocons_histo;
data_label = this.chartData.label_histo;
} else {
data_autocons = this.chartData.autocons;
data_allocons = this.chartData.allocons;
data_label = this.chartData.label;
}
data = {
labels: data_label,
datasets: [
{
label: "AutoConso",
data: data_autocons,
backgroundColor: "rgba(91, 154, 81, 0.4)",
hoverBackgroundColor: "rgba(91, 154, 81, 0.7)",
},
{
label: "AlloConso",
data: data_allocons,
backgroundColor: "rgba(57, 120, 187, 0.4)",
hoverBackgroundColor: "rgba(57, 120, 187, 0.7)",
},
],
};
} else {
if (this.scale === "day") {
data_autocons = this.chartData.autocons_prod_histo;
data_surplus = this.chartData.surplus_histo;
data_label = this.chartData.label_histo;
} else {
data_autocons = this.chartData.autocons_prod;
data_surplus = this.chartData.surplus;
data_label = this.chartData.label;
}
data = {
labels: data_label,
datasets: [
{
label: "AutoConso",
data: data_autocons,
backgroundColor: "rgba(91, 154, 81, 0.4)",
hoverBackgroundColor: "rgba(91, 154, 81, 0.7)",
borderColor: "rgba(91, 154, 81, 1)",
},
{
label: "Surplus",
data: data_surplus,
backgroundColor: "rgba(225, 80, 96, 0.4)",
hoverBackgroundColor: "rgba(225, 80, 96, 0.7)",
borderColor: "rgba(225, 80, 96, 1)",
},
],
};
}
return data;
},
_getBarChartConfig: function (typeData) {
var data = this._getBarChartData(typeData);
return {
type: "bar",
data: data,
options: {
legend: {
onHover: (event, chartElement) => {},
},
interaction: {
intersect: false,
},
scales: {
xAxes: [
{
type: "time",
time: {
unit: this.scale,
displayFormats: {
hour: "HH:mm",
day: "DD MMM",
quarter: "D MMM",
},
},
stacked: true,
offset: true,
gridLines: {
offsetGridLines: true,
},
},
],
yAxes: [
{
stacked: true,
ticks: {
beginAtZero: true,
},
scaleLabel: {
display: true,
labelString: "kWh",
},
},
],
},
tooltips: {
mode: "x",
callbacks: {
title: function (tooltipItems) {
return moment(tooltipItems[0].xLabel)
.locale("fr-FR")
.format("DD/MM/YYYY HH:ss");
},
label: function (context, data) {
return (
data.datasets[context.datasetIndex].label +
" : " +
context.yLabel.toLocaleString("fr", {
maximumFractionDigits: 1,
}) +
" kWh"
);
},
},
},
},
};
},
/**
* Returns a Pie chart configuration.
*
* @private
*/
_getPieChartData: function (typeData) {
var data, res;
var sum_res1 = 0;
var sum_res2 = 0;
if (typeData === "cons") {
this.chartData.autocons.forEach((item) => {
if ("y" in item) {
sum_res1 += item.y;
} else {
sum_res1 += item;
}
});
this.chartData.allocons.forEach((item) => {
if ("y" in item) {
sum_res2 += item.y;
} else {
sum_res2 += item;
}
});
res = [Math.floor(sum_res1), Math.floor(sum_res2)];
data = {
labels: ["AutoConso", "AlloConso"],
datasets: [
{
label: "Inférieur à 3",
data: res,
backgroundColor: [
"rgba(91, 154, 81, 0.4)",
"rgba(57, 120, 187, 0.4)",
],
hoverBackgroundColor: [
"rgba(91, 154, 81, 0.7)",
"rgba(57, 120, 187, 0.7)",
],
borderWidth: 1,
},
],
};
} else {
this.chartData.autocons_prod.forEach((item) => {
if ("y" in item) {
sum_res1 += item.y;
} else {
sum_res1 += item;
}
});
this.chartData.surplus.forEach((item) => {
if ("y" in item) {
sum_res2 += item.y;
} else {
sum_res2 += item;
}
});
res = [Math.floor(sum_res1), Math.floor(sum_res2)];
data = {
labels: ["AutoConso", "Surplus"],
datasets: [
{
label: "Inférieur à 3",
data: res,
backgroundColor: [
"rgba(91, 154, 81, 0.4)",
"rgba(225, 80, 96, 0.4)",
],
hoverBackgroundColor: [
"rgba(91, 154, 81, 0.7)",
"rgba(225, 80, 96, 0.7)",
],
borderWidth: 1,
},
],
};
}
return data;
},
_getPieChartConfig: function (typeData) {
var data = this._getPieChartData(typeData);
return {
type: "pie",
data: data,
plugins: [ChartDataLabels],
options: {
animation: {
animateScale: true,
},
plugins: {
datalabels: {
textAlign: "center",
font: {
size: 18,
weight: "bold",
},
formatter: (value, data) => {
var total = 0;
data.dataset.data.forEach((num) => {
total += num;
});
var labelPercentage = Math.round(
(value / total) * 100
);
return (
value + " kWh\n" + labelPercentage + " %"
);
},
},
},
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
var allData =
data.datasets[tooltipItem.datasetIndex]
.data;
var tooltipLabel =
data.labels[tooltipItem.index];
var tooltipData = allData[tooltipItem.index];
var total = 0;
for (var i in allData) {
total += allData[i];
}
var tooltipPercentage = Math.round(
(tooltipData / total) * 100
);
return (
tooltipLabel +
": " +
tooltipData +
" kWh (" +
tooltipPercentage +
"%)"
);
},
},
},
},
};
},
/**
* Returns a line chart configuration.
*
* @private
*/
_getLineChartData: function (typeData) {
var data;
if (typeData === "cons") {
data = {
labels: this.chartData.label,
datasets: [
{
label: "Conso",
data: this.chartData.cons,
backgroundColor: "rgba(57, 120, 187, 0.2)",
borderColor: "rgba(57, 120, 187, 1)",
borderWidth: 1,
hoverRadius: 1,
radius: 0,
},
{
label: "Production solaire",
data: this.chartData.prod,
backgroundColor: "rgba(244, 165, 25, 0)",
borderColor: "rgba(244, 165, 25, 1)",
borderWidth: 2,
hoverRadius: 1,
radius: 0,
hidden: true,
},
{
label: "AutoConso",
data: this.chartData.autocons,
backgroundColor: "rgba(91, 154, 81, 0.4)",
borderColor: "rgba(91, 154, 81, 1)",
borderWidth: 2,
hoverRadius: 1,
radius: 0,
},
],
};
} else {
data = {
labels: this.chartData.label,
datasets: [
{
label: "AutoConso",
data: this.chartData.autocons_prod,
backgroundColor: "rgba(91, 154, 81, 0.4)",
borderColor: "rgba(91, 154, 81, 1)",
borderWidth: 2,
hoverRadius: 1,
radius: 0,
fill: "origin",
},
{
label: "Surplus",
data: this.chartData.surplus,
backgroundColor: "rgba(225, 80, 96, 0.4)",
borderColor: "rgba(225, 80, 96, 1)",
borderWidth: 2,
hoverRadius: 1,
radius: 0,
fill: "-1",
},
],
};
}
return data;
},
_getLineChartConfig: function (typeData) {
var data = this._getLineChartData(typeData);
var stacked;
if (typeData === "cons") {
stacked = false;
} else {
stacked = true;
}
return {
type: "line",
data: data,
options: {
scales: {
xAxes: [
{
type: "time",
time: {
unit: this.scale,
displayFormats: {
hour: "HH:mm",
day: "DD MMM",
quarter: "D MMM",
},
},
gridLines: {
offsetGridLines: true,
},
},
],
yAxes: [
{
stacked: stacked,
scaleLabel: {
display: true,
labelString: "kW",
},
},
],
},
tooltips: {
backgroundColor: "#f5f5f5",
titleFontColor: "#333",
bodyFontColor: "#666",
bodySpacing: 4,
xPadding: 12,
mode: "x",
intersect: false,
callbacks: {
title: function (tooltipItems) {
return moment(tooltipItems[0].xLabel)
.locale("fr-FR")
.format("DD/MM/YYYY HH:ss");
},
label: function (context, data) {
return (
data.datasets[context.datasetIndex].label +
" : " +
context.yLabel.toLocaleString("fr", {
maximumFractionDigits: 1,
}) +
" kW"
);
},
},
},
elements: {
point: {
radius: 0,
},
},
},
};
},
// --------------------------------------------------------------------------
// Private
// --------------------------------------------------------------------------
_updateChartData: function (title_name) {
var self = this;
this._rpc({
route: "/chart/update_json",
params: {
operation_id: self.operation,
date_start: self.first_day,
date_end: self.last_day,
partner_id: self.partner_id,
prm_id: self.prm_id,
data_type: self.data_type,
},
}).then(function (data) {
if (title_name) {
var title_cdc = $(".title_cdc");
var title_upd =
'<h3 class="title_cdc text-center mt-2">' +
title_name +
"</h3>";
title_cdc.replaceWith(title_upd);
}
self._updateDataTemplate(data);
});
},
_updateDataTemplate: function (data) {
self = this;
self.chartData = data.chart_data;
self.scale = data.scale;
if (data.is_curve_line) {
$(".js_curv_line").removeClass("d-none");
} else {
$(".js_curv_line").addClass("d-none");
}
// Disable buttons if first or last date
if (moment(this.last_day, "dd/mm/yyyy") >= moment(this.maxDate, "dd/mm/yyyy")) {
$('button[id="next-period"]').prop("disabled", true);
} else {
$('button[id="next-period"]').prop("disabled", false);
}
if (moment(this.first_day, "dd/mm/yyyy") <= moment(this.minDate, "dd/mm/yyyy")) {
$('button[id="previous-period"]').prop("disabled", true);
} else {
$('button[id="previous-period"]').prop("disabled", false);
}
if (self.chart_line_conso !== null) {
self.chart_line_conso.data = self._getLineChartData("cons");
self.chart_line_conso.options.scales.xAxes[0].time.unit =
self.scale;
self.chart_line_conso.update();
}
if (self.chart_pie_conso !== null) {
self.chart_pie_conso.data = self._getPieChartData("cons");
self.chart_pie_conso.update();
}
if (self.chart_histo_conso !== null) {
self.chart_histo_conso.data = self._getBarChartData("cons");
self.chart_histo_conso.options.scales.xAxes[0].time.unit =
self.scale;
self.chart_histo_conso.update();
}
if (self.chart_line_prod !== null) {
self.chart_line_prod.data = self._getLineChartData("prod");
self.chart_line_prod.options.scales.xAxes[0].time.unit =
self.scale;
self.chart_line_prod.update();
}
if (self.chart_pie_prod !== null) {
self.chart_pie_prod.data = self._getPieChartData("prod");
self.chart_pie_prod.update();
}
if (self.chart_histo_prod !== null) {
self.chart_histo_prod.data = self._getBarChartData("prod");
self.chart_histo_prod.options.scales.xAxes[0].time.unit =
self.scale;
self.chart_histo_prod.update();
}
},
_onBtnPeriodClick: function (ev) {
var $iframe = $(ev.currentTarget).val();
var objquote = $iframe.replaceAll("'", '"');
const obj = JSON.parse(objquote);
this.first_day = obj.first_day;
this.last_day = obj.last_day;
this.date_range_picker
.data("daterangepicker")
.setStartDate(this.first_day);
this.date_range_picker
.data("daterangepicker")
.setEndDate(this.last_day);
this._updateChartData(this.title_name);
},
_onChangePrm: function (ev) {
var selected = $(ev.currentTarget).find("option:selected");
this.title_name = selected.data("name");
this.partner_id = parseInt(selected.data("partner-id"));
this.prm_id = parseInt(selected.data("prm-id"));
this._updateChartData(this.title_name);
},
_onPreviousPeriod: function (ev) {
this._onChangePeriod("previous");
},
_onNextPeriod: function (ev) {
this._onChangePeriod("next");
},
_onChangePeriod: function (type) {
const first_day = moment(this.first_day, "DD/MM/YYYY");
const last_day = moment(this.last_day, "DD/MM/YYYY");
const delta_days = last_day - first_day;
let delta_month = 0;
if (
first_day.isSame(first_day.clone().startOf("month"), "day") &&
last_day.isSame(last_day.clone().endOf("month"), "day")
) {
delta_month = last_day.month() - first_day.month() + 1;
}
if (type == "previous") {
// Compare for first day
let next_first = first_day
.clone()
.subtract(delta_days)
.subtract(1, "d");
const moment_min = moment(this.minDate, "DD/MM/YYYY");
this.last_day = moment(this.first_day, "DD/MM/YYYY")
.subtract(1, "d")
.format("DD/MM/YYYY");
if (delta_month > 0) {
next_first = first_day
.clone()
.subtract(delta_month, "months");
}
this.first_day = moment
.max([next_first, moment_min])
.format("DD/MM/YYYY");
}
if (type == "next") {
// Compare for last day
let next_last = last_day.clone().add(delta_days).add(1, "d");
const moment_max = moment(this.maxDate, "DD/MM/YYYY");
this.first_day = moment(this.last_day, "DD/MM/YYYY")
.add(1, "d")
.format("DD/MM/YYYY");
if (delta_month > 0) {
next_last = last_day
.clone()
.add(delta_month, "months")
.endOf("month");
}
this.last_day = moment
.min([next_last, moment_max])
.format("DD/MM/YYYY");
}
this.date_range_picker
.data("daterangepicker")
.setStartDate(this.first_day);
this.date_range_picker
.data("daterangepicker")
.setEndDate(this.last_day);
this._updateChartData(this.title_name);
},
});
});