diff --git a/models/acc_operation.py b/models/acc_operation.py index 4acd9227321c3e87c3dd92050a25386d50c44f8c..9adba58d1a4995b3a3d4314aa58dc95a3d8ada13 100644 --- a/models/acc_operation.py +++ b/models/acc_operation.py @@ -5,7 +5,7 @@ from datetime import datetime, time from dateutil.relativedelta import relativedelta from odoo import _, models -from odoo.exceptions import ValidationError +from odoo.exceptions import UserError, ValidationError from odoo.osv import expression from odoo.tools import date_utils @@ -45,11 +45,11 @@ class AccOperation(models.Model): # Get last date slot recorded last_record = self.get_last_cdc_record() start_date, end_date = self.get_interval("month", last_record) + end_date_month = end_date + relativedelta(days=1) query = """ SELECT - date_trunc('month', - cdc.date_slot AT TIME ZONE 'UTC' AT TIME ZONE 'Europe/Paris' - ) AS date_slot, + date_trunc('month', cdc.date_slot AT TIME ZONE 'UTC' \ + AT TIME ZONE 'Europe/Paris') AS date_slot, (SUM( (CASE WHEN cdc.comp_data_type = 'cons' THEN cdc.power ELSE 0 END) )/2) / 1000 as conso_tot, @@ -66,14 +66,14 @@ class AccOperation(models.Model): WHERE cdc.acc_operation_id = %s AND cdc.date_slot >= %s - AND cdc.date_slot <= %s - GROUP BY date_trunc('month', - cdc.date_slot AT TIME ZONE 'UTC' AT TIME ZONE 'Europe/Paris'); + AND cdc.date_slot < %s + GROUP BY date_trunc('month', cdc.date_slot AT TIME ZONE 'UTC' \ + AT TIME ZONE 'Europe/Paris'); """ query_params = ( self.id, - start_date, - end_date, + self._convert_time(start_date), + self._convert_time(end_date_month), ) self.env.cr.execute(query, query_params) raw_data = self.env.cr.fetchone() @@ -161,7 +161,7 @@ class AccOperation(models.Model): step = "hour" step_display_curve = "hour" # Calculate delta between 2 dates - delta = (end_date - start_date).days + delta = (self._convert_time(end_date) - self._convert_time(start_date)).days if delta > 0 and delta < 31: step_display_curve = "day" display_hourly_curves = True @@ -174,16 +174,19 @@ class AccOperation(models.Model): return display_hourly_curves, step, step_display_curve - def get_cdc_by_query_cons(self, slot_type, start_date, end_date, prm_ids=None): + def get_cdc_by_query_cons( + self, slot_type, start_date, end_date, prm_ids=None, partner_ids=None + ): """ Fonction permettant de récupérer les données pour la construction des chart pour une ou des opérations données pour les consommateurs - :param slot_type: type de slot pour la query ("hour", "month" ou + :param: slot_type: type de slot pour la query ("hour", "month" ou "year") start_date: date début end_date: date de fin prm_ids : liste des PRMs de soutirage à récupérer + partner_ids: liste des partner associés à la courbe @returns: un dictionnaire de données (labels et data pour les charts à afficher) """ @@ -196,9 +199,8 @@ class AccOperation(models.Model): query = """ SELECT - date_trunc(%s, - cdc.date_slot AT TIME ZONE 'UTC' AT TIME ZONE 'Europe/Paris' - ) AS date_slot, + date_trunc(%s, cdc.date_slot AT TIME ZONE 'UTC' \ + AT TIME ZONE 'Europe/Paris') AS date_slot, (SUM( (CASE WHEN cdc.comp_data_type = 'cons' THEN cdc.power ELSE 0 END) )/2) / 1000 as cons, @@ -217,8 +219,9 @@ class AccOperation(models.Model): AND ( cdc.acc_counter_id IN %s OR cdc.comp_data_type = 'prod' ) AND cdc.date_slot >= %s AND cdc.date_slot <= %s - GROUP BY date_trunc(%s, - cdc.date_slot AT TIME ZONE 'UTC' AT TIME ZONE 'Europe/Paris') + AND cdc.partner_id IN %s + GROUP BY date_trunc(%s, cdc.date_slot AT TIME ZONE 'UTC' \ + AT TIME ZONE 'Europe/Paris') ORDER BY date_slot ASC; """ query_params = ( @@ -227,6 +230,7 @@ class AccOperation(models.Model): tuple(prm_ids.ids), start_date, end_date, + tuple(partner_ids.ids), slot_type, ) self.env.cr.execute(query, query_params) @@ -247,13 +251,16 @@ class AccOperation(models.Model): } return cdc_cons - def get_cdc_by_query_daily_histo_cons(self, start_date, end_date, prm_ids=None): + def get_cdc_by_query_daily_histo_cons( + self, start_date, end_date, prm_ids=None, partner_ids=None + ): """ Fonction permettant de récupérer les données pour la construction des chart pour une ou des opérations données pour les consommateurs - :param start_date: date début + :param: start_date: date début end_date: date de fin prm_ids: liste des PRMs de soutirage à récupérer + partner_ids: liste des partner associés à la courbe :return: un dictionnaire de données (labels et data pour les charts à afficher) """ @@ -263,9 +270,8 @@ class AccOperation(models.Model): query = """ SELECT - date_trunc('day', - cdc.date_slot AT TIME ZONE 'UTC' AT TIME ZONE 'Europe/Paris' - ) AS date_slot, + date_trunc('day', cdc.date_slot AT TIME ZONE 'UTC' \ + AT TIME ZONE 'Europe/Paris') AS date_slot, (SUM( (CASE WHEN cdc.comp_data_type = 'autocons' THEN cdc.power ELSE 0 END) )/2) / 1000 as autocons, @@ -282,8 +288,9 @@ class AccOperation(models.Model): AND cdc.acc_counter_id IN %s AND cdc.date_slot >= %s AND cdc.date_slot <= %s - GROUP BY date_trunc('day', - cdc.date_slot AT TIME ZONE 'UTC' AT TIME ZONE 'Europe/Paris') + AND cdc.partner_id IN %s + GROUP BY date_trunc('day', cdc.date_slot AT TIME ZONE 'UTC' \ + AT TIME ZONE 'Europe/Paris') ORDER BY date_slot ASC; """ query_params = ( @@ -291,6 +298,7 @@ class AccOperation(models.Model): tuple(prm_ids.ids), start_date, end_date, + tuple(partner_ids.ids), ) self.env.cr.execute(query, query_params) raw_data = self.env.cr.fetchall() @@ -306,15 +314,18 @@ class AccOperation(models.Model): } return cdc_cons - def get_cdc_by_query_prod(self, slot_type, start_date, end_date, prm_ids=None): + def get_cdc_by_query_prod( + self, slot_type, start_date, end_date, prm_ids=None, partner_ids=None + ): """ Fonction permettant de récupérer les données pour la construction des chart pour une ou des opérations données pour les consommateurs - :param slot_type: type de slot pour la query ("hour", "month" + :param: slot_type: type de slot pour la query ("hour", "month" ou "year") start_date: date début end_date: date de fin prm_ids: liste des PRMs d'injection à récupérer + partner_ids: liste des partner associés à la courbe :return: un dictionnaire de données (labels et data pour les charts à afficher) """ @@ -324,9 +335,8 @@ class AccOperation(models.Model): query = """ SELECT - date_trunc(%s, - cdc.date_slot AT TIME ZONE 'UTC' AT TIME ZONE 'Europe/Paris' - ) AS date_slot, + date_trunc(%s, cdc.date_slot AT TIME ZONE 'UTC' \ + AT TIME ZONE 'Europe/Paris') AS date_slot, ((SUM((CASE WHEN cdc.comp_data_type = 'prod' THEN cdc.power ELSE 0 END)) @@ -344,8 +354,9 @@ class AccOperation(models.Model): AND cdc.acc_operation_id IN %s AND cdc.date_slot >= %s AND cdc.date_slot <= %s - GROUP BY date_trunc(%s, - cdc.date_slot AT TIME ZONE 'UTC' AT TIME ZONE 'Europe/Paris') + AND cdc.partner_id IN %s + GROUP BY date_trunc(%s, cdc.date_slot AT TIME ZONE 'UTC' \ + AT TIME ZONE 'Europe/Paris') ORDER BY date_slot ASC; """ query_params = ( @@ -354,6 +365,7 @@ class AccOperation(models.Model): tuple(self.ids), start_date, end_date, + tuple(partner_ids.ids), slot_type, ) self.env.cr.execute(query, query_params) @@ -370,13 +382,16 @@ class AccOperation(models.Model): } return cdc_prod - def get_cdc_by_query_daily_histo_prod(self, start_date, end_date, prm_ids=None): + def get_cdc_by_query_daily_histo_prod( + self, start_date, end_date, prm_ids=None, partner_ids=None + ): """ Fonction permettant de récupérer les données pour la construction des chart pour une ou des opérations données pour les consommateurs - :param start_date: date début + :param: start_date: date début end_date: date de fin prm_ids: liste des PRMs d'injection à récupérer + partner_ids: liste des partner associés à la courbe :return: un dictionnaire de données (labels et data pour les charts à afficher) """ @@ -386,9 +401,8 @@ class AccOperation(models.Model): query = """ SELECT - date_trunc('day', - cdc.date_slot AT TIME ZONE 'UTC' AT TIME ZONE 'Europe/Paris' - ) AS date_slot, + date_trunc('day', cdc.date_slot AT TIME ZONE 'UTC' \ + AT TIME ZONE 'Europe/Paris') AS date_slot, ((SUM((CASE WHEN cdc.comp_data_type = 'prod' THEN cdc.power ELSE 0 END)) @@ -406,8 +420,9 @@ class AccOperation(models.Model): AND cdc.acc_operation_id IN %s AND cdc.date_slot >= %s AND cdc.date_slot <= %s - GROUP BY date_trunc('day', - cdc.date_slot AT TIME ZONE 'UTC' AT TIME ZONE 'Europe/Paris') + AND cdc.partner_id IN %s + GROUP BY date_trunc('day', cdc.date_slot AT TIME ZONE 'UTC' \ + AT TIME ZONE 'Europe/Paris') ORDER BY date_slot ASC; """ query_params = ( @@ -415,6 +430,7 @@ class AccOperation(models.Model): tuple(self.ids), start_date, end_date, + tuple(partner_ids.ids), ) self.env.cr.execute(query, query_params) raw_data = self.env.cr.fetchall() @@ -459,7 +475,7 @@ class AccOperation(models.Model): """ Fonction appelée pour l'affichage des courbes globales sur le portail - :param start_date: date début + :param: start_date: date début end_date: date de fin partner_id: données uniquement de ce contact prm_id: données uniquement de ce PRM (mutuellement exclusif de @@ -472,46 +488,51 @@ class AccOperation(models.Model): """ self.ensure_one() result_graph = {} - start_date = datetime.strptime(start_date, "%d/%m/%Y") - end_date = datetime.combine(datetime.strptime(end_date, "%d/%m/%Y"), time.max) + start_date = self._convert_time(datetime.strptime(start_date, "%d/%m/%Y")) + end_date = self._convert_time( + datetime.combine(datetime.strptime(end_date, "%d/%m/%Y"), time.max) + ) display_hourly_curves, step_curve, step_display_curve = self.get_step_from_date( start_date=start_date, end_date=end_date ) - # TODO: ajouter filtre par période de PRM en fonction date de début / fin - # (si prm_id ou partner_id) + domain = [["acc_operation_id", "=", self.id]] - # Si prm_id alors filtrer pour n'afficher que ce compteur if prm_id: - acc_counter_ids = self.env["acc.counter"].browse(prm_id) - else: - # Filtre par défaut = même opération - domain = [["acc_operation_id", "=", self.id]] - # Si partner_id alors on ne prend que les PRMs appartenant à ce contact - if partner_id: - domain = expression.AND([domain, [("partner_id", "=", partner_id)]]) - acc_counter_ids = ( - self.env["acc.counter.period"].search(domain).mapped("acc_counter_id") + domain = expression.AND([domain, [("acc_counter_id", "=", prm_id)]]) + if partner_id: + domain = expression.AND([domain, [("partner_id", "=", partner_id)]]) + periods = ( + self.env["acc.counter.period"] + .sudo() + ._get_periods_from_interval( + domain=domain, start_date=start_date, end_date=end_date ) + ) + if periods: + acc_counter_ids = periods.mapped("acc_counter_id") + acc_partner_ids = periods.mapped("partner_id") + else: + raise UserError(_("No data found")) chart_data = {} if data_type == "cons" or data_type == "pmo": chart_data_cons = self.get_cdc_by_query_cons( - step_curve, start_date, end_date, acc_counter_ids + step_curve, start_date, end_date, acc_counter_ids, acc_partner_ids ) if display_hourly_curves: chart_data_histo = self.get_cdc_by_query_daily_histo_cons( - start_date, end_date, acc_counter_ids + start_date, end_date, acc_counter_ids, acc_partner_ids ) chart_data_cons.update(chart_data_histo) chart_data.update(chart_data_cons) if data_type == "prod" or data_type == "pmo": chart_data_prod = self.get_cdc_by_query_prod( - step_curve, start_date, end_date, acc_counter_ids + step_curve, start_date, end_date, acc_counter_ids, acc_partner_ids ) if display_hourly_curves: chart_data_histo = self.get_cdc_by_query_daily_histo_prod( - start_date, end_date, acc_counter_ids + start_date, end_date, acc_counter_ids, acc_partner_ids ) chart_data_prod.update(chart_data_histo) chart_data.update(chart_data_prod)