Skip to content
Extraits de code Groupes Projets
Sélectionner une révision Git
  • faa16a6061718c695ef53057fe0e94fa0e01cff9
  • 16.0 par défaut protégée
  • 16.0-stephane-full-dyn
  • 16.0-perimeter-upd
  • 16.0-refactor-perimeter
5 résultats

key_file.py

Blame
  • key_file.py 5,65 Kio
    """
    Repartion key entry file handler
    """
    import csv
    from datetime import datetime
    
    
    class RepartitionKeyEntryFile:
        def __init__(self, data, file_type="csv"):
            self.data = data
            self.operation_counter_list = None
            self.file_type = file_type
            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):
            """
            Build data { "horodatage": [{"id": "value"}, ....]}
            """
            file_reader = {"csv": self._csv}
            return file_reader.get(self.file_type)()
    
        def _csv(self):
            """
            read data from csv file { "horodatage": [{"id": "value"}, ....]}
            """
            json = {}
            counter_list_from_file = self.data[0].split(";")
            counter_list_from_file.remove("Horodate")
            csv_file = csv.DictReader(self.data, delimiter=";")
            for line in csv_file:
                json[line.get("Horodate")] = []
                for counter in counter_list_from_file:
                    json[line.get("Horodate")].append(
                        {"id": counter, "key": line.get(counter).replace(",", ".")}
                    )
            return json
    
        def get_min_date(self):
            """
            get minimal date from file
            """
    
            return min(self.json)
    
        def get_max_date(self):
            """
            get minimal date from file
            """
    
            return max(self.json)
    
        def data_to_send(self, send_empty_key=True):
            """
            build route and body for api sending
            return dict {"route", "body} to enedis
            """
            call_list = []
            for horo in self.json:
                date = datetime.strptime(horo, "%d-%m-%Y %H:%M")
                timestamp = date.strftime("%Y%m%dT%H%M%SZ")
                body = []
                for key in self.json.get(horo):
                    if send_empty_key:
                        body.append(key)
                    else:
                        if float(key.get("key")) > 0:
                            body.append(key)
    
                if send_empty_key or body:
                    call_list.append({"timestamp": timestamp, "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,
                            f"message": "Les numéros de PRM ne correspondent "
                            f"pas à ceux de l’opération",
                        }
                    return {"check": True, "message": ""}
    
        def _check_max_value(self):
            """
            check if sum of all key is not > 100
            """
            for hour in self.json:
                if self._get_key_sum(self.json.get(hour)) > 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": ""}
    
        def _get_key_sum(self, horo):
            """
            return the sum of key for a horodatage
            [{ "id":id, "key":key}, ...]
    
            """
            keys_sum = 0.0
            for key in horo:
                if key["key"] == "0.00000000":
                    key["key"] = 0.0
                keys_sum = keys_sum + float(key["key"])
    
            return round(keys_sum, 4)