| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637 |
- '''
- 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 '--auto'.
- @author: olivier.massot, févr. 2018
- '''
- from datetime import datetime, timedelta
- import logging
- import sys
- from path import Path # @UnusedImport
- from core import logconf
- from core.pde import ControlesDb, AnalytiqueDb, CommunDb, Affaire, \
- Interv, Tarification
- from core.sqlformatter import SqlFormatter
- logger = logging.getLogger("ctrl2analytique")
- logconf.start("ctrl2analytique", logging.DEBUG)
- # # POUR TESTER, décommenter les lignes suivantes
- # > Lancer le script /resources/test_ctrl2analytique.py pour reinitialiser les données de la base de 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.handlers = [h for h in logger.handlers if (type(h) == logging.StreamHandler)]
- # logger.warning("<<<<<<<<<<<<<< Mode TEST >>>>>>>>>>>>>>>>>")
- ##-----------------------------------------------
- def main():
- # ######### INITIALISATION ##########
- logger.info("Initialisation...")
- Sql = SqlFormatter()
- no_prompt = ("--auto" 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)
- # date zéro pour Access
- date_zero = datetime(1899, 12, 30, 0, 0, 0)
- 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(Sql.format("SELECT [COEFFG] FROM tbl_COEFFG WHERE [ANNEE] = {}", annee)).COEFFG / 100
- # ########## IMPORT DES AFFAIRES ##########
- # Parcourt les chantiers de contrôle pour lesquels aucune affaire n'a été créée
- 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))
- """
- affaires = []
- 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 if data.strdevis else 0
- affaire.intTypeContrat = 1
- affaire.strCT = '1'
- affaire.strTypeId = get_type_id(data.lngChantierId, data.bytCommandeId)
- affaire.intCoefFG = get_coeff_k(data.lngChantierId)
- affaire.strSituation = "En cours"
- # pour garder le lien avec la donnée d'origine:
- affaire.lngChantierId = data.lngChantierId
- affaire.bytCommandeId = data.bytCommandeId
- affaires.append(affaire)
- logger.info("> {} affaires".format(len(affaires)))
- # ########## IMPORT DES INTERVENTIONS DE COMPACTAGE ##########
- # Importe les interventions de contrôle du compactage
- def get_periode_validite(date_interv):
- """ retourne la préiode comptable correspondant à la date de l'intervention """
- if not date_interv:
- return None
- sql = Sql.format("""SELECT intPeriodeValiditeId FROM tblTarifValidite
- WHERE [dtmValiditeDebut] <= {date_interv:date} AND [dtmValiditeFin] > {date_interv:date} AND [bytClasseTarifId]=1
- """, date_interv=date_interv)
- periode = commun_db.first(sql)
- return periode.intPeriodeValiditeId if periode else None
- 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"
- interventions_cc = []
- 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 AS str_materiau_remblai, tblMateriaux_1.strMatériau AS str_materiau_enrobage,
- tblMateriaux_2.strMatériau AS str_materiau_lit, tblCompactageResultats.bytPartChantierId, tblCompactageIntervs.sngIntervIdMos
- FROM ((tblMateriaux RIGHT JOIN ((((tblCompactageIntervs LEFT JOIN tblCompactageEngins ON tblCompactageIntervs.strEquipeId = tblCompactageEngins.strEquipeId)
- INNER JOIN tblCompactageResultats ON (tblCompactageIntervs.lngChantierId = tblCompactageResultats.lngChantierId) AND
- (tblCompactageIntervs.bytIntervId = tblCompactageResultats.bytIntervId)) INNER JOIN tblCompactagePartChantiers ON
- (tblCompactageResultats.lngChantierId = tblCompactagePartChantiers.lngChantierId) AND
- (tblCompactageResultats.bytPartChantierId = tblCompactagePartChantiers.bytPartChantierId))
- 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))
- """
- 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 = get_type_compactage_interv(data.memTravaux)
- interv.strCatégorieInterventionId = "CC"
- interv.dblquantite = 1.0
- interv.strunite = "u"
- interv.dtmIntervention = data.dtmEssai
- interv.dtmDureeIntervention = data.dtmDuree
- interv.dtmDureeInstallation = date_zero # 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 if data.strTrcRegard else "-"
- interv.strgrandeur1 = data.str_materiau_remblai
- interv.strgrandeur2 = data.str_materiau_lit
- interv.strgrandeur3 = data.str_materiau_enrobage
- 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)
- # pour garder le lien avec la donnée d'origine:
- interv.lngChantierId = data.lngChantierId
- interv.bytCommandeId = data.bytCommandeId
- interv.bytIntervId = data.bytIntervId
- interventions_cc.append(interv)
- logger.info("> {} interventions Compactage".format(len(interventions_cc)))
- # ########## IMPORT DES INTERVENTIONS D'ETANCHEITE ##########
- # Importe les interventions de contrôle d'étanchéité
- interventions_ce = []
- 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 = float(data.intNbJoint)
- interv.strunite = "u"
- interv.dtmIntervention = data.dtmEssai
- interv.dtmDureeIntervention = data.dtmDuree
- interv.dtmDureeInstallation = date_zero # 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 if data.strTrcRegard else "-"
- 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)
- # pour garder le lien avec la donnée d'origine:
- interv.lngChantierId = data.lngChantierId
- interv.bytCommandeId = data.bytCommandeId
- interv.bytIntervId = data.bytIntervId
- interventions_ce.append(interv)
- logger.info("> {} interventions Etanchéité".format(len(interventions_ce)))
- # ########## IMPORT DES INTERVENTIONS D'INSPECTION VIDEO ##########
- # Importe les interventions d'inspection vidéo
- interventions_ci = []
- 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 = float(data.sngNbJourFact)
- interv.strunite = "j"
- interv.dtmIntervention = data.dtmIntervDu
- interv.dtmDureeIntervention = data.dtmDuree
- interv.dtmDureeInstallation = date_zero # 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 if data.memObservation else "-"
- 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)
- # pour garder le lien avec la donnée d'origine:
- interv.lngChantierId = data.lngChantierId
- interv.bytCommandeId = data.bytCommandeId
- interv.bytIntervId = data.bytIntervId
- interventions_ci.append(interv)
- logger.info("> {} interventions ITV".format(len(interventions_ci)))
- interventions = interventions_cc + interventions_ce + interventions_ci
- # ########## CONTROLE ET CORRECTION DES DONNEES ##########
- # En cas d'erreurs, on liste celles-ci et on annule l'import.
- errors = []
- logger.info("# Contrôle des données...")
- for affaire in affaires:
- prefix = "Affaire {}: ".format(affaire.strLiaisonControle)
- if not affaire.strMOId:
- errors.append(prefix + "MO manquant")
- else:
- if not commun_db.exists(Sql.format("SELECT [lngTiersId] FROM tblTiers WHERE [lngTiersId]={}", 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(Sql.format("SELECT [lngTiersId] FROM tblTiers WHERE [lngTiersId]={}", 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(Sql.format("SELECT [lngTiersId] FROM tblTiers WHERE [lngTiersId]={}", 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(Sql.format("SELECT [lngTiersId] FROM tblTiers WHERE [lngTiersId]={}", 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:
- if not affaire.intDevisId:
- errors.append(prefix + "Numéro de devis manquant")
- if analytique_db.exists(Sql.format("SELECT dblAffaireId FROM tbl_Affaires WHERE [strLiaisonControle]='{}'", affaire.strLiaisonControle)):
- errors.append(prefix + "Une affaire portant ce code existe déjà: {}".format(affaire.strLiaisonControle))
- for interv in interventions:
- prefix = "Intervention {}: ".format(interv.strTest)
- if not interv.strEquipeId:
- errors.append(prefix + "Equipe manquante")
- else:
- if not analytique_db.exists(Sql.format("SELECT [strEquipesId] FROM tbl_Equipe WHERE [strEquipesId]={:text}", interv.strEquipeId)):
- errors.append(prefix + "L'equipe {} n'existe pas dans tbl_Equipe".format(interv.strEquipeId))
- if not interv.strEnginId:
- errors.append(prefix + "Engin manquant")
- else:
- if not analytique_db.exists(Sql.format("SELECT [strEnginId] FROM tbl_Engin WHERE [strEnginId]={:text}", interv.strEnginId)):
- errors.append(prefix + "L'engin {} n'existe pas dans tbl_Engin".format(interv.strEnginId))
- if not interv.strRapportId:
- errors.append(prefix + "Rapport manquant")
- if not interv.strCatégorieInterventionId:
- errors.append(prefix + "Catégorie de l'intervention manquante")
- else:
- if not analytique_db.exists(Sql.format("SELECT [strCategorieInterventioinId] FROM tbl_CategorieIntervention WHERE [strCategorieInterventioinId]={:text}", interv.strCatégorieInterventionId)):
- errors.append(prefix + "La catégorie d'intervention {} n'existe pas dans tbl_CategorieIntervention".format(interv.strCatégorieInterventionId))
- if not interv.strTypeInterventionId:
- errors.append(prefix + "Type d'intervention manquant")
- else:
- if not analytique_db.exists(Sql.format("SELECT [strTypeInterventionId] FROM tbl_TypeIntervention WHERE [strTypeInterventionId]={:text}", interv.strTypeInterventionId)):
- errors.append(prefix + "Le type d'intervention {} n'existe pas dans tbl_TypeIntervention".format(interv.strTypeInterventionId))
- if not interv.dblquantite:
- errors.append(prefix + "Quantité nulle")
- if not interv.strunite:
- errors.append(prefix + "Unité non renseignée")
- else:
- if not commun_db.exists(Sql.format("SELECT [strUniteCourt] FROM tblUnite WHERE [strUniteCourt]={:text}", interv.strunite)):
- errors.append(prefix + "L'unité {} n'existe pas dans tblUnite".format(interv.strunite))
- if not interv.dtmIntervention:
- errors.append(prefix + "Erreur : date d'intervention")
- if not interv.dtmDureeIntervention or interv.dtmDureeIntervention == date_zero:
- errors.append(prefix + "Durée d'intervention nulle")
- # *** 6- Interruption si erreurs
- if errors:
- logging.error("<!> Des erreurs ont été détectées dans les données à importer. <!>")
- for msg in errors:
- logging.error(msg)
- if no_prompt or input(">> Voulez-vous continuer le traitement malgré tout? (o/n)") != 'o':
- logger.info("# Annulation de l'import")
- return
- else:
- logging.info("Aucune erreur n'a été détectée dans les données.")
- if not no_prompt:
- input("Appuyez sur Entée pour continuer...")
- # ########## MISE A JOUR DE LA BASE DE DONNEES 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.")
- # 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:
- # insertion dans tbl_Affaires
- sql = Sql.format(""" INSERT INTO tbl_Affaires ( strMOId, strMOeId, strEntrepriseId, strCommneId, strLieux, strTypeId, dtmCommande, Ref,
- blnMarche, dblMarche, intTypeContrat, strCT, strLiaisonControle, blnTarification,
- blnAnalyse, strSituation, intCoefFG )
- VALUES ({affaire.strMOId:text}, {affaire.strMOeId:text}, {affaire.strEntrepriseId:text}, {affaire.strCommneId:text}, {affaire.strLieux:text}, {affaire.strTypeId:text},
- {affaire.dtmCommande:date}, {affaire.Ref:text}, {affaire.blnMarche}, {affaire.dblMarche}, {affaire.intTypeContrat}, {affaire.strCT:text},
- {affaire.strLiaisonControle:text}, True, False, {affaire.strSituation:text}, {affaire.intCoefFG})
- """, affaire=affaire)
- analytique_db.execute(sql)
- logger.info("> Ajout de l'affaire: {}".format(affaire.strLiaisonControle))
- # On insère les interventions dans tbl_Intervention
- for interv in interventions:
- affaire = analytique_db.first(Sql.format("SELECT TOP 1 DblAffaireId FROM tbl_Affaires WHERE [strLiaisonControle]='{}'", interv.LienAff))
- if not affaire:
- logger.error("Intervention {} : Impossible de trouver l'affaire {}".format(interv.strTest, interv.LienAff))
- continue
- interv.dblAffaireId = affaire.DblAffaireId
- if not interv.intPeriode:
- interv.intPeriode = get_periode_validite(data.dtmIntervDu) # Si la date d'interv manquait avant la validation, la periode n'a pa été mise à jour
- sql = Sql.format("""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, dtmImportation, strTest )
- VALUES ({interv.dblAffaireId}, {interv.strEquipeId:text}, {interv.strEnginId:text}, {interv.strRapportId:text}, {interv.strCatégorieInterventionId:text},
- {interv.strTypeInterventionId:text}, {interv.dblquantite}, {interv.strunite:text}, {interv.dtmIntervention:date}, {interv.dtmDureeIntervention:date}, {date_zero:date},
- {interv.strcaracteristique1:text}, {interv.strgrandeur1:text}, {interv.strunite1:text}, {interv.strcaracteristique2:text},
- {interv.strgrandeur2:text}, {interv.strunite2:text}, {interv.strcaracteristique3:text}, {interv.strgrandeur3:text}, {interv.strunite3:text},
- {interv.strLiaisonControle:text}, {interv.strArticleId:text}, {interv.intPeriode}, True, False, False, {interv.remarques:text},
- False, {interv.dtmImportation:date}, {interv.strTest:text})
- """, interv=interv, date_zero=date_zero)
- analytique_db.execute(sql)
- logger.info("> Ajout de l'intervention: {}".format(interv.strTest))
- # Calcul de la tarification et ajout à tbl_Tarification
- # > On va créer une ligne de tarification pour chaque groupe d'interventions
- # > partageant le même lngRapportid et strArticleId (cad le même engin)
- for strRapportId, strArticleId in set([(interv.strRapportId, interv.strArticleId) for interv in interventions]):
- tarif = Tarification()
- tarif.intervs = [interv for interv in interventions if interv.strRapportId == strRapportId and interv.strArticleId == strArticleId]
- # recupere le prix unitaire de l'engin
- tarif_engin = commun_db.first(Sql.format("""SELECT dblPU FROM tblTarif WHERE [strArticleId]={:text} AND [intPeriodeValiditeId]={}
- """, strArticleId, get_periode_validite(interventions[0].dtmIntervention)))
- if not tarif_engin:
- logger.error("Aucun tarif trouvé dans tblTarif pour l'article {}, periode {}".format(strArticleId, tarif.intervs[0].intPeriode))
- prix_unitaire = tarif_engin.dblPU
- # recupere le taux de tva applicable à l'engin
- taux_tva = commun_db.first(Sql.format("""SELECT tblTVATaux.dblTVATaux FROM tblArticle INNER JOIN tblTVATaux ON tblArticle.bytTVAArticleId = tblTVATaux.bytTVAId
- WHERE tblArticle.strArticleId={:text};""", strArticleId)).dblTVATaux
- tarif.DblAffaireId = tarif.intervs[0].dblAffaireId
- tarif.strRapportId = strRapportId
- tarif.strArticleId = strArticleId
- tarif.dblQuantite = sum([float(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'
- tarif.strCreateur = 'scriptauto'
- sql = Sql.format(""" INSERT INTO tbl_Tarification ( DblAffaireId, strRapportId, strArticleId, dblQuantite, strUnite, dtmDebut, dtmFin, bytPeriode,
- dblPrixUnitaire, dblPrixTotal, dblTauxTVA, dblPrixTVA, strStatut, strCreateur )
- VALUES ({tarif.DblAffaireId}, {tarif.strRapportId:text}, {tarif.strArticleId:text}, {tarif.dblQuantite}, {tarif.strUnite:text}, {tarif.dtmDebut:date},
- {tarif.dtmFin:date}, {tarif.bytPeriode}, {tarif.dblPrixUnitaire}, {tarif.dblPrixTotal},
- {tarif.dblTauxTVA}, {tarif.dblPrixTVA}, {tarif.strStatut:text}, {tarif.strCreateur:text})
- """, tarif=tarif)
- analytique_db.execute(sql)
- logger.info("> Génération d'une ligne de tarification pour l'affaire {} (rapport {}, article: {})".format(tarif.intervs[0].LienAff, strRapportId, strArticleId))
- # Maj champs MOS
- # Ces champs sont utilisés dans les tables Controles pour savoir si une ligne a déjà été importée
- for affaire in affaires:
- dblAffaireId = analytique_db.first(Sql.format("SELECT TOP 1 DblAffaireId FROM tbl_Affaires WHERE [strLiaisonControle]={:text}", affaire.strLiaisonControle)).DblAffaireId
- sql = Sql.format("""UPDATE tblCommandes SET tblCommandes.sngAffaireIdMos = {DblAffaireId}
- WHERE [lngChantierId]={lngChantierId} AND [bytCommandeId]={bytCommandeId}
- """, DblAffaireId=dblAffaireId, lngChantierId=affaire.lngChantierId, bytCommandeId=affaire.bytCommandeId)
- controles_db.execute(sql)
- for interv in interventions:
- if interv.strCatégorieInterventionId == "CC":
- tbl = "tblCompactageIntervs"
- elif interv.strCatégorieInterventionId == "CE":
- tbl = "tblEtancheiteIntervs"
- elif interv.strCatégorieInterventionId == "CI":
- tbl = "tblVideoIntervs"
- else:
- continue
- sql = Sql.format("""UPDATE {tbl} SET {tbl}.sngIntervIdMos = {DblAffaireId}
- WHERE [lngChantierId]={lngChantierId} AND [bytCommandeId]={bytCommandeId} AND [bytIntervId]={bytIntervId}
- """, tbl=tbl,
- DblAffaireId=interv.dblAffaireId,
- lngChantierId=interv.lngChantierId,
- bytCommandeId=interv.bytCommandeId,
- bytIntervId=interv.bytIntervId)
- controles_db.execute(sql)
- logger.info("> Mise à jour des champs MOS")
- # On commit les modifications
- logger.info("Commit des modifications...")
- analytique_db.commit()
- controles_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.
- # > pour des raisons de performances, on ne commence le traitement qu'à partir de l'année N-1
- logger.info("Mise à jour des temps d'installation...")
- # On parcourt les interventions.
- # Lorsque le temps d'intervention total d'une même équipe un même jour est inférieur à 8h,
- # On affecte la différence de temps à la première intervention en tant que 'temps d'installation'
- sql = Sql.format("""SELECT First(tbl_Intervention.dblInterventionId) AS dblInterventionId, tbl_Intervention.strEquipeId,
- tbl_Intervention.dtmIntervention, CDate(Sum(tbl_Intervention.dtmDureeIntervention)) AS SD
- FROM tbl_Intervention
- WHERE tbl_Intervention.strLiaisonControle Like '%/%'
- AND Year([dtmIntervention])>={}
- AND tbl_Intervention.dtmDureeIntervention > 0
- AND tbl_Intervention.strEquipeId Is Not Null
- GROUP BY tbl_Intervention.strEquipeId, tbl_Intervention.dtmIntervention
- HAVING (((CDate(Sum(tbl_Intervention.dtmDureeIntervention)))<#1899/12/30 8:0:0#))
- """, datetime.now().year - 1)
- for interv in analytique_db.read_all(sql):
- tps_install = (date_zero + timedelta(hours=8) - interv.SD)
- sql = Sql.format("""UPDATE tbl_Intervention SET dtmDureeInstallation = #{}#
- WHERE dblInterventionId={}""", date_zero + tps_install, interv.dblInterventionId)
- analytique_db.execute(sql)
- logger.debug("* Mise à jour du temps d'installation de l'intervention {}".format(interv.dblInterventionId))
- logger.info("Commit des modifications...")
- analytique_db.commit()
- if __name__ == "__main__":
- main()
- logger.info("-- Fin --")
|