olivier.massot 7 лет назад
Родитель
Сommit
a8c82ba0b1
3 измененных файлов с 184 добавлено и 191 удалено
  1. 63 0
      core/db.py
  2. 30 75
      core/model.py
  3. 91 116
      ctrl2analytique.py

+ 63 - 0
core/db.py

@@ -123,3 +123,66 @@ class SqlServerDb(CustomDb):
 #     pwd = ""
 #     pwd = ""
 #     def __init__(self, dbpath, **kwargs):
 #     def __init__(self, dbpath, **kwargs):
 #         CustomDb.__init__(self, dbq=dbpath, **kwargs)
 #         CustomDb.__init__(self, dbq=dbpath, **kwargs)
+
+
+### SQL Helpers ###
+class SQLHelper():
+    """ Génère du code sql """
+    @classmethod
+    def _sql_format(cls, val):
+        """ pre-formatte une variable pour injection sql dans une base MS Access """
+        raise NotImplementedError()
+    @classmethod
+    def select(cls, where=""):
+        raise NotImplementedError()
+    @classmethod
+    def update(cls, tblname, data, where):
+        raise NotImplementedError()
+    @classmethod
+    def insert(cls, tblname, data):
+        raise NotImplementedError()
+    @classmethod
+    def delete(cls, tblname, where):
+        raise NotImplementedError()
+
+class AccessSqlHelper(SQLHelper):
+    """ SQL Helper pour MS Access """
+    @classmethod
+    def _sql_format(cls, val):
+        if val is None:
+            return "Null"
+        elif type(val) is int or type(val) is bool:
+            return "{}".format(val)
+        elif type(val) is str:
+            return "'{}'".format(val)
+        elif type(val) is datetime:
+            return "#{:%Y-%m-%d %H:%M:%S}#".format(val)
+        return "{}".format(val)
+
+    @classmethod
+    def select(cls, where=""):
+        sql = "SELECT * FROM {}".format(cls._tblname)
+        if where:
+            sql = "{} WHERE {}".format(sql, where)
+        return sql
+
+    @classmethod
+    def update(cls, tblname, data, where):
+        sql = "UPDATE {} SET {} WHERE {}".format(tblname,
+                                                  ",".join(["{} = {}".format(key, cls._sql_format(data[key])) for key in data]),
+                                                  " AND ".join(["{} = {}".format(key, cls._sql_format(where[key])) for key in where]))
+        return sql
+
+    @classmethod
+    def insert(cls, tblname, data):
+        sql = "INSERT INTO {} ({}) VALUES ({})".format(tblname,
+                                                       ",".join(data.keys()),
+                                                       ",".join([cls._sql_format(data[key]) for key in data]))
+        return sql
+
+    @classmethod
+    def delete(cls, tblname, where):
+        sql = "DELETE * FROM {} WHERE {}".format(tblname,
+                                                 " AND ".join(["{} = {}".format(key, cls._sql_format(where[key])) for key in where]))
+        return sql
+

+ 30 - 75
core/model.py

@@ -3,105 +3,60 @@
 
 
     @author: olivier.massot, févr. 2018
     @author: olivier.massot, févr. 2018
 '''
 '''
-from datetime import datetime
 import logging
 import logging
 
 
-
 logger = logging.getLogger("model")
 logger = logging.getLogger("model")
 
 
-def _sql_format(val):
-    """ pre-formatte une variable pour injection sql dans une base MS Access """
-    if val is None:
-        return "Null"
-    elif type(val) is int or type(val) is bool:
-        return "{}".format(val)
-    elif type(val) is str:
-        return "'{}'".format(val)
-    elif type(val) is datetime:
-        return "#{:%Y-%m-%d %H:%M:%S}#".format(val)
-    return "{}".format(val)
 
 
 class Model():
 class Model():
-    """ Modèle de données d'un objet
+    _mapping = {}
 
 
-    """
-    _cnn = None
-    _tblname = ""
-    _fields = []
-    _identityfields = []
+    @property
+    def _fields(self):
+        return list(self.__dict__.keys())
 
 
-    def __init__(self):
-        """ Génère un objet vide,
-        les propriétés de l'objet sont générées automatiquement à partir de la variable de classe _FIELDS"""
-        for fld in self._identityfields + self._fields:
-            setattr(self, fld, None)
+    @property
+    def data(self):
+        return self.__dict__
 
 
     def __repr__(self):
     def __repr__(self):
