| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- '''
- Met à jour la base controle avec les données d'un chantier Wincan
- usage: wincan2ctrl [-c <idchantier>] [-i <inspectioname>] [-o]
- Options:
- -c <idchantier> Passe le code chantier
- -i <inspectioname> Passe le nom de l'inpection wincan
- -o Ne demande pas confirmation avant de lancer le traitement
- -h, --help Affiche l'aide
- Attention: Si un des arguments comporte des espaces, pensez à le mettre entre guillemets
- @olivier.massot, mai 2018
- '''
- import logging
- import sys
- from docopt import docopt
- from path import Path
- from core import logconf
- from core.pde import ControlesDb, WincanDb, InspectionTronconWincan, \
- InterventionITV, PiracaDb
- from core.sqlformatter import SqlFormatter
- logger = logging.getLogger("wincan2ctrl")
- logconf.start("wincan2ctrl", logging.DEBUG)
- # # POUR TESTER, décommenter les lignes suivantes
- # > Lancer le script /resources/test_wincan2ctrl.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")
- # WincanDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\Wincan\parc_2007\DB\PARC_2007.mdb")
- # PiracaDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\db_Piraca.mdb")
- # logger.handlers = [h for h in logger.handlers if (type(h) == logging.StreamHandler)]
- # logger.warning("<<<<<<<<<<<<<< Mode TEST >>>>>>>>>>>>>>>>>")
- ##-----------------------------------------------
- def main():
- logger.info("Initialisation...")
- Sql = SqlFormatter()
- # Connexion à Controles
- controles_db = ControlesDb(autocommit=False)
- # Connexion à Wincan
- wincan_db = WincanDb(autocommit=False)
- # Connexion à CommunDb
- piraca_db = PiracaDb(autocommit=False)
- def get_lib(lib_id, tbl_id):
- row = piraca_db.first(Sql.format("""SELECT LIB_ID, LIB_LIB, TLB_ID
- FROM LISTE_LIBELLE_WINCAN
- WHERE TLB_ID='{}' AND LIB_ID='{}'""", tbl_id, lib_id))
- if not row:
- logger.error("Aucun libelle trouvé dans la table LISTE_LIBELLE_WINCAN pour %s, id=%s", tbl_id, lib_id)
- raise KeyError()
- return row.LIB_LIB
- def get_materiau(wincan_id):
- return controles_db.first(Sql.format("""SELECT strMateriauCourt
- FROM tblMateriaux
- WHERE strWincanId='{}'""", wincan_id)).strMateriauCourt
- # Parse les arguments
- args = docopt(__doc__, help=False)
- chantier_id = args["-c"] if args["-c"] else 0
- inspname = args["-i"] if args["-i"] else ""
- # Demande à l'utilisateur de saisir les informations qui n'ont pas été passées en argument
- if not inspname:
- # Propose une liste d'inspections possibles
- sql = """SELECT SI_InspName
- FROM SI_T
- WHERE SI_Spare1 Is Null OR Len([SI_Spare1])=0
- GROUP BY SI_InspName
- """
- candidats = wincan_db.read_all(sql)
- print("Veuillez choisir une inspection Wincan à traiter en saisissant son numéro:")
- for i, candidat in enumerate(candidats):
- print("[{}] - {}".format(i, candidat.SI_InspName))
- while not inspname:
- reponse = input("> ")
- try:
- inspname = candidats[int(reponse)].SI_InspName
- except ValueError:
- print("Valeur invalide!")
- if not chantier_id:
- try:
- default = int(inspname[:6])
- chantier_id = input("Veuillez saisir le code chantier [{}]: ".format(default))
- if not chantier_id:
- chantier_id = default
- except ValueError:
- chantier_id = input("Veuillez saisir le code chantier: ")
- if not chantier_id:
- logger.error("Code chantier invalide")
- return
- # Calcul du numéro d'intervention
- last_interv_id = controles_db.first("SELECT max(bytIntervId) as last_interv_id FROM tblVideoIntervs WHERE lngChantierId={}".format(chantier_id)).last_interv_id
- interv_id = last_interv_id + 1 if last_interv_id else 1
- # Récupération du numéro de commande en cours
- commande_id = controles_db.first("SELECT bytCommandeId FROM tblVideoBases WHERE lngChantierId={}".format(chantier_id)).bytCommandeId
- # Affiche les infos et demande confirmation avant ed lancer le traitement
- logger.info("## Traitement de l'inspection Wincan")
- logger.info("Nom chantier: %s", inspname)
- logger.info("Code chantier: %s", chantier_id)
- logger.info("Numero d'intervention: %s", interv_id)
- logger.info("Numero de commande: %s", commande_id)
- if not args["-o"]:
- if not input("Voulez-vous continuer? (o/n)") == 'o':
- if input("Etes-vous sûr de vouloir annuler l'opération? (o/n)") == 'o':
- logger.info("Opération annulée par l'utilisateur")
- return
- # Recuperation des données de l'intervention
- sql = """SELECT SI_T.SI_InspName, Sum(S_T.S_Sectionlength) AS Long_insp, Min(SI_T.SI_Date) AS mindate, Max(SI_T.SI_Date) AS maxdate,
- First(SI_T.SI_Operator) AS Equipe, First(SI_T.SI_Vehicle) AS Mat, First(SI_T.SI_InspMethod) AS InspMethod,
- First(SI_T.SI_ReasonOfInspection) AS SI_ReasonOfInspection, First(S_T.S_SectionPurpose) AS nature,
- First(S_T.S_SectionUse) AS Fonction, First(S_T.S_SectionType) AS Type
- FROM S_T INNER JOIN SI_T ON S_T.S_ID = SI_T.SI_Section_ID
- WHERE (((SI_T.[SI_InspName])='{}'))
- GROUP BY SI_T.SI_InspName
- HAVING Sum(S_T.S_Sectionlength) Is Not Null AND First(SI_T.SI_Operator) Is Not Null AND First(SI_T.SI_Vehicle) Is Not Null AND First(SI_T.SI_InspMethod) Is Not Null
- """.format(inspname)
- try:
- inspection = next(wincan_db.read(sql))
- except StopIteration:
- logger.error("Aucune inspection trouvée pour le nom '%s'", inspname)
- raise
- # Insère l'inspection dans la table tblVideoIntervs de Controles
- logger.info("Création de l'intervention dans tblVideoIntervs")
- interv = InterventionITV()
- interv.lngChantierId = chantier_id
- interv.bytIntervId = interv_id
- interv.dtmIntervDu = inspection.mindate
- interv.dtmIntervAu = inspection.maxdate
- interv.strEquipeId = inspection.Equipe
- interv.intlMaterielID = inspection.Mat
- interv.bytCommandeId = commande_id
- interv.lngTroncon = inspection.Long_insp
- interv.SI_InspMethod = inspection.InspMethod
- interv.SI_ReasonOfInspection = get_lib(inspection.SI_ReasonOfInspection, "SI_REASONOfINSPECTION")
- sql = Sql.format("""INSERT INTO tblVideoIntervs ( lngChantierId, bytIntervId, dtmIntervDu, dtmIntervAu, strEquipeId,
- intlMaterielID, bytCommandeId, lngTroncon, SI_InspMethod, SI_ReasonOfInspection )
- VALUES ({interv.lngChantierId}, {interv.bytIntervId}, {interv.dtmIntervDu:date}, {interv.dtmIntervAu:date}, {interv.strEquipeId:text},
- {interv.intlMaterielID}, {interv.bytCommandeId}, {interv.lngTroncon}, {interv.SI_InspMethod:text}, {interv.SI_ReasonOfInspection:text})
- """, interv=interv)
- controles_db.execute(sql)
- # Met a jour les champs SI_Spare1 et SI_Spare2 de la table Wincan en retour
- logger.info("Mise à jour en retour de SI_T")
- sql = """UPDATE SI_T
- SET SI_Spare1='{}', SI_Spare2='{}'
- WHERE SI_InspName='{}'
- """.format(chantier_id, interv_id, inspection.SI_InspName)
- wincan_db.execute(sql)
- # Met a jour la table tbl_so_rate de Controles
- logger.info("Traitement des inspections")
- # Extrait les données des tronçons
- sql = """SELECT SI_T.SI_ID, S_T.S_ID, SI_T.SI_InspName, SI_T.SI_Spare1, SI_T.SI_Spare2, SI_T.SI_AutoNumber, SI_T.SI_MediaNumber1, S_T.S_SectionFlow,
- S_T.S_StartNode, S_T.S_EndNode, S_T.S_StartNodeType, S_T.S_EndNodeType, S_T.S_StartNodeCoord_Z, S_T.S_EndNodeCoord_Z,
- S_T.S_Sectionlength, S_T.S_SectionPurpose, S_T.S_SectionUse, S_T.S_SectionType, S_T.S_PipeMaterial, S_T.S_YearLayed,
- S_T.S_PipeDia, S_T.S_Situation, S_T.S_Spare1, S_T.S_PipeShape, S_T.S_Pipelength, S_T.S_Spare3,
- SI_T.SI_Spare0, SI_T.SI_Date
- FROM S_T INNER JOIN SI_T ON S_T.S_ID = SI_T.SI_Section_ID
- WHERE SI_T.SI_Spare1='{}' AND SI_T.SI_Spare2='{}'
- """.format(chantier_id, interv_id)
- for data in wincan_db.read(sql):
- logger.info("* Traitement de %s (S_ID: %s)", data.SI_InspName, data.S_ID)
- inspection = InspectionTronconWincan()
- inspection.s_guid = data.S_ID[2:-1] if (data.S_ID[:2] == "b'" and data.S_ID[-1:] == "'") else data.S_ID
- inspection.si_guid = data.SI_ID[2:-1] if (data.SI_ID[:2] == "b'" and data.SI_ID[-1:] == "'") else data.SI_ID
- inspection.nom_chantier = data.SI_InspName
- inspection.lng_chantier_id = data.SI_Spare1
- inspection.byt_interv_id = data.SI_Spare2
- inspection.si_autonumber = data.SI_AutoNumber
- inspection.classement_troncons = data.SI_MediaNumber1
- inspection.nom_troncon = "{r1}-{r2}".format(r1=data.S_StartNode, r2=data.S_EndNode) if data.S_SectionFlow == '2' else "{r2}-{r1}".format(r1=data.S_StartNode, r2=data.S_EndNode)
- inspection.startnode_type = get_lib(data.S_StartNodeType, "S_StartNodeType")
- inspection.endnode_type = get_lib(data.S_StartNodeType, "S_EndNodeType")
- inspection.sens_ecoul = ">>" if data.S_SectionFlow == '1' else ('<<' if data.S_SectionFlow == '2' else '')
- inspection.startnode_z = data.S_StartNodeCoord_Z
- inspection.endnode_z = data.S_EndNodeCoord_Z
- inspection.section_length = data.S_Sectionlength
- inspection.section_purpose = data.S_SectionPurpose
- inspection.section_use = data.S_SectionUse
- inspection.section_type = data.S_SectionType
- inspection.materiau = get_materiau(data.S_PipeMaterial)
- inspection.annee_pose = data.S_YearLayed
- inspection.diametre = get_lib(int(data.S_PipeDia), "S_PipeDia")
- inspection.route = get_lib(data.S_Situation, "S_Situation")
- inspection.n_route = data.S_Spare1
- inspection.pipe_shape = data.S_PipeShape
- inspection.pipe_length = data.S_Pipelength
- if data.S_Spare3:
- inspection.arbres = get_lib(data.S_Spare3, "S_Spare3")
- inspection.test_ecoulement = data.SI_Spare0
- inspection.si_date = data.SI_Date
- sql = """ SELECT SO_T.SO_ID, SO_T.SO_Rate, SO_T.SO_Photonumber1, SO_T.SO_Photonumber2
- FROM SO_T
- WHERE SO_T.SO_Inspecs_ID='{}'
- """.format(inspection.si_guid)
- # Parcours les opérations réalisées au cours de l'inspection du tronçon
- for opdata in wincan_db.read(sql):
- inspection.nb_ops += 1
- if opdata.SO_Rate == 1:
- inspection.rate_1 = inspection.rate_1 + 1 if inspection.rate_1 else 1
- elif opdata.SO_Rate == 2:
- inspection.rate_2 = inspection.rate_2 + 1 if inspection.rate_2 else 1
- elif opdata.SO_Rate == 3:
- inspection.rate_3 = inspection.rate_3 + 1 if inspection.rate_3 else 1
- elif opdata.SO_Rate == 4:
- inspection.rate_4 = inspection.rate_4 + 1 if inspection.rate_4 else 1
- elif opdata.SO_Rate == 5:
- inspection.rate_5 = inspection.rate_5 + 1 if inspection.rate_5 else 1
- elif not opdata.SO_Rate:
- pass
- elif opdata.SO_Rate >= 6:
- logger.error("Attention: une valeur de [SO_Rate] supérieure à 5 a été enregistrée (SO_ID: %s)", opdata.SO_ID)
- if opdata.SO_Photonumber1:
- inspection.nb_photos += 1
- if opdata.SO_Photonumber2:
- inspection.nb_photos += 1
- if not any([inspection.rate_1, inspection.rate_2, inspection.rate_3, inspection.rate_4, inspection.rate_5]):
- inspection.DG = 'ABS' # Absence de défauts
- elif not any([inspection.rate_1, inspection.rate_2, inspection.rate_3]):
- inspection.DG = 'ACC' # Défauts acceptables
- else:
- inspection.DG = 'INT' # Défauts non-acceptables
- logger.info("\t- Mise à jour de tblso_Rate_Analyse")
- sql = Sql.format("""INSERT INTO tblso_Rate_Analyse (
- lngChantierId, bytIntervId, SI_InspName, SI_AutoNumber,
- [Classement tronons], Nom_troncon, S_StartNodeType,
- Sens_ecoul, S_EndNodeType, S_PipeShape, MateriauCourt,
- SI_Date, nb_Arbres, ANNEE_POSE,
- Route, NRoute, Test_ecoulement, MaxDeS_StartNodeCoord_Z, MaxDeS_EndNodeCoord_Z,
- MaxDeS_Sectionlength, MaxDeS_Pipelength, MaxDeDiametre, cpt_Photos, [Total de SO_ID],
- 1, 2, 3, 4, 5, DG
- )
- VALUES ({inspection.lng_chantier_id}, {inspection.byt_interv_id}, {inspection.nom_chantier:text}, {inspection.si_autonumber},
- {inspection.classement_troncons:text}, {inspection.nom_troncon:text}, {inspection.startnode_type:text},
- {inspection.sens_ecoul:text}, {inspection.endnode_type:text}, {inspection.pipe_shape:text}, {inspection.materiau:text},
- {inspection.si_date:date}, {inspection.arbres:text}, {inspection.annee_pose},
- {inspection.route:text}, {inspection.n_route:text}, {inspection.test_ecoulement:text}, {inspection.startnode_z}, {inspection.endnode_z},
- {inspection.section_length}, {inspection.pipe_length}, {inspection.diametre:text}, {inspection.nb_photos}, {inspection.nb_ops},
- {inspection.rate_1}, {inspection.rate_2}, {inspection.rate_3}, {inspection.rate_4}, {inspection.rate_5}, {inspection.DG:text}
- )
- """, inspection=inspection)
- controles_db.execute(sql)
- # Met à jour tblvideointervs.strResGlobal avec le resultat global
- # le resultat global vaut '-' si un de ces trois champs n'est pas nul: tbl_so_rate.1, tbl_so_rate.2, tbl_so_rate.3
- # >> On peut peut-être rassembler cette partie et l'insertion dans cette table au debut?
- logger.info("\t- Mise à jour du resultat global dans tblVideoIntervs")
- sql = """UPDATE tblVideoIntervs
- SET strResGlobal='{}'
- WHERE lngChantierId= {} AND bytIntervId= {}
- """.format('-' if inspection.DG == 'INT' else '+',
- chantier_id,
- interv_id)
- controles_db.execute(sql)
- # Met à jour la table tblVideoBases pour marquer le chantier comme traité
- logger.info("\t- Mise à jour de tblVideoBases")
- sql = """UPDATE tblVideoBases
- SET blnWincan=True,bytNbInterv={}
- WHERE lngChantierId={}
- """.format(inspection.byt_interv_id,
- inspection.lng_chantier_id)
- controles_db.execute(sql)
- # Met à jour les données du réseau dans tblChantiers
- logger.info("\t- Mise à jour des données du réseau dans tblChantiers")
- sql = """UPDATE tblChantiers
- SET bytFoncReseauId ={} , bytNatureReseauId={}, bytTypeReseauId={}
- WHERE lngChantierId={}
- """.format(inspection.section_use,
- inspection.section_purpose,
- inspection.section_type,
- inspection.lng_chantier_id)
- controles_db.execute(sql)
- logger.info("Commit des modifications")
- controles_db.commit()
- wincan_db.commit()
- if __name__ == "__main__":
- main()
- logger.info("-- Fin --")
|