''' 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 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") ##----------------------------------------------- # *** 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) # Make the working directory 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): _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): # 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) # on insère les affaires depuis tblCommandes et tblChantier (le lien est strLiaisonControle) 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): 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" with open(affaires_file, 'a') as f: f.write(affaire.to_csv()) # *** 2- Import des interventions de contrôle du compactage dans le fichier intervs.csv class Interv(Model): _FIELDS = ["strEquipeId", "strEnginId", "strRapportId", "strTypeInterventionId", "strTypeInterventionId", "strCatégorieInterventionId", "dblquantite", "strunite", "dtmIntervention", "dtmDureeIntervention", "dtmDureeInstallation", "strLiaisonControle", "strArticleId", "remarques", "strgrandeur1", "strgrandeur2", "strgrandeur3", "strcaracteristique1", "strcaracteristique2", "strcaracteristique3", "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) 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): 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 # TODO: Contrôler si l'engin existe dans tbl_Engin 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 recalculés en fin de traitement interv.strLiaisonControle = "{}/{}/{}".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId) interv.strArticleId = data.strEnginId 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.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) with open(intervs_file, 'a') as f: f.write(interv.to_csv()) # *** 3- Import des interventions de contrôle d'étanchéité dans le fichier intervs.csv 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.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.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) with open(intervs_file, 'a') as f: f.write(interv.to_csv()) # *** 4- Import des interventions d'inspection vidéo dans le fichier intervs.csv 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.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.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) with open(intervs_file, 'a') as f: f.write(interv.to_csv()) # *** 5- Mises à jours et contrôles des erreurs