-        return "<{} => {}>".format(self.__class__.__name__, ",".join(["{}={}".format(field, getattr(self, field)) for field in self._identityfields + self._fields]))
+        return "<{} => {}>".format(self.__class__.__name__, ",".join(["{}={}".format(field, value) for field, value in self.__dict__.items()]))
 
 
     @classmethod
     @classmethod
     def from_dict(cls, data):
     def from_dict(cls, data):
         """ Retourne un objet à partir d'un dictionnaire de données """
         """ Retourne un objet à partir d'un dictionnaire de données """
-        facture = cls()
+        model = cls()
         for key, value in data.items():
         for key, value in data.items():
-            setattr(facture, key, value)
-        return facture
-
-    ### Fonctions CSV ###
-    def to_csv(self):
-        """ Renvoie une chaine de caractère correspondant aux données de l'objet au format CSV
-        Séparateur = tabulation (car c'est un caractère interdit dans Access) """
-        return "\t".join([str(getattr(self, field)).replace("\t", " ") for field in self._identityfields + self._fields] + ["\n"])
+            setattr(model, key, value)
+        return model
 
 
     @classmethod
     @classmethod
-    def from_csv(cls, line):
-        """ 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._identityfields + cls._fields, line.split("\t"))))
-
-    def dump(self, path):
+    def _map_type(cls, field, value):
+        try:
+            return cls._mapping[field](value)
+        except KeyError:
+            return value
+
+    # Fonctions CSV
+    def dump_to_csv(self, path):
         """ Ajoute les données du modèle au format CSV dans le fichier spécifié en paramètre.
         """ 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 """
         Créé le fichier s'il n'existe pas, avec une ligne d'en-tête """
         if not path.exists():
         if not path.exists():
             logger.debug("Génère le fichier %s", path)
             logger.debug("Génère le fichier %s", path)
-            firstline = "\t".join(self._identityfields + self._fields + ["\n"])
+            firstline = "\t".join(self._fields + ["\n"])
             with open(path, 'w+') as f:
             with open(path, 'w+') as f:
                 f.write(firstline)
                 f.write(firstline)
 
 
         with open(path, 'a') as f:
         with open(path, 'a') as f:
-            f.write(self.to_csv())
-
-    ### Fonctions Access ###
-    @classmethod
-    def select(cls, where=""):
-        sql = "SELECT * FROM {}".format(cls._tblname)
-        if where:
-            sql = "{} WHERE {}".format(sql, where)
-        logger.debug(sql)
-        for row in cls._cnn.read(sql):
-            yield cls.from_dict({f: getattr(row, f) for f in cls._identityfields + cls._fields})
+            f.write("\t".join([str(getattr(self, field)).replace("\t", " ") for field in self._fields] + ["\n"]))
 
 
     @classmethod
     @classmethod
-    def first(cls, where=""):
-        return next(cls.select(where))
-
-    def update(self):
-        sql = "UPDATE {} SET {} WHERE {}".format(self._tblname,
-                                                  ",".join(["{} = {}".format(f, _sql_format(getattr(self, f))) for f in self._fields]),
-                                                  " AND ".join(["{} = {}".format(k, _sql_format(getattr(self, k))) for k in self._identityfields]))
-        logger.debug(sql)
-        self._cnn.execute(sql)
-
-    def insert(self):
-        sql = "INSERT INTO {} ({}) VALUES ({})".format(self._tblname,
-                                                              ",".join(self._fields),
-                                                              ",".join([_sql_format(getattr(self, f)) for f in self._fields]))
-        logger.debug(sql)
-        print(sql)
-        self._cnn.execute(sql)
-
-    def delete(self):
-        sql = "DELETE * FROM {} WHERE {}".format(self._tblname,
-                                                 " AND ".join(["{} = {}".format(k, _sql_format(getattr(self, k))) for k in self._identityfields]))
-        logger.debug(sql)
-        self._cnn.execute(sql)
+    def load_csv(cls, path):
+        """ parcourt les lignes du fichier csv et renvoie chaque ligne sous forme d'un objet Model
+        ATTENTION: chaque propriété dont le type n'est pas précisé dans _mapping aura le type 'string'
+        """
+        with open(path) as f:
+            fields = next(f).split("\t")
+            for line in f:
+                data = {key: cls._map_type(key, value) for key, value in zip(fields, line.split("\t"))}
+                yield(cls.from_dict(data))

