wincan2ctrl.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. '''
  2. Met à jour la base controle avec les données d'un chantier Wincan
  3. usage: wincan2ctrl [-c=idchantier] [-i=idinterv] [-m=idcommande] [-n=inspectioname]
  4. Options:
  5. -c Passe le code chantier
  6. -i Passe le numero d'intervention
  7. -m Passe le numero de commande
  8. -n Passe le nom de l'inpection wincan
  9. -h, --help Affiche l'aide
  10. @olivier.massot, mai 2018
  11. '''
  12. import logging
  13. import sys
  14. from docopt import docopt
  15. from path import Path
  16. from core import logconf
  17. from core.db import AccessSqlHelper
  18. from core.pde import ControlesDb, WincanDb, CommunDb, InspectionTronconWincan
  19. from core.sqlformatter import SqlFormatter
  20. logger = logging.getLogger("wincan2ctrl")
  21. logconf.start("wincan2ctrl", logging.DEBUG)
  22. # # POUR TESTER, décommenter les lignes suivantes
  23. # > Lancer le script /resources/test_wincan2ctrl.py pour reinitialiser les données de la base de test
  24. ##-----------------------------------------------
  25. ControlesDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\cg67Parc_data.mdb")
  26. WincanDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\Wincan\parc_2007\DB\PARC_2007.mdb")
  27. CommunDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\Commun_Data.mdb")
  28. logger.handlers = [h for h in logger.handlers if (type(h) == logging.StreamHandler)]
  29. logger.warning("<<<<<<<<<<<<<< Mode TEST >>>>>>>>>>>>>>>>>")
  30. ##-----------------------------------------------
  31. logger.info("Initialisation...")
  32. Sql = SqlFormatter()
  33. sqlHelper = AccessSqlHelper
  34. # Connexion à Controles
  35. controles_db = ControlesDb(autocommit=False)
  36. # Connexion à Wincan
  37. wincan_db = WincanDb(autocommit=False)
  38. # Connexion à CommunDb
  39. commun_db = CommunDb(autocommit=False)
  40. def get_lib(tbl_id, lib_id):
  41. return wincan_db.first(Sql.format("""SELECT LIB_ID, LIB_LIB, TLB_ID
  42. FROM LISTE_LIBELLE_WINCAN
  43. WHERE TLB_ID='{}' AND LIB_ID={}""", tbl_id, lib_id)).LIB_LIB
  44. def get_materiau(wincan_id):
  45. return controles_db.first(Sql.format("""SELECT strMateriauCourt
  46. FROM tblMateriaux
  47. WHERE strWincanId='{}'""", wincan_id)).strMateriauCourt
  48. # Parse les arguments
  49. args = docopt(__doc__, help=False)
  50. chantier_id = args["-c"] if args["-c"] else 0
  51. interv_id = args["-i"] if args["-i"] else 0
  52. commande_id = args["-m"] if args["-m"] else 0
  53. inspname = args["-n"] if args["-n"] else ""
  54. # Demande à l'utilisateur de saisir les informations qui n'ont pas été passées en argument
  55. if not inspname:
  56. # Propose une liste d'inspections possibles
  57. sql = """SELECT SI_InspName, Max(SI_Date) AS DateMax, SI_Spare1, SI_Spare2
  58. FROM SI_T
  59. GROUP BY SI_InspName, SI_Spare1, SI_Spare2
  60. HAVING SI_spare1 Is Null OR Len([SI_spare1])=0
  61. ORDER BY Max(SI_T.SI_Date) DESC
  62. """
  63. candidats = wincan_db.read_all(sql)
  64. print("Veuillez choisir une inspection Wincan à traiter en saisissant son numéro:")
  65. for i, candidat in enumerate(candidats):
  66. print("[{}] - {}".format(i, candidat))
  67. while not inspname:
  68. reponse = input("> ")
  69. try:
  70. inspname = candidats[int(reponse)].SI_InspName
  71. except ValueError:
  72. logger.error("(!) Valeur invalide")
  73. if not chantier_id:
  74. chantier_id = input("Veuillez saisir le code chantier: ")
  75. if not interv_id:
  76. interv_id = input("Veuillez saisir le numero de l'intervention: ")
  77. if not commande_id:
  78. commande_id = input("Veuillez saisir le code de la commande: ")
  79. # Affiche les infos et demande confirmation avant ed lancer le traitement
  80. logger.info("## Traitement de l'inspection Wincan: %s", inspname)
  81. logger.info("Code chantier: %s", inspname)
  82. logger.info("Numero d'intervention: %s", inspname)
  83. logger.info("Numero de commande: %s", inspname)
  84. if input("Voulez-vous continuer? (o/n)") != 'o':
  85. if input("Etes-vous sûr de vouloir annuler l'opération? (o/n)") == 'o':
  86. logger.info("Opération annulée par l'utilisateur")
  87. sys.exit()
  88. 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, Max(SI_T.SI_Operator) AS Equipe, Max(SI_T.SI_Vehicle) AS Mat, Max(SI_T.SI_InspMethod) AS InspMethod, Max(SI_T.SI_ReasonOfInspection) AS MaxDeSI_ReasonOfInspection, Min(S_T.S_SectionPurpose) AS nature, Min(S_T.S_SectionUse) AS Fonction, Min(S_T.S_SectionType) AS Type
  89. FROM S_T INNER JOIN SI_T ON S_T.S_ID = SI_T.SI_Section_ID
  90. GROUP BY SI_T.SI_InspName
  91. HAVING Sum(S_T.S_Sectionlength) Is Not Null AND Max(SI_T.SI_Operator) Is Not Null AND Max(SI_T.SI_Vehicle) Is Not Null AND Max(SI_T.SI_InspMethod) Is Not Null AND SI_InspName='{}'
  92. """.format(inspname)
  93. for inspection in wincan_db.read(sql):
  94. # insère les inspections dans la table tblVideoIntervs de Controles
  95. logger.info("Mise à jour de tblVideoIntervs")
  96. sql = """INSERT INTO tblVideoIntervs ( lngChantierId, bytIntervId, dtmIntervDu, dtmIntervAu, strEquipeId, intlMaterielID, bytCommandeId, lngTroncon, SI_InspMethod, SI_ReasonOfInspection )
  97. SELECT {} AS chantier, {} AS interv, {} AS mindate, {} AS maxdate, {} AS equipe, {} AS mat, {} AS commande, {} AS long_insp, {} AS methode, {} AS reason
  98. """.format(chantier_id, interv_id, inspection.mindate, inspection.maxdate, inspection.Equipe, inspection.Mat, commande_id, inspection.long_insp, inspection.InspMethod, get_lib("SI_REASONOfINSPECTION", inspection.SI_ReasonOfInspection))
  99. controles_db.execute(sql)
  100. # Met a jour les champs SI_Spare1 et SI_Spare2 de la table Wincan pour marquer les lignes comme importées
  101. logger.info("Mise à jour en retour de SI_T")
  102. sql = "update SI_T set SI_Spare1={}, SI_Spare2={} where SI_InspName='{}'".format(chantier_id, interv_id, inspection.SI_InspName)
  103. wincan_db.execute(sql)
  104. # Met a jour la table tbl_so_rate de Controles
  105. logger.info("Traitement des inspections de tronçons")
  106. # Extrait les données des tronçons
  107. 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,
  108. 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,
  109. S_T.S_Sectionlength, S_T.S_SectionPurpose, S_T.S_SectionUse, S_T.S_SectionType, S_T.S_PipeMaterial, S_T.S_YearLayed,
  110. S_T.S_PipeDia, S_T.S_Situation, S_T.S_Spare1, S_T.S_PipeShape, S_T.S_Pipelength, S_T.S_Spare3,
  111. SI_T.SI_Spare0 AS Test_ecoulement, SI_T.SI_Date
  112. FROM S_T INNER JOIN SI_T ON S_T.S_ID = SI_T.SI_Section_ID
  113. """
  114. for data in wincan_db.read(sql):
  115. logger.info("* Traitement de %s (S_ID: %s)", data.SI_InspName, data.S_ID)
  116. inspection = InspectionTronconWincan()
  117. inspection.s_guid = data.S_ID
  118. inspection.si_guid = data.SI_ID
  119. inspection.nom_chantier = data.SI_InspName
  120. inspection.lng_chantier_id = data.SI_Spare1
  121. inspection.byt_interv_id = data.SI_Spare2
  122. inspection.si_autonumber = data.SI_AutoNumber
  123. inspection.classement_troncons = data.SI_MediaNumber1
  124. inspection.nom_troncon = ("{0}-{1}" if data.S_SectionFlow == 2 else "{1}-{0}").format(data.S_StartNode, data.S_EndNode)
  125. inspection.startnode_type = get_lib(data.S_T.S_StartNodeType, "S_StartNodeType")
  126. inspection.endnode_type = get_lib(data.S_T.S_StartNodeType, "S_EndNodeType")
  127. inspection.sens_ecoul = ">>" if data.S_SectionFlow == '1' else ('<<' if data.S_SectionFlow == '2' else '')
  128. inspection.startnode_z = data.S_StartNodeCoord_Z
  129. inspection.endnode_z = data.S_EndNodeCoord_Z
  130. inspection.section_length = data.S_Sectionlength
  131. inspection.section_purpose = data.S_SectionPurpose
  132. inspection.section_use = data.S_SectionUse
  133. inspection.section_type = data.S_SectionType
  134. inspection.materiau = get_materiau(data.S_PipeMaterial)
  135. inspection.annee_pose = data.S_YearLayed
  136. inspection.diametre = get_lib(data.S_PipeDia, "S_PipeDia")
  137. inspection.route = get_lib(data.S_Situation, "S_Situation")
  138. inspection.n_route = data.S_Spare1
  139. inspection.pipe_shape = data.S_PipeShape
  140. inspection.pipe_length = data.S_Pipelength
  141. inspection.arbres = get_lib(data.S_Spare3, "S_Spare3")
  142. inspection.test_ecoulement = data.SI_Spare0
  143. inspection.si_date = data.SI_Date
  144. sql = """ SELECT SO_T.SO_ID, SO_T.SO_Rate, SO_T.SO_Photonumber1, SO_T.SO_Photonumber2
  145. FROM SO_T
  146. WHERE SO_T.SO_Inspecs_ID='{}'
  147. """.format(data.SI_ID)
  148. # Parcours les opérations réalisées au cours de l'inspection du tronçon
  149. for opdata in wincan_db.read(sql):
  150. inspection.nb_ops += 1
  151. if opdata.SO_Rate == 1:
  152. inspection.rate_1 += 1
  153. elif opdata.SO_Rate == 2:
  154. inspection.rate_2 += 1
  155. elif opdata.SO_Rate == 3:
  156. inspection.rate_3 += 1
  157. elif opdata.SO_Rate == 4:
  158. inspection.rate_4 += 1
  159. elif opdata.SO_Rate == 5:
  160. inspection.rate_5 += 1
  161. elif opdata.SO_Rate >= 6:
  162. logger.error("Attention: une valeur de [SO_Rate] supérieure à 5 a été enregistrée (SO_ID: %s)", opdata.SO_ID)
  163. if opdata.SO_Photonumber1:
  164. inspection.cpt_photos += 1
  165. if opdata.SO_Photonumber2:
  166. inspection.cpt_photos += 1
  167. logger.info("\t- Mise à jour de tblso_Rate_Analyse")
  168. sql = """INSERT INTO tblso_Rate_Analyse (
  169. lngChantierId, bytIntervId, SI_InspName, SI_AutoNumber,
  170. [Classement tronons], Nom_troncon, S_StartNodeType, Sens_ecoul, S_EndNodeType,
  171. S_PipeShape, MateriauCourt, SI_Date, nb_Arbres, ANNEE_POSE,
  172. Route, NRoute, Test_ecoulement, MaxDeS_StartNodeCoord_Z, MaxDeS_EndNodeCoord_Z,
  173. MaxDeS_Sectionlength, MaxDeS_Pipelength, MaxDeDiametre, cpt_Photos, [Total de SO_ID],
  174. 1, 2, 3, 4, 5
  175. )
  176. VALUES ({inspection.lng_chantier_id}, {inspection.byt_interv_id}, {inspection.nom_chantier}, {inspection.si_autonumber},
  177. {inspection.classement_troncons}, {inspection.nom_troncon}, {inspection.startnode_type}, {inspection.sens_ecoul}, {inspection.endnode_type},
  178. {inspection.pipe_shape}, {inspection.materiau}, {inspection.si_date}, {inspection.arbres}, {inspection.annee_pose},
  179. {inspection.route}, {inspection.n_route}, {inspection.test_ecoulement}, {inspection.startnode_z}, {inspection.endnode_z},
  180. {inspection.section_length}, {inspection.pipe_length}, {inspection.diametre}, {inspection.nb_photos}, {inspection.nb_ops},
  181. {inspection.rate_1}, {inspection.rate_2}, {inspection.rate_3}, {inspection.rate_4}, {inspection.rate_5}
  182. )
  183. """.format(inspection)
  184. controles_db.execute(sql)
  185. # Met à jour tblvideointervs.strResGlobal avec le resultat global
  186. # 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
  187. logger.info("\t- Mise à jour du resultat global dans tblvideointervs")
  188. sql = """UPDATE tblvideointervs
  189. SET strResGlobal='{}'
  190. WHERE lngChantierId= {} AND bytIntervId= {}
  191. """.format('-' if (inspection.rate_1 or inspection.rate_2 or inspection.rate_3) else '+',
  192. inspection.lng_chantier_id,
  193. inspection.byt_interv_id)
  194. controles_db.execute(sql)
  195. # Met à jour la table tblVideoBases pour marquer le chantier comme traité
  196. logger.info("\t- Mise à jour de tblVideoBases")
  197. sql = """UPDATE tblVideoBases
  198. SET blnWincan=-1,bytNbInterv={}
  199. WHERE lngChantierId={}
  200. """.format(inspection.byt_interv_id,
  201. inspection.lng_chantier_id)
  202. controles_db.execute(sql)
  203. # Met à jour les données du réseau dans tblChantiers
  204. logger.info("\t- Mise à jour des données du réseau dans tblChantiers")
  205. sql = """UPDATE tblChantiers
  206. SET bytFoncReseauId ={} , bytNatureReseauId={}, bytTypeReseauId={}
  207. WHERE lngChantierId={}
  208. """.format(inspection.section_use,
  209. inspection.section_purpose,
  210. inspection.section_type,
  211. inspection.inspection.lng_chantier_id)
  212. controles_db.execute(sql)
  213. logger.info("Commit des modifications")
  214. controles_db.commit()
  215. wincan_db.commit()