Skip to content
Extraits de code Groupes Projets

Comparer les révisions

Les modifications sont affichées comme si la révision source était fusionnée avec la révision cible. En savoir plus sur la comparaison des révisions.

Source

Sélectionner le projet cible
No results found
Sélectionner une révision Git
  • 16.0
1 résultat

Cible

Sélectionner le projet cible
  • lefilament/oacc/oacc_portal_overview_cdc
  • arthur-enercoop/oacc_portal_overview_cdc
2 résultats
Sélectionner une révision Git
  • 16.0
  • 16.0-admin-menu-refactoring
2 résultats
Afficher les modifications
Validations sur la source (54)
......@@ -9,7 +9,8 @@ exclude: |
# Maybe reactivate this when all README files include prettier ignore tags?
^README\.md$|
# Library files can have extraneous formatting (even minimized)
/static/(src/)?lib/|
/static/(src/)?lib/(.*/)?|
/static/src/js/lib/|
# Repos using Sphinx to generate docs don't need prettying
^docs/_templates/.*\.html$|
# Don't bother non-technical authors with formatting issues in docs
......
......@@ -5,12 +5,12 @@ load-plugins=pylint_odoo
score=n
[ODOOLINT]
readme_template_url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst"
manifest_required_authors=Le Filament
manifest_required_keys=license
manifest_deprecated_keys=description,active
license_allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3
valid_odoo_versions=16.0
readme-template-url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst"
manifest-required-authors=Le Filament
manifest-required-keys=license
manifest-deprecated-keys=description,active
license-allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3
valid-odoo-versions=16.0
[MESSAGES CONTROL]
disable=all
......
......@@ -3,7 +3,7 @@
"summary": "Gestion portail affichage des courbes de charge",
"author": "Le Filament",
"website": "https://le-filament.com",
"version": "16.0.1.0.1",
"version": "16.0.1.0.2",
"license": "AGPL-3",
"depends": ["web", "oacc_portal"],
"data": [
......
# Copyright 2021- Le Filament (https://le-filament.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
from odoo import http
import werkzeug
from odoo import _, http
from odoo.exceptions import AccessError
from odoo.http import request
from odoo.addons.oacc_portal.controllers.main import CustomerPortal as CustomerPortal
......@@ -159,6 +162,7 @@ class CustomerPortal(CustomerPortal):
start_date=None,
end_date=None,
data_type=None,
graph_type="histo",
**kw,
):
"""
......@@ -167,10 +171,42 @@ class CustomerPortal(CustomerPortal):
- When click on a consumer, a productor or a PRM
- When click on date range
"""
# TODO: add check that prm_id and partner_id are allowed for this user
operation = request.env["acc.operation"].browse(operation_id)
vals = operation._graph_view_global(
start_date, end_date, partner_id, prm_id, data_type
try:
roles = self._get_role(operation)
except AccessError as e:
raise werkzeug.exceptions.abort(
werkzeug.wrappers.Response(status=401)
) from e
# Si l'opération n'a pas de courbes on renvoie une erreur 401
# Si l'utilisateur n'est pas soit superAdmin, soit Admin, soit Pmo,
# 1. si prm_id est passé il doit aussi y avoir un partner_id
# 2. il faut vérifier qu'il est bien autorisé à accéder au partner_id
# si passé en paramètre
# sinon on renvoie une erreur 401
# (on ne vérifie pas qu'il ait bien accès au prm, aucune donnée ne sera renvoyée
# si les courbes du prm demandées n'appartiennent pas à ce partner)
if not roles.get("isDataCdc") or (
not roles.get("isSuperAdmin")
and not roles.get("isAdmin")
and not roles.get("isPmo")
and (prm_id or partner_id)
and (
(prm_id and not partner_id)
or (
partner_id
and partner_id != request.env.user.commercial_partner_id.id
)
)
):
raise werkzeug.exceptions.abort(werkzeug.wrappers.Response(status=401))
if graph_type == "repartition_data":
vals = operation._get_repartition_data(
start_date, end_date, partner_id, prm_id
)
else:
vals = operation._get_graph(
start_date, end_date, partner_id, prm_id, data_type, graph_type
)
return vals
......@@ -197,8 +233,57 @@ class CustomerPortal(CustomerPortal):
This route is called :
- When click on button export
"""
# TODO: add check that prm_id and partner_id are allowed for this user
operation = request.env["acc.operation"].sudo().browse(int(operation_id))
try:
if (
request.env.user.commercial_partner_id.id
not in operation.partner_role_ids.partner_id.ids
and not request.env.user.has_group("oacc.group_operation_superadmin")
):
raise AccessError(_("You are not allowed to access this operation"))
roles = self._get_role(operation)
except AccessError as e:
raise werkzeug.exceptions.abort(
werkzeug.wrappers.Response(status=401)
) from e
# Si l'opération n'a pas de courbes on renvoie une erreur 401
# Si l'utilisateur n'est pas soit superAdmin, soit Admin, soit Pmo,
# 1. le partner_id est obligatoire
# 2. il faut vérifier qu'il est bien autorisé à accéder au partner_id
# 3. il faut vérifier que le PRM correspond bien à une période de ce partner_id
# sur l'opération
# sinon on renvoie une erreur 401
# (on ne vérifie pas qu'il ait bien accès au prm, aucune donnée ne sera renvoyée
# si les courbes du prm demandées n'appartiennent pas à ce partner)
if not roles.get("isDataCdc") or (
not roles.get("isSuperAdmin")
and not roles.get("isAdmin")
and not roles.get("isPmo")
and (
not partner_id
or (
partner_id
and int(partner_id) != request.env.user.commercial_partner_id.id
)
or (
prm_id
and (
int(prm_id)
not in operation.acc_injection_period_ids.filtered(
lambda p: p.partner_id.id == int(partner_id)
).acc_counter_id.ids
and int(prm_id)
not in operation.acc_delivery_period_ids.filtered(
lambda p: p.partner_id.id == int(partner_id)
).acc_counter_id.ids
)
)
)
):
raise werkzeug.exceptions.abort(werkzeug.wrappers.Response(status=401))
file_values = operation._export_cdc(
start_date, end_date, partner_id, prm_id, data_type
)
......
from . import acc_enedis_cdc
from . import acc_operation
Ce diff est replié.
......@@ -7,7 +7,15 @@ from dateutil.relativedelta import relativedelta
from odoo import fields, http, models
from ..tools import export_cdc
DATA_TYPE_MAP = {
"pmo": ["autocons", "allocons", "autocons_prod", "surplus"],
"cons": ["autocons", "allocons"],
"prod": ["autocons_prod", "surplus"],
}
EXPORT_DATA_TYPE_MAP = {
"cons": ["cons", "autocons", "allocons"],
"prod": ["prod", "autocons_prod", "surplus"],
}
class AccOperation(models.Model):
......@@ -53,13 +61,85 @@ class AccOperation(models.Model):
"target": "new",
}
def _graph_view_global(
@staticmethod
def _get_step_from_date(start_date, end_date):
"""
Fonction retournant le pas des courbes en fonction de 2 dates.
:return:
display_hourly_curves (boolean) : whether or not hourly curves
should be displayed
step: hour/month/year
step_display_curve: hour/day/month/year
"""
display_hourly_curves = False
step = "hour"
step_display_curve = "hour"
# Calculate delta between 2 dates
delta = (end_date - start_date).days
if 1 < delta <= 31:
step_display_curve = "day"
display_hourly_curves = True
elif 31 < delta <= 366:
step = "month"
step_display_curve = "month"
elif delta > 366:
step = "year"
step_display_curve = "year"
return display_hourly_curves, step, step_display_curve
def _get_repartition_data(
self,
start_date,
end_date,
filter_partner_id,
filter_prm_id,
):
from ..tools import prepare_repartition_data
self.ensure_one()
start_date = datetime.strptime(start_date, "%d/%m/%Y")
end_date = datetime.strptime(end_date, "%d/%m/%Y") + relativedelta(days=1)
energy_dict = self.env["acc.enedis.cdc.day"]._get_proratized_energy(
acc_operation_id=self.id,
start_date=start_date,
end_date=end_date,
filter_date=False,
exclude_empty_partner=False,
)
(total_prod, total_surplus) = prepare_repartition_data.get_prod_datas_prorata(
energy_dict["prod"]["partner_ids"], filter_partner_id, filter_prm_id
)
if total_prod == 0:
return "Pas de donnée de production pour cette période"
tPartners = prepare_repartition_data.get_partners_data_prorata(
self.env,
energy_dict["cons"]["partner_ids"],
total_prod,
filter_partner_id,
filter_prm_id,
)
tSurplus = {
"surplus": total_surplus,
"percentage": 100 * total_surplus / total_prod if total_prod else 0,
}
render_values = {"tPartners": tPartners, "tSurplus": tSurplus}
html = self.env["ir.ui.view"]._render_template(
"oacc_portal_overview_cdc.repartition_prod_content", render_values
)
return html
def _get_graph(
self,
start_date=None,
end_date=None,
partner_id=None,
prm_id=None,
data_type=None,
chart_type="histo",
):
"""
Fonction appelée pour l'affichage des courbes globales
......@@ -73,40 +153,54 @@ class AccOperation(models.Model):
- "pmo" : vue globale (cons + prod sans filtrage)
- "cons" : vue mon suivi conso (avec filtrage possible)
- "prod" : vue mon suivi production (avec filtrage possible)
char chart_type: type de visualisation attendue :
- histo (histogramme + camembert agrégé)
- curve (courbe à l'heure)
@returns: dictionnaire pour la construction des graphes
"""
self.ensure_one()
result_graph = {}
Cdc_model = self.env["acc.enedis.cdc"]
start_date = datetime.strptime(start_date, "%d/%m/%Y")
end_date = datetime.strptime(end_date, "%d/%m/%Y") + relativedelta(days=1)
(
display_hourly_curves,
step_curve,
step_display_curve,
) = Cdc_model._get_step_from_date(start_date=start_date, end_date=end_date)
) = self._get_step_from_date(start_date=start_date, end_date=end_date)
chart_data = {}
if data_type == "cons" or data_type == "pmo":
chart_data_cons = Cdc_model._get_cdc_by_query_cons(
self.id, step_curve, start_date, end_date, prm_id, partner_id
)
if display_hourly_curves:
chart_data_histo = Cdc_model._get_cdc_by_query_daily_histo_cons(
self.id, start_date, end_date, prm_id, partner_id
if chart_type == "histo":
if step_display_curve != "hour":
chart_data = self.env["acc.enedis.cdc.day"]._get_chart(
acc_operation_id=self.id,
start_date=start_date,
end_date=end_date,
partner_id=partner_id,
prm_id=prm_id,
groupby_date_slot=step_display_curve,
values_type=DATA_TYPE_MAP[data_type],
)
chart_data_cons.update(chart_data_histo)
chart_data.update(chart_data_cons)
if data_type == "prod" or data_type == "pmo":
chart_data_prod = Cdc_model._get_cdc_by_query_prod(
self.id, step_curve, start_date, end_date, prm_id, partner_id
elif step_display_curve == "hour":
chart_data = self.env["acc.enedis.cdc"]._get_chart(
acc_operation_id=self.id,
start_date=start_date,
end_date=end_date,
partner_id=partner_id,
prm_id=prm_id,
groupby_date_slot=step_display_curve,
values_type=DATA_TYPE_MAP[data_type],
)
if display_hourly_curves:
chart_data_histo = Cdc_model._get_cdc_by_query_daily_histo_prod(
self.id, start_date, end_date, prm_id, partner_id
elif chart_type == "curve" and display_hourly_curves:
chart_data = self.env["acc.enedis.cdc"]._get_chart(
acc_operation_id=self.id,
start_date=start_date,
end_date=end_date,
partner_id=partner_id,
prm_id=prm_id,
groupby_date_slot="hour",
values_type=DATA_TYPE_MAP[data_type],
extra_value_type="prod" if data_type != "prod" else None,
)
chart_data_prod.update(chart_data_histo)
chart_data.update(chart_data_prod)
result_graph["chart_data"] = chart_data
result_graph.update(self.get_date_min_max(partner_id))
......@@ -122,7 +216,7 @@ class AccOperation(models.Model):
def _export_cdc(self, start_date, end_date, partner_id, prm_id, data_type):
"""
Fonction permettant d'exporter les courbes Enedis
:param start_date:
:param end_date:
:param partner_id:
......@@ -130,6 +224,8 @@ class AccOperation(models.Model):
:param data_type:
:return:
"""
from ..tools import export_cdc
start = datetime.strptime(start_date, "%d/%m/%Y")
end = datetime.strptime(end_date, "%d/%m/%Y") + relativedelta(days=1)
......@@ -137,30 +233,21 @@ class AccOperation(models.Model):
self, start_date, end_date, partner_id, prm_id, data_type
)
header = export_cdc.make_header_lines(self, partner_id, prm_id, data_type)
if data_type in ["cons"]:
data_file = export_cdc.make_cons_data(
self.env["acc.enedis.cdc"]._cdc_by_query_cons(
self.id,
"minute",
start,
end,
prm_id,
partner_id,
curve_types=["cons", "autocons", "allocons"],
)
)
if data_type in ["prod"]:
data_file = export_cdc.make_prod_data(
self.env["acc.enedis.cdc"]._cdc_by_query_prod(
self.id,
"minute",
start,
end,
prm_id,
partner_id,
curve_types=["autoprod", "surplus", "prod"],
)
data_dict = self.env["acc.enedis.cdc"]._get_curves(
acc_operation_id=self.id,
start_date=start,
end_date=end,
partner_id=int(partner_id) if partner_id else None,
prm_id=int(prm_id) if prm_id else None,
groupby_date_slot="minute",
values_type=EXPORT_DATA_TYPE_MAP[data_type],
exclude_empty_partner=False,
)
data_file = []
if data_type in ["cons"]:
data_file = export_cdc.make_cons_data(data_dict)
elif data_type in ["prod"]:
data_file = export_cdc.make_prod_data(data_dict)
fout = StringIO()
for h_line in header:
......@@ -204,30 +291,29 @@ class AccOperation(models.Model):
def _get_values_init_graph(self, partner_id=None):
self.ensure_one()
values = {}
Cdc_model = self.env["acc.enedis.cdc"]
last_record = Cdc_model._get_last_cdc_record(self.id, partner_id)
date_day_start, date_day_end = Cdc_model._get_interval("day", last_record)
date_day_start, date_day_end = last_record.get_interval("day")
date_day_start = date_day_start.strftime("%d/%m/%Y")
date_day_end = date_day_end.strftime("%d/%m/%Y")
date_week_start, date_week_end = Cdc_model._get_interval("week", last_record)
date_week_start, date_week_end = last_record.get_interval("week")
date_week_start = date_week_start.strftime("%d/%m/%Y")
date_week_end = date_week_end.strftime("%d/%m/%Y")
date_month_start, date_month_end = Cdc_model._get_interval("month", last_record)
date_month_start, date_month_end = last_record.get_interval("month")
date_month_start = date_month_start.strftime("%d/%m/%Y")
date_month_end = date_month_end.strftime("%d/%m/%Y")
date_year_start, date_year_end = Cdc_model._get_interval("year", last_record)
date_year_start, date_year_end = last_record.get_interval("year")
date_year_start = date_year_start.strftime("%d/%m/%Y")
date_year_end = date_year_end.strftime("%d/%m/%Y")
values = {
return {
"date_day_start": date_day_start,
"date_day_end": date_day_end,
"date_week_start": date_week_start,
......@@ -237,5 +323,3 @@ class AccOperation(models.Model):
"date_year_start": date_year_start,
"date_year_end": date_year_end,
}
return values
.daterange-content {
padding-top: 10px;
max-width: 300px;
}
......@@ -22,3 +21,7 @@ Charts
.line_chart_prod {
margin: auto;
}
.collapse-row {
visibility: collapse;
}
Ce diff est replié.
......@@ -4,11 +4,11 @@
<odoo>
<!-- Layout operation -->
<template id="layout_op" inherit_id="oacc_portal.layout_op">
<template id="nav_menu_content" inherit_id="oacc_portal.nav_menu_content">
<xpath expr="//li[@id='menu-accueil']" position="after">
<li
class="nav-item"
t-if="isPmo or isConsumer or isProductor or isAdmin or isSuperAdmin"
t-if="(isPmo or isConsumer or isProductor or isAdmin or isSuperAdmin) and isDataCdc"
>
<a
t-attf-href="/operation/#{slug(operation)}/pmo"
......@@ -19,7 +19,7 @@
</li>
<li
class="nav-item"
t-if="isPmo or isConsumer or isAdmin or isSuperAdmin"
t-if="(isPmo or isConsumer or isAdmin or isSuperAdmin) and isDataCdc"
>
<a
t-attf-href="/operation/#{slug(operation)}/consumer"
......@@ -30,7 +30,7 @@
</li>
<li
class="nav-item"
t-if="isPmo or isProductor or isAdmin or isSuperAdmin"
t-if="(isPmo or isProductor or isAdmin or isSuperAdmin) and isDataCdc"
>
<a
t-attf-href="/operation/#{slug(operation)}/productor"
......
......@@ -3,14 +3,12 @@ import unicodedata
PROD_HEADER = [
"Horodatage",
"Production (W)",
"Production (kWh)",
"Surplus (kWh)",
"Production autoconsommée (kWh)",
]
CONS_HEADER = [
"Horodatage",
"Consommation (W)",
"Consommation (kWh)",
"Alloconsommation (kWh)",
"Autoconsommation (kWh)",
......@@ -55,14 +53,15 @@ def make_filename(
operation, start_date, end_date, partner_id, prm_id, data_type, file_type="csv"
):
"""
Genere le nom du fichier exporte sous la forme
Elocoop_[nom opé]_[date_debut]_[date_fin]_[production ou consommation]_[contact ou PRM].csv
Génère le nom du fichier exporté sous la forme
Elocoop_[nom opé]_[date_debut]_[date_fin]_[production ou consommation]\
_[contact ou PRM].csv
:param operation: id de l operation
:param start_date: date de debut
:param start_date: date de début
:param end_date: date de fin
:param partner_id: id du partner
:param prm_id: id du prm
:param data_type: type de données (consomation ou production)
:param data_type: type de données (consommation ou production)
:param file_type: type de fichier par defaut csv
:return:
"""
......@@ -81,11 +80,11 @@ def make_filename(
return filename
def make_cons_data(raw_data):
def make_cons_data(energy_dict):
"""
make data file with cons hearder
horodatage cons w cons kwh allocons autocans
:param raw_data:
:param energy_dict:
:return:
"""
......@@ -93,79 +92,96 @@ def make_cons_data(raw_data):
data_file_lines = []
rounding = 3
for row in raw_data:
for period in energy_dict:
data_file_lines.append(
";".join(
[
# horodatage
row[0].strftime("%d/%m/%Y %H:%M"),
# consommation en watt
str(round(row[1] * 2000, rounding)),
period.strftime("%d/%m/%Y %H:%M"),
# consommation en kwh
str(round(row[1], rounding)),
str(round(energy_dict[period].get("cons", 0.0), rounding)),
# allocons
str(round(row[3], rounding)),
str(
round(
energy_dict[period].get("cons", 0.0)
- energy_dict[period].get("autocons", 0.0),
rounding,
)
),
# autocons
str(round(row[2], rounding)),
str(round(energy_dict[period].get("autocons", 0.0), rounding)),
]
)
)
sum_value["cons"] += round(row[1], rounding)
sum_value["allo_cons"] += round(row[3], rounding)
sum_value["auto_cons"] += round(row[2], rounding)
sum_value["cons"] += round(energy_dict[period].get("cons", 0.0), rounding)
sum_value["auto_cons"] += round(
energy_dict[period].get("autocons", 0.0), rounding
)
sum_value["allo_cons"] += round(
energy_dict[period].get("cons", 0.0)
- energy_dict[period].get("autocons", 0.0),
rounding,
)
tot = ";".join(
[
"TOTAL",
"",
str(round(sum_value.get("cons"), rounding)),
str(round(sum_value.get("allo_cons"), rounding)),
str(round(sum_value.get("auto_cons"), rounding)),
str(round(sum_value.get("cons", 0.0), rounding)),
str(round(sum_value.get("allo_cons", 0.0), rounding)),
str(round(sum_value.get("auto_cons", 0.0), rounding)),
]
)
data_file_lines.insert(0, tot)
return data_file_lines
def make_prod_data(raw_data):
def make_prod_data(energy_dict):
"""
make data file with prod hearder
horodatage prod w prod kwh surplus autocons
:param raw_data:
:param energy_dict:
:return:
"""
data_file_lines = []
rounding = 3
sum_value = {"prod": 0, "surplus": 0, "auto_cons": 0}
for row in raw_data:
for period in energy_dict:
data_file_lines.append(
";".join(
[
# horodatage
row[0].strftime("%d/%m/%Y %H:%M"),
# production en watt
str(round(row[3] * 2000, rounding)),
period.strftime("%d/%m/%Y %H:%M"),
# production en kwh
str(round(row[3], rounding)),
str(round(energy_dict[period].get("prod", 0.0), rounding)),
# surplus
str(round(row[2], rounding)),
str(round(energy_dict[period].get("surplus", 0.0), rounding)),
# autocons
str(round(row[1], rounding)),
str(
round(
energy_dict[period].get("prod", 0.0)
- energy_dict[period].get("surplus", 0.0),
rounding,
)
),
]
)
)
sum_value["prod"] += round(row[3], rounding)
sum_value["surplus"] += round(row[2], rounding)
sum_value["auto_cons"] += round(row[1], rounding)
sum_value["prod"] += round(energy_dict[period].get("prod", 0.0), rounding)
sum_value["surplus"] += round(energy_dict[period].get("surplus", 0.0), rounding)
sum_value["auto_cons"] += round(
energy_dict[period].get("prod", 0.0)
- energy_dict[period].get("surplus", 0.0),
rounding,
)
tot = ";".join(
[
"TOTAL",
"",
str(round(sum_value.get("prod"), rounding)),
str(round(sum_value.get("surplus"), rounding)),
str(round(sum_value.get("auto_cons"), rounding)),
str(round(sum_value.get("prod", 0.0), rounding)),
str(round(sum_value.get("surplus", 0.0), rounding)),
str(round(sum_value.get("auto_cons", 0.0), rounding)),
]
)
data_file_lines.insert(0, tot)
......
def get_prod_datas_prorata(
inj_partners_node, filter_partner_id=None, filter_counter_id=None
):
total_surplus = 0
total_prod = 0
for partner_id in inj_partners_node: # producteur
if filter_partner_id is not None and partner_id != filter_partner_id:
continue
inj_counters_node = inj_partners_node[partner_id]["acc_counter_ids"]
for counter_id in inj_counters_node: # injection
if filter_counter_id is not None and counter_id != filter_counter_id:
continue
total_surplus = total_surplus + inj_counters_node[counter_id].get(
"surplus", 0.0
)
total_prod = total_prod + inj_counters_node[counter_id].get("prod", 0.0)
return total_prod, total_surplus
def _sort_partners_prorata(
del_partners_node, filter_partner_id=None, filter_counter_id=None
):
tPartners = {}
for partner_id in del_partners_node: # consommateur
del_counters_node = del_partners_node[partner_id]["acc_counter_ids"]
autocons = 0
for counter_id in del_counters_node: # soutirage
if filter_counter_id is not None:
autocons += del_counters_node[counter_id][
"autocons_per_inj_counter"
].get(filter_counter_id, 0.0)
elif filter_partner_id is not None:
autocons += del_counters_node[counter_id][
"autocons_per_inj_partner"
].get(filter_partner_id, 0.0)
else:
autocons += del_counters_node[counter_id].get("autocons")
tPartners[partner_id] = autocons
sorted_partner = dict(
sorted(tPartners.items(), key=lambda item: item[1], reverse=True)
)
return sorted_partner
def _sort_counters_prorata(
del_counters_node, filter_partner_id=None, filter_counter_id=None
):
tCounters = {}
for counter_id in del_counters_node: # soutirage
autocons = 0
if filter_counter_id:
autocons = del_counters_node[counter_id]["autocons_per_inj_counter"].get(
filter_counter_id, 0.0
)
elif filter_partner_id:
autocons = del_counters_node[counter_id]["autocons_per_inj_partner"].get(
filter_partner_id, 0.0
)
else:
autocons = del_counters_node[counter_id].get("autocons", 0.0)
tCounters[counter_id] = autocons
sorted_counter = dict(
sorted(tCounters.items(), key=lambda item: item[1], reverse=True)
)
return sorted_counter
def _get_counters_data_prorata(
del_counters_dict,
del_counters_ndoe,
total,
filter_partner_id=None,
filter_counter_id=None,
):
tCounters = {}
subtotal = 0
sorted_counter = _sort_counters_prorata(
del_counters_ndoe, filter_partner_id, filter_counter_id
)
for counter_id in sorted_counter: # soutirage
tCounter = {
"name": del_counters_dict[counter_id]["name"],
"street": del_counters_dict[counter_id]["street"],
"street2": del_counters_dict[counter_id]["street2"],
"zip": del_counters_dict[counter_id]["zip"],
"city": del_counters_dict[counter_id]["city"],
"autocons": sorted_counter[counter_id],
"percentage": 100 * sorted_counter[counter_id] / total,
}
subtotal = subtotal + sorted_counter[counter_id]
tCounters[counter_id] = tCounter
return subtotal, tCounters
def get_partners_data_prorata(
env,
del_partners_node,
total,
filter_partner_id=None,
filter_counter_id=None,
):
tPartners = {}
dbPartners = env["res.partner"].browse(del_partners_node.keys())
del_partners_dict = {
partner["id"]: partner["name"] for partner in dbPartners.read(["name"])
}
del_counter_ids = {}
for partner_id in dbPartners.ids:
acc_counter_ids = del_partners_node[partner_id].get("acc_counter_ids", [])
for counter_id in acc_counter_ids:
del_counter_ids[counter_id] = acc_counter_ids[counter_id]
if 0 in del_partners_node:
del_partners_dict[0] = "Pas de participant lié".upper()
acc_counter_ids = del_partners_node[0].get("acc_counter_ids", [])
for counter_id in acc_counter_ids:
del_counter_ids[counter_id] = acc_counter_ids[counter_id]
dbCounters = env["acc.counter"].browse(del_counter_ids.keys())
del_counters_dict = {
counter["id"]: {
"name": counter["name"],
"street": counter["street"],
"street2": counter["street2"],
"zip": counter["zip"],
"city": counter["city"],
}
for counter in dbCounters.read(["name", "street", "street2", "zip", "city"])
}
sorted_partner = _sort_partners_prorata(
del_partners_node, filter_partner_id, filter_counter_id
)
for partner_id in sorted_partner: # consommateur
tPartner = {}
tPartner["name"] = del_partners_dict[partner_id]
del_counters_node = del_partners_node[partner_id]["acc_counter_ids"]
(subtotal, tCounters) = _get_counters_data_prorata(
del_counters_dict,
del_counters_node,
total,
filter_partner_id,
filter_counter_id,
)
tPartner["autocons"] = subtotal
tPartner["percentage"] = 100 * subtotal / total
tPartner["counters"] = tCounters
tPartners[partner_id] = tPartner
return tPartners