+ 91 - 116
ctrl2analytique.py

@@ -15,7 +15,8 @@ import sys
 from path import Path  # @UnusedImport
 from path import Path  # @UnusedImport
 
 
 from core import logconf
 from core import logconf
-from core.model import CsvModel, Model
+from core.db import AccessSqlHelper
+from core.model import Model
 from core.pde import ControlesDb, AnalytiqueDb, mk_workdir, CommunDb
 from core.pde import ControlesDb, AnalytiqueDb, mk_workdir, CommunDb
 
 
 
 
@@ -26,36 +27,14 @@ logconf.start("ctrl2analytique", logging.DEBUG)
 # > Lancer le script /resources/test_ctrl2analytique.py pour reinitialiser les données de la base de test
 # > Lancer le script /resources/test_ctrl2analytique.py pour reinitialiser les données de la base de test
 ##-----------------------------------------------
 ##-----------------------------------------------
 
 
-# logger.warning("<<<<<<<<<<<<<<   Mode TEST   >>>>>>>>>>>>>>>>>")
-# ControlesDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\cg67Parc_data.mdb")
-# AnalytiqueDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\Db_analytique.mdb")
-# CommunDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\Commun_Data.mdb")
+logger.warning("<<<<<<<<<<<<<<   Mode TEST   >>>>>>>>>>>>>>>>>")
+ControlesDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\cg67Parc_data.mdb")
+AnalytiqueDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\Db_analytique.mdb")
+CommunDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\Commun_Data.mdb")
 
 
 ##-----------------------------------------------
 ##-----------------------------------------------
 
 
 
 
-class Affaire(CsvModel):
-    """ Modèle de données d'une affaire Analytique """
-    _FIELDS = ["strLiaisonControle", "strMOeId", "strCommneId", "strLieux",
-               "strEntrepriseId", "strMOId", "dtmCommande", "Ref", "blnMarche",
-               "dblMarche", "intTypeContrat", "strCT", "strTypeId", "intCoefFG", "strSituation",
-               "lngChantierId", "bytCommandeId"]
-
-class Interv(CsvModel):
-    """ Modèle de données d'une intervention de contrôle réseaux """
-    _FIELDS = ["strEquipeId", "strEnginId", "strRapportId", "strTypeInterventionId",
-               "strCatégorieInterventionId", "dblquantite", "strunite", "dtmIntervention",
-               "dtmDureeIntervention", "strLiaisonControle", "strArticleId", "intPeriode",
-               "remarques", "strgrandeur1", "strgrandeur2", "strgrandeur3",
-               "strcaracteristique1", "strcaracteristique2", "strcaracteristique3",
-               "strunite1", "strunite2", "strunite3", "dtmImportation", "strTest", "LienAff",
-               "lngChantierId", "bytCommandeId", "bytIntervId"
-               ]
-
-class Tarification(Model):
-    """ Modèle de donnée d'une ligne de tarification """
-    pass
-
 # #########    INITIALISATION    ##########
 # #########    INITIALISATION    ##########
 logger.info("Initialisation...")
 logger.info("Initialisation...")
 
 
@@ -83,6 +62,21 @@ for file in (affaires_file, intervs_file):
         logger.debug("Supprime le fichier %s", file)
         logger.debug("Supprime le fichier %s", file)
         file.remove()
         file.remove()
 
 
+
+class Affaire(Model):
+    """ Modèle de données d'une affaire Analytique """
+    pass
+
+class Interv(Model):
+    """ Modèle de données d'une intervention de contrôle réseaux """
+    pass
+
+class Tarification(Model):
+    """ Modèle de donnée d'une ligne de tarification """
+    pass
+
+sqlHelper = AccessSqlHelper
+
 def get_type_id(lngChantierId, bytCommandeId):
 def get_type_id(lngChantierId, bytCommandeId):
     """ Recupère le type de chantier.
     """ Recupère le type de chantier.
     'ZP': Chantier de contrôle d'étanchéité
     'ZP': Chantier de contrôle d'étanchéité
@@ -152,7 +146,7 @@ for data in controles_db.read(sql):
     affaire.bytCommandeId = data.bytCommandeId
     affaire.bytCommandeId = data.bytCommandeId
 
 
     # Créé la ligne dans le fichier affaires.csv
     # Créé la ligne dans le fichier affaires.csv
-    affaire.dump(affaires_file)
+    affaire.dump_to_csv(affaires_file)
 
 
     compteur += 1
     compteur += 1
 
 
@@ -243,7 +237,7 @@ for data in controles_db.read(sql):
     interv.bytIntervId = data.bytIntervId
     interv.bytIntervId = data.bytIntervId
 
 
     # Créé la ligne dans le fichier intervs.csv
     # Créé la ligne dans le fichier intervs.csv
-    interv.dump(intervs_file)
+    interv.dump_to_csv(intervs_file)
 
 
     compteur += 1
     compteur += 1
 
 
@@ -313,7 +307,7 @@ for data in controles_db.read(sql):
     interv.bytIntervId = data.bytIntervId
     interv.bytIntervId = data.bytIntervId
 
 
     # Créé la ligne dans le fichier intervs.csv
     # Créé la ligne dans le fichier intervs.csv
-    interv.dump(intervs_file)
+    interv.dump_to_csv(intervs_file)
 
 
     compteur += 1
     compteur += 1
 
 
@@ -377,7 +371,7 @@ for data in controles_db.read(sql):
     interv.bytIntervId = data.bytIntervId
     interv.bytIntervId = data.bytIntervId
 
 
     # Créé la ligne dans le fichier intervs.csv
     # Créé la ligne dans le fichier intervs.csv
-    interv.dump(intervs_file)
+    interv.dump_to_csv(intervs_file)
 
 
     compteur += 1
     compteur += 1
 
 
@@ -398,73 +392,65 @@ errors = -1
 while errors:
 while errors:
     errors = []
     errors = []
 
 
