Skip to content
Extraits de code Groupes Projets
Valider 5d350e41 rédigé par Julien - Le Filament's avatar Julien - Le Filament
Parcourir les fichiers

16.0 keys

parent f9d75649
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -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:
......
from . import models
from . import wizard
......@@ -11,8 +11,10 @@
# 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,
......
# 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__)
......
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
"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
static/description/icon.png

8,95 ko

"""
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": ""}
......@@ -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
<?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
from . import acc_repartition_keys_wizard
# 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
# ------------------------------------------------------
<?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
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter