''' Génère les affaires dans la base Analytique à partir des données de la base Contrôles. **IMPORTANT**: pour lancer le script sans interaction avec l'utilisateur (par ex, dans le cas d'une tâche planifiée), appeller le script avec l'option '-n'. @author: olivier.massot, févr. 2018 ''' from datetime import datetime import logging import sys from path import Path from core import logconf from core.model import Model from core.pde import ControlesDb, AnalytiqueDb, mk_workdir, CommunDb logger = logging.getLogger("ctrl2analytique") logconf.start("ctrl2analytique", logging.DEBUG) # # POUR TESTER, décommenter les lignes suivantes ##----------------------------------------------- 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") ##----------------------------------------------- # ######### INITIALISATION ########## logger.info("Initialisation...") no_prompt = ("-n" in sys.argv) if no_prompt: logger.info("> Lancé en mode automatique (sans interruption)") # Connexion à Analytique analytique_db = AnalytiqueDb(autocommit=False) # Connexion à Controles controles_db = ControlesDb(autocommit=False) # Connexion à CommunDb commun_db = CommunDb(autocommit=False) # Créé le répertoire de travail workdir = mk_workdir("ctrl2analytique") affaires_file = workdir / "affaires.csv" intervs_file = workdir / "intervs.csv" # > Supprime les fichiers d'import s'il existent for file in (affaires_file, intervs_file): if file.exists(): logger.debug("Supprime le fichier %s", 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", "intCoefFG", "strSituation"] def get_type_id(lngChantierId, bytCommandeId): """ Recupère le type de chantier. 'ZP': Chantier de contrôle d'étanchéité 'ZC': Chantier de contrôle du compactage 'ZI': Chantier d'inspection vidéo 'ZZ': Chantier mixte. '': Inconnu """ sql = """SELECT lngChantierId, 'ZP' as type FROM tblEtancheiteBases WHERE [lngChantierId] = {chantier} AND [bytCommandeId] = {commande} UNION SELECT lngChantierId, 'ZC' as type FROM tblCompactageBases WHERE [lngChantierId] = {chantier} UNION SELECT lngChantierId, 'ZI' as type FROM tblVideoBases WHERE [lngChantierId] = {chantier}; """.format(chantier=lngChantierId, commande=bytCommandeId) res = controles_db.read_all(sql) if len(res) == 0: return "" elif len(res) == 1: return res[0].type else: 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] return analytique_db.first("SELECT [COEFFG] FROM tbl_COEFFG WHERE [ANNEE] = {}".format(annee)).COEFFG / 100 # ########## IMPORT DES AFFAIRES ########## # 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, tblChantiers.strEntrepriseId, tblCommandes.strCollectiviteId as CommandeCollectiviteId, tblCommandes.dtmCommande, tblCommandes.strRefCommande, tblCommandes.blnMarche, tblCommandes.dblMtMarche, tblCommandes.strdevis FROM tblChantiers INNER JOIN tblCommandes ON tblChantiers.lngChantierId = tblCommandes.lngChantierId WHERE (((tblCommandes.sngAffaireIdMos) Is Null Or (tblCommandes.sngAffaireIdMos)=0)) """ for data in controles_db.read(sql): # Création de l'affaire affaire = Affaire() affaire.strLiaisonControle = "{}/{}".format(data.lngChantierId, data.bytCommandeId) affaire.strMOeId = data.strSubdivisionId affaire.strCommneId = data.ChantierCollectiviteId affaire.strLieux = data.strLocChantier affaire.strEntrepriseId = data.strEntrepriseId affaire.strMOId = data.CommandeCollectiviteId affaire.dtmCommande = data.dtmCommande affaire.Ref = data.strRefCommande affaire.blnMarche = data.blnMarche affaire.dblMarche = data.dblMtMarche affaire.intDevisId = data.strdevis affaire.strCT = '1' affaire.strTypeId = get_type_id(data.lngChantierId, data.bytCommandeId) affaire.intCoefFG = get_coeff_k(data.lngChantierId) affaire.strSituation = "En cours" # 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 affaire.bytCommandeId = data.bytCommandeId compteur += 1 logger.info("> {} affaires ajoutées à {}".format(compteur, affaires_file)) # ########## 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", "remarques", "strgrandeur1", "strgrandeur2", "strgrandeur3", "strcaracteristique1", "strcaracteristique2", "strcaracteristique3", "dtmImportation", "strTest", "LienAff" ] 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) return commun_db.first(sql).intPeriodeValiditeId compteur = 0 sql = """SELECT tblCompactageIntervs.lngChantierId, tblCompactageIntervs.bytCommandeId, tblCompactageIntervs.bytIntervId, tblCompactageIntervs.strEquipeId, tblCompactageEngins.strEnginId, tblCompactageIntervs.lngRapportId, tblCompactageBases.memTravaux, tblCompactageResultats.dtmEssai, tblCompactageResultats.dtmDuree, tblCompactagePartChantiers.strTrcRegard, tblMateriaux.strMatériau, tblCompactageResultats.bytPartChantierId, tblCompactageIntervs.sngIntervIdMos FROM ((tblMateriaux RIGHT JOIN ((((tblCompactageIntervs LEFT JOIN tblCompactageEngins ON tblCompactageIntervs.strEquipeId = tblCompactageEngins.strEquipeId) INNER JOIN tblCompactageResultats ON (tblCompactageIntervs.bytIntervId = tblCompactageResultats.bytIntervId) AND (tblCompactageIntervs.lngChantierId = tblCompactageResultats.lngChantierId)) INNER JOIN tblCompactagePartChantiers ON (tblCompactageResultats.bytPartChantierId = tblCompactagePartChantiers.bytPartChantierId) AND (tblCompactageResultats.lngChantierId = tblCompactagePartChantiers.lngChantierId)) INNER JOIN tblCompactageBases ON tblCompactageIntervs.lngChantierId = tblCompactageBases.lngChantierId) ON tblMateriaux.strMateriauId = tblCompactagePartChantiers.strMateriauRemblaiId) LEFT JOIN tblMateriaux AS tblMateriaux_1 ON tblCompactagePartChantiers.strMateriauEnrobageId = tblMateriaux_1.strMateriauId) LEFT JOIN tblMateriaux AS tblMateriaux_2 ON tblCompactagePartChantiers.strMateriauLitId = tblMateriaux_2.strMateriauId WHERE (((tblCompactageIntervs.sngIntervIdMos)=0 Or (tblCompactageIntervs.sngIntervIdMos) Is Null)) """ 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: return "CC1" elif "A.E.P" in observation: return "CC2" elif "GAZ" in observation: return "CC4" else: return "CC3" for data in controles_db.read(sql): interv = Interv() interv.strEquipeId = "C{}".format(data.strEquipeId) interv.strEnginId = data.strEnginId interv.strRapportId = data.strRapportId interv.strTypeInterventionId = get_type_compactage_interv(data.memTravaux) interv.strCatégorieInterventionId = "CC" interv.dblquantite = 1 interv.strunite = "u" interv.dtmIntervention = data.dtmEssai interv.dtmDureeIntervention = data.dtmDuree interv.dtmDureeInstallation = 0 # Les temps d'installation seront calculés en fin de traitement interv.strLiaisonControle = "{}/{}/{}".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId) interv.strArticleId = data.strEnginId interv.intPeriode = get_periode_validite(data.dtmEssai) interv.remarques = data.strTrcRegard interv.strgrandeur1 = data.strMatériau interv.strgrandeur2 = data.strMatériau interv.strgrandeur3 = data.strMatériau interv.strcaracteristique1 = "Matériau remblai" interv.strcaracteristique2 = "Matériau lit de pose" interv.strcaracteristique3 = "Matériau enrobage" interv.strunite1 = "" interv.strunite2 = "" interv.strunite3 = "" interv.dtmImportation = "{}".format(datetime.now().strftime("%Y-%m-%d")) interv.strTest = "{}/{}/{}/{}".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId, data.bytPartChantierId) interv.LienAff = "{}/{}".format(data.lngChantierId, data.bytCommandeId) # Créé la ligne dans le fichier intervs.csv interv.dump(intervs_file) compteur += 1 logger.info("> {} interventions Compactage ajoutées au fichier".format(compteur)) # ########## 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, tblEtancheiteIntervs.lngRapportId, tblEtancheitePartChantiers.bytTypeEssai, tblMateriaux.strMateriauId, tblMateriaux.strMatériau, tblEtancheitePartChantiers.intDiametre, tblEtancheitePartChantiers.sngLgHt, tblEtancheitePartChantiers.intNbJoint, tblEtancheiteResultats.dtmDuree, tblEtancheiteResultats.dtmEssai, tblEtancheitePartChantiers.strTrcRegard, tblEtancheiteResultats.bytPartChantierId FROM ((tblEtancheiteIntervs INNER JOIN tblEtancheiteResultats ON (tblEtancheiteIntervs.lngChantierId = tblEtancheiteResultats.lngChantierId) AND (tblEtancheiteIntervs.bytIntervId = tblEtancheiteResultats.bytIntervId)) INNER JOIN tblEtancheitePartChantiers ON (tblEtancheiteResultats.lngChantierId = tblEtancheitePartChantiers.lngChantierId) AND (tblEtancheiteResultats.bytPartChantierId = tblEtancheitePartChantiers.bytPartChantierId)) INNER JOIN tblMateriaux ON tblEtancheitePartChantiers.strMateriauId = tblMateriaux.strMateriauId WHERE (((tblEtancheiteIntervs.sngIntervIdMos)=0 Or (tblEtancheiteIntervs.sngIntervIdMos) Is Null)); """ def get_engin_etancheite(equipe, diametre, materiau, type_essai): """ retourne l'engin correspondant à l'essai en fonction eds caractéristiques de l'essai """ sql = """SELECT strEnginId FROM tblEtancheiteEngins WHERE ([strEquipeId] = '{}') AND ([intDiametre] = {}) AND ([strMateriauId] = '{}') AND ([bytTypeEssaiId] ={}) """.format(equipe, diametre, materiau, type_essai) row = controles_db.first(sql) return row.strEnginId if row else "" for data in controles_db.read(sql): interv = Interv() interv.strEquipeId = "C{}".format(data.strEquipeId) interv.strEnginId = get_engin_etancheite(data.strEquipeId, data.intDiametre, data.strMateriauId, data.bytTypeEssai) interv.strRapportId = data.lngRapportId interv.strTypeInterventionId = "CE{}".format(data.bytTypeEssai) interv.strCatégorieInterventionId = "CE" interv.dblquantite = data.intNbJoint interv.strunite = "u" interv.dtmIntervention = data.dtmEssai interv.dtmDureeIntervention = data.dtmDuree interv.dtmDureeInstallation = 0 # Les temps d'installation seront recalculés en fin de traitement interv.strLiaisonControle = "{}/{}/{}".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId) interv.strArticleId = interv.strEnginId interv.intPeriode = get_periode_validite(data.dtmEssai) interv.remarques = data.strTrcRegard interv.strgrandeur1 = data.strMatériau interv.strgrandeur2 = data.intDiametre interv.strgrandeur3 = data.sngLgHt interv.strcaracteristique1 = "Matériau" interv.strcaracteristique2 = "Diamètre" interv.strcaracteristique3 = "Longueur" interv.strunite1 = "" interv.strunite2 = "mm" interv.strunite3 = "m" interv.dtmImportation = "{}".format(datetime.now().strftime("%Y-%m-%d")) interv.strTest = "{}/{}/{}/{}".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId, data.bytPartChantierId) interv.LienAff = "{}/{}".format(data.lngChantierId, data.bytCommandeId) # 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)) # ########## 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, tblVideoEngins.strEnginId, tblVideoIntervs.lngRapportId, First(tblso_rate_Analyse.MateriauCourt) AS strmateriau, tblVideoIntervs.lngTroncon, tblVideoIntervs.sngNbJourFact, First(tblso_rate_Analyse.MaxDeDiametre) AS diam, tblVideoIntervs.dtmDuree, tblVideoIntervs.dtmIntervDu, First(tblVideoIntervs.memObservation) AS memObservation, tblChantiers.strEntrepriseId FROM ((tblVideoEngins RIGHT JOIN tblVideoIntervs ON tblVideoEngins.strEquipeId = tblVideoIntervs.strEquipeId) INNER JOIN tblso_rate_Analyse ON (tblVideoIntervs.lngChantierId = tblso_rate_Analyse.lngChantierId) AND (tblVideoIntervs.bytIntervId = tblso_rate_Analyse.bytIntervId)) INNER JOIN tblChantiers ON tblVideoIntervs.lngChantierId = tblChantiers.lngChantierId WHERE (((tblVideoIntervs.sngIntervIdMos) Is Null Or (tblVideoIntervs.sngIntervIdMos)=0)) GROUP BY tblVideoIntervs.lngChantierId, tblVideoIntervs.bytCommandeId, tblVideoIntervs.bytIntervId, tblVideoIntervs.strEquipeId, tblVideoIntervs.lngRapportId, tblVideoIntervs.lngTroncon, tblVideoIntervs.sngNbJourFact, tblVideoIntervs.dtmDuree, tblVideoIntervs.dtmIntervDu, tblVideoEngins.strEnginId, tblChantiers.strEntrepriseId """ for data in controles_db.read(sql): interv = Interv() interv.strEquipeId = "C{}".format(data.strEquipeId) interv.strEnginId = data.strEnginId interv.strRapportId = data.lngRapportId interv.strTypeInterventionId = "CI1" if data.strEntrepriseId != 195 else "CI2" interv.strCatégorieInterventionId = "CI" interv.dblquantite = data.sngNbJourFact interv.strunite = "j" interv.dtmIntervention = data.dtmIntervDu interv.dtmDureeIntervention = data.dtmDuree interv.dtmDureeInstallation = 0 # Les temps d'installation seront recalculés en fin de traitement interv.strLiaisonControle = "{}/{}/{}".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId) interv.strArticleId = data.strEnginId interv.intPeriode = get_periode_validite(data.dtmIntervDu) interv.remarques = data.memObservation interv.strgrandeur1 = data.strmateriau interv.strgrandeur2 = data.diam interv.strgrandeur3 = data.lngTroncon interv.strcaracteristique1 = "Matériau" interv.strcaracteristique2 = "Diamètre" interv.strcaracteristique3 = "Longueur inspectée" interv.strunite1 = "" interv.strunite2 = "mm" interv.strunite3 = "m" interv.dtmImportation = "{}".format(datetime.now().strftime("%Y-%m-%d")) interv.strTest = "{}/{}/{}/1".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId) interv.LienAff = "{}/{}".format(data.lngChantierId, data.bytCommandeId) # Créé la ligne dans le fichier intervs.csv interv.dump(intervs_file) compteur += 1 logger.info("> {} interventions ITV ajoutées au fichier".format(compteur)) logging.info("Les données à importer ont été ajoutées aux fichiers '{}' et '{}'".format(affaires_file, intervs_file)) logging.info("Ces fichiers sont au format CSV (séparateur: tabulation)") # ########## CONTROLE ET CORRECTION DES DONNEES ########## errors = -1 while 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)) # *** 6- Interruption pour corection manuelle des données (si nécessaire) if errors: logging.error(" Des erreurs ont été détectées dans les données à importer. ") for msg in errors: logging.error(msg) prompt = "" while prompt != "v": prompt = input(">> Veuillez contrôler les données, puis taper 'v' pour continuer, ou 'q' pour quitter...") if prompt == "q": sys.exit(1) # ########## 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: next(f) # saute la première ligne for line in f: affaire = Affaire.from_csv(line) with open(intervs_file) as f: next(f) # saute la première ligne for line in f: interv = Interv.from_csv(line) try: affaires[interv.LienAff].append(interv) except KeyError: 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 sql = """ INSERT INTO tbl_Affaires ( strMOId, strMOeId, strEntrepriseId, strCommneId, strLieux, strTypeId, dtmCommande, Ref, blnMarche, dblMarche, intTypeContrat, strCT, strAvancement, strLiaisonControle, intDevisId, blnTarification, blnAnalyse, remarques, strSituation, dtmFin, intCoefFG ) VALUES ('{affaire.strMOId}', '{affaire.strMOeId}', '{affaire.strEntrepriseId}', '{affaire.strCommneId}', '{affaire.strLieux}', '{affaire.strTypeId}', #{affaire.dtmCommande}#, '{affaire.Ref}', {affaire.blnMarche}, {affaire.dblMarche}, {affaire.intTypeContrat}, '{affaire.strCT}', '{affaire.strAvancement}', '{affaire.strLiaisonControle}', {affaire.intDevisId},True, {affaire.blnAnalyse}, '{affaire.remarques}', '{affaire.strSituation}', #{affaire.dtmFin}#, {affaire.intCoefFG}) """.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 # insertions des interventions dans tbl_Intervention for interv in affaire.intervs: sql = """INSERT INTO tbl_Intervention ( DblAffaireId, strEquipeId, strEnginId, strRapportId, strCatégorieInterventionId, strTypeInterventionId, dblquantite, strunite, dtmIntervention, dtmDureeIntervention, dtmDureeInstallation, strcaracteristique1, strgrandeur1, strunite1, strcaracteristique2, strgrandeur2, strunite2, strcaracteristique3, strgrandeur3, strunite3, strLiaisonControle, strarticleId, intPeriode, blnTarification, blnAnalyse, blnFacturer, remarques, blnPeriode, dtnPeriodeDebut, dtmImportation, blnVerifFacture, strTest ) VALUES ({dblAffaireId}, '{interv.strEquipeId}', '{interv.strEnginId}', '{interv.strRapportId}', '{interv.strCatégorieInterventionId}', '{interv.strTypeInterventionId}', {interv.dblquantite}, '{interv.strunite}', #{interv.dtmIntervention}#, #{interv.dtmDureeIntervention}#, #{interv.dtmDureeInstallation}#, '{interv.strcaracteristique1}', '{interv.strgrandeur1}', '{interv.strunite1}', '{interv.strcaracteristique2}', '{interv.strgrandeur2}', '{interv.strunite2}', '{interv.strcaracteristique3}', '{interv.strgrandeur3}', '{interv.strunite3}', '{interv.strLiaisonControle}', '{interv.strarticleId}', {interv.intPeriode}, True, {interv.blnAnalyse}, {interv.blnFacturer}, '{interv.remarques}', {interv.blnPeriode},#{interv.dtnPeriodeDebut}#, #{interv.dtmImportation}#, {interv.blnVerifFacture}, '{interv.strTest}') """.format(dblAffaireId=affaire.DblAffaireId, interv=interv) 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) for strArticleId in set([interv.strArticleId for interv in affaires.intervs]): # recupere le prix unitaire de l'engin prix_unitaire = commun_db.first("""SELECT dblPU FROM tblTarif WHERE [strArticleId]='{}' AND [intPeriodeValiditeId]={} """.format(affaire.strArticleId, affaire.intPeriode)).dblPU # recupere le taux de tva applicable à l'engin taux_tva = commun_db.first("""SELECT tblTVATaux.dblTVATaux FROM tblArticle INNER JOIN tblTVATaux ON tblArticle.bytTVAArticleId = tblTVATaux.bytTVAId WHERE (((tblArticle.strArticleId)='{}'));""".format(strArticleId)).dblTVATaux tarif = Tarification() tarif.intervs = [interv for interv in affaires.intervs if interv.strArticleId == strArticleId] tarif.DblAffaireId = affaire.DblAffaireId tarif.strRapportId = tarif.intervs[0].strRapportId tarif.strArticleId = strArticleId tarif.dblQuantite = sum([interv.dblquantite for interv in tarif.intervs]) tarif.strUnite = tarif.intervs[0].strUnite tarif.dtmDebut = min([interv.dtmIntervention for interv in tarif.intervs]) tarif.dtmFin = max([interv.dtmIntervention for interv in tarif.intervs]) tarif.bytPeriode = tarif.intervs[0].intPeriode tarif.dblPrixUnitaire = prix_unitaire tarif.dblPrixTotal = tarif.dblQuantite * tarif.dblPrixUnitaire tarif.dblTauxTVA = taux_tva tarif.dblPrixTVA = tarif.dblPrixTotal * (0.01 * tarif.dblTauxTVA) tarif.strStatut = 'A facturer' sql = """ INSERT INTO tbl_Tarification ( DblAffaireId, strRapportId, strArticleId, dblQuantite, strUnite, dtmDebut, dtmFin, bytPeriode, dblPrixUnitaire, dblPrixTotal, strStatut ) VALUES ({tarif.DblAffaireId}, {tarif.strRapportId}, {tarif.strArticleId}, {tarif.dblQuantite}, {tarif.strUnite}, {tarif.dtmDebut}, {tarif.dtmFin}, {tarif.bytPeriode}, {tarif.dblPrixUnitaire}, {tarif.dblPrixUnitaire}, {tarif.dblPrixTotal}, {tarif.dblTauxTVA}, {tarif.dblPrixTVA}, {tarif.strStatut}) """.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 # 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, lngChantierId=affaire.lngChantierId, bytCommandeId=affaire.bytCommandeId) analytique_db.execute(sql) for tbl in ("tblCompactageIntervs", "tblEtancheiteIntervs", "tblVideoIntervs"): sql = """UPDATE {tbl} SET {tbl}.sngIntervIdMos = {DblAffaireId} WHERE [lngChantierId]={lngChantierId} AND [bytCommandeId]={bytCommandeId} """.format(DblAffaireId=affaire.DblAffaireId, 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() # ########## 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é")