-    with open(affaires_file) as f:
-        next(f)  # saute la première ligne
-
-        for line in f:
-            affaire = Affaire.from_csv(line)
-
-            prefix = "Affaire {}: ".format(affaire.strLiaisonControle)
-            if not affaire.strMOId:
-                errors.append(prefix + "MO manquant")
-            else:
-                if not commun_db.exists("SELECT [lngTiersId] FROM tblTiers WHERE [lngTiersId]={}".format(affaire.strMOId)):
-                    errors.append(prefix + "Le MO {} n'existe pas dans tblTiers".format(affaire.strMOId))
-            if not affaire.strMOeId:
-                errors.append(prefix + "MOe manquant")
-            else:
-                if not commun_db.exists("SELECT [lngTiersId] FROM tblTiers WHERE [lngTiersId]={}".format(affaire.strMOeId)):
-                    errors.append(prefix + "Le MOe {} n'existe pas dans tblTiers".format(affaire.strMOeId))
-            if not affaire.strEntrepriseId:
-                errors.append(prefix + "Entreprise manquante")
-            else:
-                if not commun_db.exists("SELECT [lngTiersId] FROM tblTiers WHERE [lngTiersId]={}".format(affaire.strEntrepriseId)):
-                    errors.append(prefix + "L'entreprise {} n'existe pas dans tblTiers".format(affaire.strEntrepriseId))
-            if not affaire.strCommneId:
-                errors.append(prefix + "Commune manquante")
-            else:
-                if not commun_db.exists("SELECT [lngTiersId] FROM tblTiers WHERE [lngTiersId]={}".format(affaire.strCommneId)):
-                    errors.append(prefix + "La commune {} n'existe pas dans tblTiers".format(affaire.strCommneId))
-            if not affaire.strTypeId:
-                errors.append(prefix + "Type d'affaire manquant")
-            if not affaire.dtmCommande:
-                errors.append(prefix + "Date de commande manquante")
-            if affaire.blnMarche == True and not affaire.intDevisId:
-                errors.append(prefix + "Numéro de devis manquant")
-
-            if analytique_db.exists("SELECT dblAffaireId FROM tbl_Affaires WHERE [strLiaisonControle]='{}'".format(affaire.strLiaisonControle)):
-                errors.append(prefix + "Une affaire portant ce code existe déjà: {}".format(affaire.strLiaisonControle))
-
-    with open(intervs_file) as f:
-        next(f)  # saute la première ligne
-
-        for line in f:
-            interv = Interv.from_csv(line)
-
-            prefix = "Intervention {}: ".format(interv.strLiaisonControle)
-            if not interv.strEquipeId:
-                errors.append(prefix + "Equipe manquante")
-            if not interv.strEnginId:
-                errors.append(prefix + "Engin manquant")
-            if not interv.strRapportId:
-                errors.append(prefix + "Rapport manquant")
-            if not interv.strCatégorieInterventionId:
-                errors.append(prefix + "Catégorie de l'intervention manquante")
-            if not interv.strTypeInterventionId:
-                errors.append(prefix + "Type d'intervention manquant")
-            if not interv.dblquantite:
-                errors.append(prefix + "Quantité nulle")
-            if not interv.strunite:
-                errors.append(prefix + "Unité non renseignée")
-            if not interv.dtmIntervention:
-                errors.append(prefix + "Erreur : date d'intervention")
-            if not interv.dtmDureeIntervention:
-                errors.append(prefix + "Durée d'intervention nulle")
-            if not interv.strunite:
-                errors.append(prefix + "Unité non renseignée")
-
-            if not engin_existe(interv.strEnginId):
-                errors.append(prefix + "l'engin {} n'existe pas".format(interv.strEnginId))
+    for affaire in Affaire.load_csv(affaires_file):
+
+        prefix = "Affaire {}: ".format(affaire.strLiaisonControle)
+        if not affaire.strMOId:
+            errors.append(prefix + "MO manquant")
+        else:
+            if not commun_db.exists("SELECT [lngTiersId] FROM tblTiers WHERE [lngTiersId]={}".format(affaire.strMOId)):
+                errors.append(prefix + "Le MO {} n'existe pas dans tblTiers".format(affaire.strMOId))
+        if not affaire.strMOeId:
+            errors.append(prefix + "MOe manquant")
+        else:
+            if not commun_db.exists("SELECT [lngTiersId] FROM tblTiers WHERE [lngTiersId]={}".format(affaire.strMOeId)):
+                errors.append(prefix + "Le MOe {} n'existe pas dans tblTiers".format(affaire.strMOeId))
+        if not affaire.strEntrepriseId:
+            errors.append(prefix + "Entreprise manquante")
+        else:
+            if not commun_db.exists("SELECT [lngTiersId] FROM tblTiers WHERE [lngTiersId]={}".format(affaire.strEntrepriseId)):
+                errors.append(prefix + "L'entreprise {} n'existe pas dans tblTiers".format(affaire.strEntrepriseId))
+        if not affaire.strCommneId:
+            errors.append(prefix + "Commune manquante")
+        else:
+            if not commun_db.exists("SELECT [lngTiersId] FROM tblTiers WHERE [lngTiersId]={}".format(affaire.strCommneId)):
+                errors.append(prefix + "La commune {} n'existe pas dans tblTiers".format(affaire.strCommneId))
+        if not affaire.strTypeId:
+            errors.append(prefix + "Type d'affaire manquant")
+        if not affaire.dtmCommande:
+            errors.append(prefix + "Date de commande manquante")
+        if affaire.blnMarche == True and not affaire.intDevisId:
+            errors.append(prefix + "Numéro de devis manquant")
+
+        if analytique_db.exists("SELECT dblAffaireId FROM tbl_Affaires WHERE [strLiaisonControle]='{}'".format(affaire.strLiaisonControle)):
+            errors.append(prefix + "Une affaire portant ce code existe déjà: {}".format(affaire.strLiaisonControle))
+
+    for interv in Interv.load_csv(intervs_file):
+
+        prefix = "Intervention {}: ".format(interv.strLiaisonControle)
+        if not interv.strEquipeId:
+            errors.append(prefix + "Equipe manquante")
+        if not interv.strEnginId:
+            errors.append(prefix + "Engin manquant")
+        if not interv.strRapportId:
+            errors.append(prefix + "Rapport manquant")
+        if not interv.strCatégorieInterventionId:
+            errors.append(prefix + "Catégorie de l'intervention manquante")
+        if not interv.strTypeInterventionId:
+            errors.append(prefix + "Type d'intervention manquant")
+        if not interv.dblquantite:
+            errors.append(prefix + "Quantité nulle")
+        if not interv.strunite:
+            errors.append(prefix + "Unité non renseignée")
+        if not interv.dtmIntervention:
+            errors.append(prefix + "Erreur : date d'intervention")
+        if not interv.dtmDureeIntervention:
+            errors.append(prefix + "Durée d'intervention nulle")
+        if not interv.strunite:
+            errors.append(prefix + "Unité non renseignée")
+
+        if not engin_existe(interv.strEnginId):
+            errors.append(prefix + "l'engin {} n'existe pas".format(interv.strEnginId))
 
 
     # *** 6- Interruption pour corection manuelle des données (si nécessaire)
     # *** 6- Interruption pour corection manuelle des données (si nécessaire)
     if errors:
     if errors:
