From 5d350e4179db7e1acdf523f7cf901a9d5260b64b Mon Sep 17 00:00:00 2001 From: Julien - Le Filament <julien@le-filament.com> Date: Mon, 19 Feb 2024 16:36:35 +0100 Subject: [PATCH] 16.0 keys --- README.rst | 4 +- __init__.py | 1 + __manifest__.py | 4 +- models/__init__.py | 2 +- models/acc_operation.py | 4 +- models/acc_repartition_keys.py | 2 +- security/ir.model.access.csv | 3 +- static/description/icon.png | Bin 0 -> 9161 bytes tools/__init__.py | 0 tools/key_file.py | 149 +++++++++++++++++++ views/acc_operation_views.xml | 21 +-- views/acc_repartition_keys_views.xml | 21 +++ wizard/__init__.py | 1 + wizard/acc_repartition_keys_wizard.py | 82 ++++++++++ wizard/acc_repartition_keys_wizard_views.xml | 34 +++++ 15 files changed, 307 insertions(+), 21 deletions(-) create mode 100755 static/description/icon.png create mode 100644 tools/__init__.py create mode 100644 tools/key_file.py create mode 100644 views/acc_repartition_keys_views.xml create mode 100644 wizard/__init__.py create mode 100644 wizard/acc_repartition_keys_wizard.py create mode 100644 wizard/acc_repartition_keys_wizard_views.xml diff --git a/README.rst b/README.rst index 786b31a..ae6b9ae 100644 --- a/README.rst +++ b/README.rst @@ -3,9 +3,9 @@ :alt: License: AGPL-3 -=========== +============================ OACC - Clefs de répartition -=========== +============================ Ce module permet d'uploader de tester et d envoyer a enedis les clefs de répartion pour une Opération d'AutoConsommation Collective: diff --git a/__init__.py b/__init__.py index 0650744..9b42961 100644 --- a/__init__.py +++ b/__init__.py @@ -1 +1,2 @@ from . import models +from . import wizard diff --git a/__manifest__.py b/__manifest__.py index 7fe4121..6acd514 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -11,9 +11,11 @@ # datas # views "views/acc_operation_views.xml", + "views/acc_repartition_keys_views.xml", # views menu # wizard + "wizard/acc_repartition_keys_wizard_views.xml", ], "installable": True, "auto_install": False, -} \ No newline at end of file +} diff --git a/models/__init__.py b/models/__init__.py index 95d38c2..1831689 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,2 +1,2 @@ from . import acc_operation -from . import acc_repartition_keys \ No newline at end of file +from . import acc_repartition_keys diff --git a/models/acc_operation.py b/models/acc_operation.py index fd774d8..1d29e8b 100644 --- a/models/acc_operation.py +++ b/models/acc_operation.py @@ -1,8 +1,8 @@ # Copyright 2021- Le Filament (https://le-filament.com) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) import logging -from odoo import _, fields, models +from odoo import fields, models _logger = logging.getLogger(__name__) @@ -41,4 +41,4 @@ class AccOperation(models.Model): # ------------------------------------------------------ # Actions - # ------------------------------------------------------ \ No newline at end of file + # ------------------------------------------------------ diff --git a/models/acc_repartition_keys.py b/models/acc_repartition_keys.py index b71474b..c71adcb 100644 --- a/models/acc_repartition_keys.py +++ b/models/acc_repartition_keys.py @@ -38,4 +38,4 @@ class AccRepartitionKeys(models.Model): # ------------------------------------------------------ # Business methods - # ------------------------------------------------------ \ No newline at end of file + # ------------------------------------------------------ diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index a07c238..8ce08fb 100644 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -1,3 +1,4 @@ id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink "access_acc_repartition_keys_group_partner_manager","acc_repartition_keys group_partner_manager","model_acc_repartition_keys","base.group_partner_manager",1,1,1,1 -"access_acc_repartition_keys_group_user","acc_repartition_keys group_user","model_acc_repartition_keys","base.group_user",1,0,0,0 \ No newline at end of file +"access_acc_repartition_keys_group_user","acc_repartition_keys group_user","model_acc_repartition_keys","base.group_user",1,0,0,0 +"access_acc_repartition_keys_wizard_group_partner_manager","acc_repartition_keys_wizard group_partner_manager","model_acc_repartition_keys_wizard","base.group_partner_manager",1,1,1,1 diff --git a/static/description/icon.png b/static/description/icon.png new file mode 100755 index 0000000000000000000000000000000000000000..82ef47760a441cf229b5009f0a18ccf3842fbfa5 GIT binary patch literal 9161 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 literal 0 HcmV?d00001 diff --git a/tools/__init__.py b/tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tools/key_file.py b/tools/key_file.py new file mode 100644 index 0000000..7e8a0a7 --- /dev/null +++ b/tools/key_file.py @@ -0,0 +1,149 @@ +""" +Repartion key entry file handler +""" +import csv +from datetime import datetime + + +class RepartitionKeyEntryFile: + def __init__(self, data, operation_counter_list): + self.data = data + self.operation_counter_list = operation_counter_list + self.json = self._to_json() + + def check(self): + """ + Lorsque le fichier est validé, des vérifications sont effectuées, et une erreur est affichée si le test ne passe pas : + • Première ligne, colonnes 2 à la fin : les numéros de PRM sont exactement ceux qui sont dans l’onglet Point de soutirage. + Aucun numéro de PRM n'apparaît plusieurs fois. + ◦ Erreur envoyée : “Les numéros de PRM ne correspondent pas à ceux de l’opération.” + + • Lignes 2 à la fin, Horodate : Les dates sont celles d’un seul mois complet. + ◦ Erreur envoyée “Les dates doivent être celles d’un seul mois complet.” + + • La somme sur chaque ligne doit être inférieure à 100. + ◦ Erreur envoyée “Ligne X : la somme dépasse 100%” + + """ + check_methods = [self._check_counter, self._check_same_month, self._check_max_value] + result = {"check": True, "message": ""} + for check in check_methods: + check_result = check() + if not check_result.get("check"): + result["check"] = False + result["message"] += f"{check_result['message']}\n" + + return result + + def _to_json(self): + """ + make data ready to send { "horodatage": [{"id": "value"}, ....]} + """ + json = {} + counter_list_from_file = self.data[0].split(";") + csv_file = csv.reader(self.data, delimiter=";") + line_count = 0 + for line in csv_file: + if line: + if line_count == 0: + line_count += 1 + continue + json[line[0]] = [] + line_count += 1 + counter_count = 1 + for counter in counter_list_from_file[1:]: + json[line[0]].append( + {"id": counter, "key": line[counter_count].replace(",", ".")} + ) + counter_count += 1 + return json + + def data_to_send(self, agreement_id, send_empty_key=False): + """ + return dict {"route", "body} to enedis + """ + call_list = [] + for horo in self.json: + date = datetime.strptime(horo, "%d-%m-%Y %H:%M") + route = f"/agreements/{agreement_id}/repartition_keys/{date.strftime('%Y%m%dT%H%MZ')}" + body = [] + for keys in self.json.get(horo): + if send_empty_key: + body.append(keys) + else: + if float(keys.get("key")) > 0: + body.append(keys) + if body: + call_list.append({"route": route, "body": body}) + return call_list + + def _check_counter(self): + """ + Check if all counter in file belong to operation + + """ + + if self.data: + counter_list_from_file = self.data[0].split(";")[1:] + + if sorted(self.operation_counter_list) == sorted(counter_list_from_file): + return {"check": True, "message": ""} + else: + missing_in_file = [ + counter + for counter in self.operation_counter_list + if counter not in counter_list_from_file + ] + missing_in_operation = [ + counter + for counter in counter_list_from_file + if counter not in self.operation_counter_list + ] + if missing_in_file or missing_in_operation: + return { + "check": False, + "message": "Les numéros de PRM ne correspondent pas à ceux de l’opération", + } + return {"check": True, "message": ""} + + def _check_max_value(self): + """ + check if all value are in the same month + """ + for hour in self.json: + max = 0 + for key in self.json[hour]: + if key["key"] == "0.00000000": + key["key"] = 0.0 + try: + max = max + float(key["key"]) + except ValueError: + pass + + if max > 100: + return { + "check": False, + "message": f"Ligne {hour} la somme dépasse 100.", + } + return {"check": True, "message": ""} + + def _check_same_month(self): + """ + check if all value are in the same month + """ + if ( + len( + set( + [ + datetime.strptime(date, "%d-%m-%Y %H:%M").month + for date in self.json + ] + ) + ) + != 1 + ): + return { + "check": False, + "message": "Les dates doivent être celles d’un seul mois complet.", + } + return {"check": True, "message": ""} diff --git a/views/acc_operation_views.xml b/views/acc_operation_views.xml index f5b2aa5..a70536f 100644 --- a/views/acc_operation_views.xml +++ b/views/acc_operation_views.xml @@ -2,7 +2,6 @@ <!-- Copyright 2021- Le Filament (https://le-filament.com) License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> <odoo> - <record id="acc_operation_form_view" model="ir.ui.view"> <field name="name">acc_operation_form_view.keys.form</field> <field name="model">acc.operation</field> @@ -11,22 +10,18 @@ <xpath expr="//notebook" position="inside"> <page string="Clefs de répartition" name="keys"> <header> -<!-- <button--> -<!-- string="Test"--> -<!-- type="object"--> -<!-- class="btn-primary"--> -<!-- name="test_file"--> -<!-- />--> + <button + string="Importer un fichier" + type="action" + name="%(oacc_repartition_keys.acc_repartition_keys_wizard_action)d" + class="btn-primary" + /> </header> - <group> + <tree> <field name="keys_repartition_ids" /> -<!-- <tree>--> -<!-- <field name="date_send"/>--> -<!-- </tree>--> - </group> + </tree> </page> </xpath> </field> </record> - </odoo> \ No newline at end of file diff --git a/views/acc_repartition_keys_views.xml b/views/acc_repartition_keys_views.xml new file mode 100644 index 0000000..e247914 --- /dev/null +++ b/views/acc_repartition_keys_views.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> +<!-- <data>--> + <record id="acc_keys_repatition_action" model="ir.actions.act_window"> + <field name="name">Keys</field> + <field name="res_model">acc.repartition.keys</field> + <field name="view_mode">tree,form</field> + </record> + <record id="acc_keys_repartition_tree" model="ir.ui.view"> + <field name="name">acc.repartition.keys.tree</field> + <field name="model">acc.repartition.keys</field> + <field name="arch" type="xml"> + <tree string="Keys" editable="bottom"> + <field name="date_send"/> + <field name="csv_file"/> + <field name="operation_id"/> + </tree> + </field> + </record> +<!-- </data>--> +</odoo> \ No newline at end of file diff --git a/wizard/__init__.py b/wizard/__init__.py new file mode 100644 index 0000000..cbd8c61 --- /dev/null +++ b/wizard/__init__.py @@ -0,0 +1 @@ +from . import acc_repartition_keys_wizard diff --git a/wizard/acc_repartition_keys_wizard.py b/wizard/acc_repartition_keys_wizard.py new file mode 100644 index 0000000..1d414cc --- /dev/null +++ b/wizard/acc_repartition_keys_wizard.py @@ -0,0 +1,82 @@ +# Copyright 2021- Le Filament (https://le-filament.com) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) +import base64 +from odoo import fields, models +from odoo.exceptions import UserError + +from ..tools.key_file import RepartitionKeyEntryFile + + +class AccRepartitionKeysWizard(models.TransientModel): + _name = "acc.repartition.keys.wizard" + _description = "Clefs de répartition" + + # ------------------------------------------------------ + # Default methods + # ------------------------------------------------------ + def _default_operation_id(self): + return self.env.context.get("active_id") + + # ------------------------------------------------------ + # Fields declaration + # ------------------------------------------------------ + csv_file = fields.Binary("Contenu du fichier CSV") + date_send = fields.Date("Date de l'envoi des clefs", default=None) + operation_id = fields.Many2one( + "acc.operation", "Opération", default=_default_operation_id + ) + + # ------------------------------------------------------ + # SQL Constraints + # ------------------------------------------------------ + + # ------------------------------------------------------ + # Computed fields / Search Fields + # ------------------------------------------------------ + + # ------------------------------------------------------ + # Onchange / Constraints + # ------------------------------------------------------ + + # ------------------------------------------------------ + # CRUD methods (ORM overrides) + # ------------------------------------------------------ + + # ------------------------------------------------------ + # Actions + # ------------------------------------------------------ + def send_imported_file(self): + """ + testing a file, check taht all prm id exist, are in operation and all operation prm are in file + :return: + """ + if self.csv_file: + file = ( + base64.b64decode(self.csv_file) + .decode("utf-8") + .replace("\r", "") + .split("\n") + ) + + counter_list_from_operation = [ + counter.name + for counter in self.env["acc.counter"].search( + [("acc_operation_id.id", "=", self.operation_id.id)] + ) + ] + + entry_file_handler = RepartitionKeyEntryFile( + data=file, operation_counter_list=counter_list_from_operation + ) + + file_check_result = entry_file_handler.check() + + if not file_check_result.get("check"): + raise UserError(file_check_result.get("message")) + + data_to_send = entry_file_handler.data_to_send(agreement_id=self.operation_id.name) + + + # ------------------------------------------------------ + # Business methods + # ------------------------------------------------------ diff --git a/wizard/acc_repartition_keys_wizard_views.xml b/wizard/acc_repartition_keys_wizard_views.xml new file mode 100644 index 0000000..77b2181 --- /dev/null +++ b/wizard/acc_repartition_keys_wizard_views.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <record id="acc_repartition_keys_wizard_form" model="ir.ui.view"> + <field name="name">acc.repartition.keys.wizard.form</field> + <field name="model">acc.repartition.keys.wizard</field> + <field name="arch" type="xml"> + <form string="Création clefs de repartition"> + <header> + <button + class="btn btn-primary" + name="send_imported_file" + type="object" + string="Envoyer a enedis" + /> + </header> + <group name="keys" string="Clefs de repartition" col="2"> + <field name="csv_file"/> + </group> + </form> + </field> + </record> + + <record id="acc_repartition_keys_wizard_action" model="ir.actions.act_window"> + <field name="name">Création clefs de repartition</field> + <field name="type">ir.actions.act_window</field> + <field name="res_model">acc.repartition.keys.wizard</field> + <field name="view_mode">form</field> + <field + name="view_id" + ref="acc_repartition_keys_wizard_form" + /> + <field name="target">new</field> + </record> +</odoo> \ No newline at end of file -- GitLab