Ver código fonte

Script ctrl2analytique terminé (pas testé)

olivier.massot 7 anos atrás
pai
commit
0061540ccb
2 arquivos alterados com 103 adições e 45 exclusões
  1. 15 0
      core/model.py
  2. 88 45
      ctrl2analytique.py

+ 15 - 0
core/model.py

@@ -3,8 +3,11 @@
 
     @author: olivier.massot, févr. 2018
 '''
+import logging
 
 
+logger = logging.getLogger("model")
+
 class Model():
     """ Modèle de données d'un objet """
     _FIELDS = []
@@ -36,3 +39,15 @@ class Model():
         """ Retourne un objet Facture à partir d'une ligne de texte au format CSV
         Séparateur = tabulation (car c'est un caractère interdit dans Access) """
         return cls.from_dict(dict(zip(cls._FIELDS, line.split("\t"))))
+
+    def dump(self, path):
+        """ Ajoute les données du modèle au format CSV dans le fichier spécifié en paramètre.
+        Créé le fichier s'il n'existe pas, avec une ligne d'en-tête """
+        if not path.exists():
+            logger.debug("Génère le fichier %s", path)
+            firstline = "\t".join(self._FIELDS + ["\n"])
+            with open(path, 'w+') as f:
+                f.write(firstline)
+
+        with open(path, 'a') as f:
+            f.write(self.to_csv())

+ 88 - 45
ctrl2analytique.py

@@ -31,7 +31,7 @@ CommunDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\Commun_Data.mdb")
 
 ##-----------------------------------------------
 
-# *** Initialisation
+# #########    INITIALISATION    ##########
 logger.info("Initialisation...")
 
 no_prompt = ("-n" in sys.argv)
@@ -47,14 +47,11 @@ controles_db = ControlesDb(autocommit=False)
 # Connexion à CommunDb
 commun_db = CommunDb(autocommit=False)
 
-# Make the working directory
+# Créé le répertoire de travail
 workdir = mk_workdir("ctrl2analytique")
 affaires_file = workdir / "affaires.csv"
 intervs_file = workdir / "intervs.csv"
 
-errors = []
-
-
 # > Supprime les fichiers d'import s'il existent
 for file in (affaires_file, intervs_file):
     if file.exists():
@@ -62,6 +59,7 @@ for file in (affaires_file, intervs_file):
         file.remove()
 
 class Affaire(Model):
+    """ Modèle de données d'une affaire Analytique """
     _FIELDS = ["strLiaisonControle", "strMOeId", "strCommneId", "strLieux",
                "strEntrepriseId", "strMOId", "dtmCommande", "Ref", "blnMarche",
                "dblMarche", "intDevisId", "strCT", "strTypeId",
@@ -92,24 +90,17 @@ def get_type_id(lngChantierId, bytCommandeId):
         return "ZZ"
 
 def get_coeff_k(lngChantierId):
-
+    """ Récupère le coefficient de calcul des frais généraux (batiments, frais administratifs...Etc.) """
     # On déduit l'année du chantier à partir du code chantier
     annee = "20" + str(lngChantierId)[:2] if len(str(lngChantierId)) == 6 else "200" + str(lngChantierId)[:1]
-
-    # On retrouve dans la table tbl_COEFFG le coefficient correspondant
     return analytique_db.first("SELECT [COEFFG] FROM tbl_COEFFG WHERE [ANNEE] = {}".format(annee)).COEFFG / 100
 
 
-# *** 1- Import des chantiers Contrôles dans le fichier affaires.csv
 
-nb_affaires, nb_intervs = 0, 0
 
-logger.debug("Génère le fichier %s", affaires_file)
-firstline = "\t".join(Affaire._FIELDS + ["\n"])
-with open(affaires_file, 'w+') as f:
-    f.write(firstline)
+# ##########   IMPORT DES AFFAIRES    ##########
 
-# on insère les affaires depuis tblCommandes et tblChantier (le lien est strLiaisonControle)
+# Parcourt les chantiers de contrôle pour lesquels aucune affaire n'a été créée, et les ajoute au fichier affaire.csv
 
 compteur = 0
 sql = """ SELECT tblCommandes.lngChantierId, tblCommandes.bytCommandeId, tblChantiers.strSubdivisionId, tblChantiers.strCollectiviteId as ChantierCollectiviteId, tblChantiers.strLocChantier,
@@ -138,8 +129,8 @@ for data in controles_db.read(sql):
     affaire.intCoefFG = get_coeff_k(data.lngChantierId)
     affaire.strSituation = "En cours"
 
-    with open(affaires_file, 'a') as f:
-        f.write(affaire.to_csv())
+    # Créé la ligne dans le fichier affaires.csv
+    affaire.dump(affaires_file)
 
     # pour garder le lien avec la donnée d'origine:
     affaire.lngChantierId = data.lngChantierId
@@ -149,9 +140,15 @@ for data in controles_db.read(sql):
 
 logger.info("> {} affaires ajoutées à {}".format(compteur, affaires_file))
 
-# *** 2- Import des interventions de contrôle du compactage dans le fichier intervs.csv
+
+
+
+# ########## IMPORT DES INTERVENTIONS DE COMPACTAGE ##########
+
+# Importe les interventions de contrôle du compactage dans le fichier intervs.csv
 
 class Interv(Model):
+    """ Modèle de données d'une intervention de contrôle réseaux """
     _FIELDS = ["strEquipeId", "strEnginId", "strRapportId", "strTypeInterventionId",
                "strTypeInterventionId", "strCatégorieInterventionId", "dblquantite", "strunite", "dtmIntervention",
                "dtmDureeIntervention", "dtmDureeInstallation", "strLiaisonControle", "strArticleId", "intPeriode",
@@ -160,15 +157,12 @@ class Interv(Model):
                "dtmImportation", "strTest", "LienAff"
                ]
 
-logger.debug("Génère le fichier %s", intervs_file)
-firstline = "\t".join(Interv._FIELDS + ["\n"])
-with open(intervs_file, 'w+') as f:
-    f.write(firstline)
-
 def engin_existe(strEnginId):
+    """ retourne True si le code de l'engin existe dans la table tbl_Engin """
     return analytique_db.exists("SELECT strEnginId FROM tbl_Engin WHERE strEnginId='{}'".format(strEnginId))
 
 def get_periode_validite(date_interv):
+    """ retourne la préiode comptable correspondant à la date de l'intervention """
     sql = """SELECT intPeriodeValiditeId FROM tblTarifValidite
             WHERE [dtmValiditeDebut] <= #{date_interv}# AND [dtmValiditeFin] > #{date_interv}# AND [bytClasseTarifId]=1
     """.format(date_interv=date_interv)
@@ -192,6 +186,7 @@ sql = """SELECT tblCompactageIntervs.lngChantierId, tblCompactageIntervs.bytComm
       """
 
 def get_type_compactage_interv(observation):
+    """ retourne le sous-type d'intervention à partir du commentaire associé """
     if "ASSAINISEMENT" or "ASSAINISEMENT" in observation:
         return "CC3"
     elif "CABLE" in observation:
@@ -206,10 +201,6 @@ def get_type_compactage_interv(observation):
 for data in controles_db.read(sql):
     interv = Interv()
 
-    if not engin_existe(data.strEnginId):
-        errors.append("""Intervention compactage {}/{}/{}/{}: l'engin {} n'existe pas"""
-                      .format(data.lngChantierId, data.bytCommandeId, data.bytIntervId, data.bytPartChantierId, data.strEnginId))
-
     interv.strEquipeId = "C{}".format(data.strEquipeId)
     interv.strEnginId = data.strEnginId
     interv.strRapportId = data.strRapportId
@@ -237,14 +228,19 @@ for data in controles_db.read(sql):
     interv.strTest = "{}/{}/{}/{}".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId, data.bytPartChantierId)
     interv.LienAff = "{}/{}".format(data.lngChantierId, data.bytCommandeId)
 
-    with open(intervs_file, 'a') as f:
-        f.write(interv.to_csv())
+    # Créé la ligne dans le fichier intervs.csv
+    interv.dump(intervs_file)
 
     compteur += 1
 
 logger.info("> {} interventions Compactage ajoutées au fichier".format(compteur))
 
-# *** 3- Import des interventions de contrôle d'étanchéité dans le fichier intervs.csv
+
+
+# ########## IMPORT DES INTERVENTIONS D'ETANCHEITE ##########
+
+# Importe les interventions de contrôle d'étanchéité dans le fichier intervs.csv
+
 compteur = 0
 
 sql = """SELECT tblEtancheiteIntervs.lngChantierId, tblEtancheiteIntervs.bytCommandeId, tblEtancheiteIntervs.bytIntervId, tblEtancheiteIntervs.strEquipeId,
@@ -297,14 +293,20 @@ for data in controles_db.read(sql):
     interv.strTest = "{}/{}/{}/{}".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId, data.bytPartChantierId)
     interv.LienAff = "{}/{}".format(data.lngChantierId, data.bytCommandeId)
 
-    with open(intervs_file, 'a') as f:
-        f.write(interv.to_csv())
+    # Créé la ligne dans le fichier intervs.csv
+    interv.dump(intervs_file)
 
     compteur += 1
 
 logger.info("> {} interventions Etanchéité ajoutées au fichier".format(compteur))
 
-# *** 4- Import des interventions d'inspection vidéo dans le fichier intervs.csv
+
+
+# ########## IMPORT DES INTERVENTIONS D'INSPECTION VIDEO ##########
+
+
+# Importe les interventions d'inspection vidéo dans le fichier intervs.csv
+
 compteur = 0
 
 sql = """SELECT tblVideoIntervs.lngChantierId, tblVideoIntervs.bytCommandeId, tblVideoIntervs.bytIntervId, tblVideoIntervs.strEquipeId,
@@ -323,9 +325,6 @@ sql = """SELECT tblVideoIntervs.lngChantierId, tblVideoIntervs.bytCommandeId, tb
 for data in controles_db.read(sql):
     interv = Interv()
 
-
-
-
     interv.strEquipeId = "C{}".format(data.strEquipeId)
     interv.strEnginId = data.strEnginId
     interv.strRapportId = data.lngRapportId
@@ -353,8 +352,8 @@ for data in controles_db.read(sql):
     interv.strTest = "{}/{}/{}/1".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId)
     interv.LienAff = "{}/{}".format(data.lngChantierId, data.bytCommandeId)
 
-    with open(intervs_file, 'a') as f:
-        f.write(interv.to_csv())
+    # Créé la ligne dans le fichier intervs.csv
+    interv.dump(intervs_file)
 
     compteur += 1
 
@@ -365,7 +364,11 @@ logging.info("Les données à importer ont été ajoutées aux fichiers '{}' et
 logging.info("Ces fichiers sont au format CSV (séparateur: tabulation)")
 
 
-# *** 6- Recherche d'erreurs
+
+
+
+# ########## CONTROLE ET CORRECTION DES DONNEES ##########
+
 errors = -1
 
 while errors:
@@ -452,7 +455,11 @@ while errors:
             sys.exit(1)
 
 
-# *** 7- Insertion des données dans les tables Analytique
+
+
+# ########## MISE A JOUR DE LA BASE DE DONNEES ANALYTIQUE ##########
+
+# On charge en mémoire les affaires et les interventions qui leurs sont associées
 
 affaires = {}
 with open(affaires_file) as f:
@@ -472,9 +479,13 @@ with open(intervs_file) as f:
             logger.error("L'intervention {} n'est liée à aucune affaire. Elle ne sera pas importée.".format(interv.strLiaisonControle))
 
 class Tarification(Model):
+    """ Modèle de donnée d'une ligne de tarification """
     _FIELDS = ["DblAffaireId", "strRapportId", "strArticleId", "dblQuantite", "strUnite",
                "dtmDebut", "dtmFin", "bytPeriode", "dblPrixUnitaire", "dblPrixTotal", "strStatut"]
 
+
+# On insère les affaires, interventions dans Analytique, et on génère la ou les lignes de tarification associées
+
 for affaire in affaires.values():
 
     # insertion dans tbl_Affaires
@@ -488,6 +499,7 @@ for affaire in affaires.values():
        """.format(affaire=affaire)
 
     analytique_db.execute(sql)
+    logger.info("> Ajout de l'affaire: {}".format(affaire.strLiaisonControle))
 
     affaire.DblAffaireId = analytique_db.first("SELECT TOP 1 DblAffaireId FROM tbl_Affaires WHERE [strLiaisonControle]='{}'".format(affaire.strLiaisonControle)).DblAffaireId
 
@@ -509,6 +521,9 @@ for affaire in affaires.values():
 
         analytique_db.execute(sql)
 
+        logger.info("> Ajout de l'intervention: {}".format(interv.strLiaisonControle))
+
+
 
     # Calcul de la tarification et ajout à tbl_Tarification
     # > On va créer une ligne de tarification pour chaque engin (cad. pour chaque strArticleId)
@@ -545,9 +560,11 @@ for affaire in affaires.values():
                 """.format(tarif=tarif)
         analytique_db.execute(sql)
 
+        logger.info("> Génération d'une ligne de tarification pour l'article: {}".format(affaire.strLiaisonControle, strArticleId))
+
 
     # Maj champs MOS
-    # (champs utilisés dans les tables Controles pour savoir si une ligne a déjà été importée)
+    # Ces champs sont utilisés dans les tables Controles pour savoir si une ligne a déjà été importée
     sql = """UPDATE tblCommandes SET tblCommandes.sngAffaireIdMos = {DblAffaireId}
             WHERE [lngChantierId]={lngChantierId} AND [bytCommandeId]={bytCommandeId}
             """.format(DblAffaireId=affaire.DblAffaireId,
@@ -562,16 +579,42 @@ for affaire in affaires.values():
                            lngChantierId=affaire.lngChantierId,
                            bytCommandeId=affaire.bytCommandeId)
         analytique_db.execute(sql)
+    logger.info("> Mise à jour des champs MOS")
 
     # On commit les modifications
+    logger.info("Commit des modifications...")
     analytique_db.commit()
 
-    logger.info("> Affaire créée: {}".format(affaire.strLiaisonControle))
-    for interv in affaire.intervs:
-        logger.info("> Intervention créée: {}".format(interv.strLiaisonControle))
 
 
-# Maj des temps d'installation
+# ########## MISE A JOUR DES TEMPS D'INSTALLATION ##########
+
+# > Le temps d'installation est le temps passé par chaque agent en transport, préparation, reporting...etc.
+# > C'est donc le temps de travail théorique, moins le temps d'intervention.
+
+logger.info("Mise à jour des temps d'installation...")
+
+sql = """ SELECT First(tbl_Intervention.dblInterventionId) AS dblInterventionId,
+        tbl_Intervention.strEquipeId, tbl_Intervention.dtmIntervention,
+        Year([dtmIntervention]) AS annee, Sum(tbl_Intervention.dtmDureeIntervention) AS SD,
+        FROM tbl_Intervention
+        WHERE (((tbl_Intervention.strLiaisonControle) Like '*/*'))
+        GROUP BY tbl_Intervention.strEquipeId, Year([dtmIntervention]), tbl_Intervention.dtmIntervention
+        HAVING (((tbl_Intervention.strEquipeId) Is Not Null)
+            AND ((Year([dtmIntervention]))>=Year(Date())-1)
+            AND ((tbl_Intervention.dtmIntervention) Is Not Null)
+            AND ((Sum(tbl_Intervention.dtmDureeIntervention))>0
+            And (Sum(tbl_Intervention.dtmDureeIntervention)) Is Not Null)
+            AND ((Count(tbl_Intervention.dtmDureeIntervention))>0
+            And (Count(tbl_Intervention.dtmDureeIntervention)) Is Not Null))"""
+
+for interv in analytique_db.read(sql):
+    if interv.SD < (8 / 24):
+        tps_install = ((8 / 24) - interv.SD)
+        sql = """UPDATE tbl_Intervention SET tbl_Intervention.dtmDureeInstallation = #{}#
+                 WHERE (((tbl_Intervention.dblInterventionId)={}));""".format(tps_install, interv.dblInterventionId)
+        logger.debug("* Mise à jour du temps d'installation de l'intervention {}".format(interv.dblInterventionId))
 
 
 
+logger.info("# Import terminé")