@@ -484,34 +470,21 @@ while errors:
             sys.exit(1)
             sys.exit(1)
 
 
 
 
-
-
 # ########## MISE A JOUR DE LA BASE DE DONNEES ANALYTIQUE ##########
 # ########## MISE A JOUR DE LA BASE DE DONNEES ANALYTIQUE ##########
 
 
 # On charge en mémoire les affaires et les interventions
 # On charge en mémoire les affaires et les interventions
 logger.info("# Mise à jour de la base Analytique")
 logger.info("# Mise à jour de la base Analytique")
 logger.info("> NB: Les modifications ne seront appliquées à la base que si toutes les opérations se déroulent normalement.")
 logger.info("> NB: Les modifications ne seront appliquées à la base que si toutes les opérations se déroulent normalement.")
 
 
-affaires = []
-with open(affaires_file) as f:
-    next(f)  # saute la première ligne
-    for line in f:
-        affaire = Affaire.from_csv(line)
-        affaires.append(affaire)
-
-intervs = []
-with open(intervs_file) as f:
-    next(f)  # saute la première ligne
-    for line in f:
-        interv = Interv.from_csv(line)
-        intervs.append(interv)
-
+affaires = list(Affaire.load_csv(affaires_file))
+intervs = list(Interv.load_csv(intervs_file))
 
 
 # On insère les affaires, interventions dans Analytique, et on génère la ou les lignes de tarification associées
 # 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:
 for affaire in affaires:
 
 
     # insertion dans tbl_Affaires
     # insertion dans tbl_Affaires
+
     sql = """ INSERT INTO tbl_Affaires ( strMOId, strMOeId, strEntrepriseId, strCommneId, strLieux, strTypeId, dtmCommande, Ref,
     sql = """ INSERT INTO tbl_Affaires ( strMOId, strMOeId, strEntrepriseId, strCommneId, strLieux, strTypeId, dtmCommande, Ref,
                                         blnMarche, dblMarche, intTypeContrat, strCT, strLiaisonControle, blnTarification,
                                         blnMarche, dblMarche, intTypeContrat, strCT, strLiaisonControle, blnTarification,
                                         blnAnalyse, strSituation, intCoefFG )
                                         blnAnalyse, strSituation, intCoefFG )
@@ -521,6 +494,7 @@ for affaire in affaires:
        """.format(affaire=affaire)
        """.format(affaire=affaire)
 
 
     analytique_db.execute(sql)
     analytique_db.execute(sql)
+
     logger.info("> Ajout de l'affaire: {}".format(affaire.strLiaisonControle))
     logger.info("> Ajout de l'affaire: {}".format(affaire.strLiaisonControle))
 
 
 
 
@@ -535,11 +509,11 @@ for interv in intervs:
     interv.dblAffaireId = affaire.DblAffaireId
     interv.dblAffaireId = affaire.DblAffaireId
 
 
     sql = """INSERT INTO tbl_Intervention ( DblAffaireId, strEquipeId, strEnginId, strRapportId, strCatégorieInterventionId, strTypeInterventionId,
     sql = """INSERT INTO tbl_Intervention ( DblAffaireId, strEquipeId, strEnginId, strRapportId, strCatégorieInterventionId, strTypeInterventionId,
-              dblquantite, strunite, dtmIntervention, dtmDureeIntervention, strcaracteristique1, strgrandeur1, strunite1,
+              dblquantite, strunite, dtmIntervention, dtmDureeIntervention, dtmDureeInstallation, strcaracteristique1, strgrandeur1, strunite1,
               strcaracteristique2, strgrandeur2, strunite2, strcaracteristique3, strgrandeur3, strunite3, strLiaisonControle, strarticleId,
               strcaracteristique2, strgrandeur2, strunite2, strcaracteristique3, strgrandeur3, strunite3, strLiaisonControle, strarticleId,
               intPeriode, blnTarification, blnAnalyse, blnFacturer, remarques, blnPeriode, dtmImportation, strTest )
               intPeriode, blnTarification, blnAnalyse, blnFacturer, remarques, blnPeriode, dtmImportation, strTest )
       VALUES ({interv.dblAffaireId}, '{interv.strEquipeId}', '{interv.strEnginId}', '{interv.strRapportId}', '{interv.strCatégorieInterventionId}',
       VALUES ({interv.dblAffaireId}, '{interv.strEquipeId}', '{interv.strEnginId}', '{interv.strRapportId}', '{interv.strCatégorieInterventionId}',
-          '{interv.strTypeInterventionId}', {interv.dblquantite}, '{interv.strunite}', #{interv.dtmIntervention}#, #{interv.dtmDureeIntervention}#,
+          '{interv.strTypeInterventionId}', {interv.dblquantite}, '{interv.strunite}', #{interv.dtmIntervention}#, #{interv.dtmDureeIntervention}#, #1899-12-30 00:00:00#,
           '{interv.strcaracteristique1}', '{interv.strgrandeur1}', '{interv.strunite1}', '{interv.strcaracteristique2}',
           '{interv.strcaracteristique1}', '{interv.strgrandeur1}', '{interv.strunite1}', '{interv.strcaracteristique2}',
           '{interv.strgrandeur2}', '{interv.strunite2}', '{interv.strcaracteristique3}', '{interv.strgrandeur3}', '{interv.strunite3}', '{interv.strLiaisonControle}',
           '{interv.strgrandeur2}', '{interv.strunite2}', '{interv.strcaracteristique3}', '{interv.strgrandeur3}', '{interv.strunite3}', '{interv.strLiaisonControle}',
           '{interv.strArticleId}', {interv.intPeriode}, True, False, False, '{interv.remarques}',
           '{interv.strArticleId}', {interv.intPeriode}, True, False, False, '{interv.remarques}',
@@ -663,6 +637,7 @@ for interv in analytique_db.read_all(sql):
     sql = """UPDATE tbl_Intervention SET tbl_Intervention.dtmDureeInstallation = #{}#
     sql = """UPDATE tbl_Intervention SET tbl_Intervention.dtmDureeInstallation = #{}#
              WHERE (((tbl_Intervention.dblInterventionId)={}));""".format(date0 + tps_install, interv.dblInterventionId)
              WHERE (((tbl_Intervention.dblInterventionId)={}));""".format(date0 + tps_install, interv.dblInterventionId)
     analytique_db.execute(sql)
     analytique_db.execute(sql)
+
     logger.debug("* Mise à jour du temps d'installation de l'intervention {}".format(interv.dblInterventionId))
     logger.debug("* Mise à jour du temps d'installation de l'intervention {}".format(interv.dblInterventionId))
 analytique_db.commit()
 analytique_db.commit()