ctrl2analytique.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. '''
  2. Génère les affaires dans la base Analytique à partir des données de la base Contrôles.
  3. **IMPORTANT**: pour lancer le script sans interaction avec l'utilisateur
  4. (par ex, dans le cas d'une tâche planifiée), appeller le script avec l'option '-n'.
  5. @author: olivier.massot, févr. 2018
  6. '''
  7. from datetime import datetime
  8. import logging
  9. import sys
  10. from path import Path
  11. from core import logconf
  12. from core.model import Model
  13. from core.pde import ControlesDb, AnalytiqueDb, mk_workdir
  14. logger = logging.getLogger("ctrl2analytique")
  15. logconf.start("ctrl2analytique", logging.DEBUG)
  16. # # POUR TESTER, décommenter les lignes suivantes
  17. ##-----------------------------------------------
  18. logger.warning("<<<<<<<<<<<<<< Mode TEST >>>>>>>>>>>>>>>>>")
  19. ControlesDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\cg67Parc_data.mdb")
  20. AnalytiqueDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\Db_analytique.mdb")
  21. ##-----------------------------------------------
  22. # *** Initialisation
  23. logger.info("Initialisation...")
  24. no_prompt = ("-n" in sys.argv)
  25. if no_prompt:
  26. logger.info("> Lancé en mode automatique (sans interruption)")
  27. # Connexion à Analytique
  28. analytique_db = AnalytiqueDb(autocommit=False)
  29. # Connexion à Controles
  30. controles_db = ControlesDb(autocommit=False)
  31. # Make the working directory
  32. workdir = mk_workdir("ctrl2analytique")
  33. affaires_file = workdir / "affaires.csv"
  34. intervs_file = workdir / "intervs.csv"
  35. # > Supprime les fichiers d'import s'il existent
  36. for file in (affaires_file, intervs_file):
  37. if file.exists():
  38. logger.debug("Supprime le fichier %s", file)
  39. file.remove()
  40. class Affaire(Model):
  41. _FIELDS = ["strLiaisonControle", "strMOeId", "strCommneId", "strLieux",
  42. "strEntrepriseId", "strMOId", "dtmCommande", "Ref", "blnMarche",
  43. "dblMarche", "intDevisId", "strCT", "strTypeId",
  44. "intCoefFG", "strSituation"]
  45. def get_type_id(lngChantierId, bytCommandeId):
  46. """ Recupère le type de chantier.
  47. 'ZP': Chantier de contrôle d'étanchéité
  48. 'ZC': Chantier de contrôle du compactage
  49. 'ZI': Chantier d'inspection vidéo
  50. 'ZZ': Chantier mixte.
  51. '': Inconnu
  52. """
  53. sql = """SELECT lngChantierId, 'ZP' as type FROM tblEtancheiteBases WHERE [lngChantierId] = {chantier} AND [bytCommandeId] = {commande}
  54. UNION
  55. SELECT lngChantierId, 'ZC' as type FROM tblCompactageBases WHERE [lngChantierId] = {chantier}
  56. UNION
  57. SELECT lngChantierId, 'ZI' as type FROM tblVideoBases WHERE [lngChantierId] = {chantier};
  58. """.format(chantier=lngChantierId,
  59. commande=bytCommandeId)
  60. res = controles_db.read_all(sql)
  61. if len(res) == 0:
  62. return ""
  63. elif len(res) == 1:
  64. return res[0].type
  65. else:
  66. return "ZZ"
  67. def get_coeff_k(lngChantierId):
  68. # On déduit l'année du chantier à partir du code chantier
  69. annee = "20" + str(lngChantierId)[:2] if len(str(lngChantierId)) == 6 else "200" + str(lngChantierId)[:1]
  70. # On retrouve dans la table tbl_COEFFG le coefficient correspondant
  71. return analytique_db.first("SELECT [COEFFG] FROM tbl_COEFFG WHERE [ANNEE] = {}".format(annee)).COEFFG / 100
  72. # *** 1- Import des chantiers Contrôles dans le fichier affaires.csv
  73. nb_affaires, nb_intervs = 0, 0
  74. logger.debug("Génère le fichier %s", affaires_file)
  75. firstline = "\t".join(Affaire._FIELDS + ["\n"])
  76. with open(affaires_file, 'w+') as f:
  77. f.write(firstline)
  78. # on insère les affaires depuis tblCommandes et tblChantier (le lien est strLiaisonControle)
  79. sql = """ SELECT tblCommandes.lngChantierId, tblCommandes.bytCommandeId, tblChantiers.strSubdivisionId, tblChantiers.strCollectiviteId as ChantierCollectiviteId, tblChantiers.strLocChantier,
  80. tblChantiers.strEntrepriseId, tblCommandes.strCollectiviteId as CommandeCollectiviteId, tblCommandes.dtmCommande, tblCommandes.strRefCommande, tblCommandes.blnMarche, tblCommandes.dblMtMarche, tblCommandes.strdevis
  81. FROM tblChantiers INNER JOIN tblCommandes ON tblChantiers.lngChantierId = tblCommandes.lngChantierId
  82. WHERE (((tblCommandes.sngAffaireIdMos) Is Null Or (tblCommandes.sngAffaireIdMos)=0))
  83. """
  84. for data in controles_db.read(sql):
  85. affaire = Affaire()
  86. affaire.strLiaisonControle = "{}/{}".format(data.lngChantierId, data.bytCommandeId)
  87. affaire.strMOeId = data.strSubdivisionId
  88. affaire.strCommneId = data.ChantierCollectiviteId
  89. affaire.strLieux = data.strLocChantier
  90. affaire.strEntrepriseId = data.strEntrepriseId
  91. affaire.strMOId = data.CommandeCollectiviteId
  92. affaire.dtmCommande = data.dtmCommande
  93. affaire.Ref = data.strRefCommande
  94. affaire.blnMarche = data.blnMarche
  95. affaire.dblMarche = data.dblMtMarche
  96. affaire.intDevisId = data.strdevis
  97. affaire.strCT = '1'
  98. affaire.strTypeId = get_type_id(data.lngChantierId, data.bytCommandeId)
  99. affaire.intCoefFG = get_coeff_k(data.lngChantierId)
  100. affaire.strSituation = "En cours"
  101. with open(affaires_file, 'a') as f:
  102. f.write(affaire.to_csv())
  103. # *** 2- Import des interventions de contrôle du compactage dans le fichier intervs.csv
  104. class Interv(Model):
  105. _FIELDS = ["strEquipeId", "strEnginId", "strRapportId", "strTypeInterventionId",
  106. "strTypeInterventionId", "strCatégorieInterventionId", "dblquantite", "strunite", "dtmIntervention",
  107. "dtmDureeIntervention", "dtmDureeInstallation", "strLiaisonControle", "strArticleId",
  108. "remarques", "strgrandeur1", "strgrandeur2", "strgrandeur3",
  109. "strcaracteristique1", "strcaracteristique2", "strcaracteristique3",
  110. "dtmImportation", "strTest", "LienAff"
  111. ]
  112. logger.debug("Génère le fichier %s", intervs_file)
  113. firstline = "\t".join(Interv._FIELDS + ["\n"])
  114. with open(intervs_file, 'w+') as f:
  115. f.write(firstline)
  116. sql = """SELECT tblCompactageIntervs.lngChantierId, tblCompactageIntervs.bytCommandeId, tblCompactageIntervs.bytIntervId, tblCompactageIntervs.strEquipeId,
  117. tblCompactageEngins.strEnginId, tblCompactageIntervs.lngRapportId, tblCompactageBases.memTravaux, tblCompactageResultats.dtmEssai,
  118. tblCompactageResultats.dtmDuree, tblCompactagePartChantiers.strTrcRegard, tblMateriaux.strMatériau,
  119. tblCompactageResultats.bytPartChantierId, tblCompactageIntervs.sngIntervIdMos
  120. FROM ((tblMateriaux RIGHT JOIN ((((tblCompactageIntervs LEFT JOIN tblCompactageEngins ON tblCompactageIntervs.strEquipeId = tblCompactageEngins.strEquipeId)
  121. INNER JOIN tblCompactageResultats ON (tblCompactageIntervs.bytIntervId = tblCompactageResultats.bytIntervId)
  122. AND (tblCompactageIntervs.lngChantierId = tblCompactageResultats.lngChantierId)) INNER JOIN tblCompactagePartChantiers
  123. ON (tblCompactageResultats.bytPartChantierId = tblCompactagePartChantiers.bytPartChantierId)
  124. AND (tblCompactageResultats.lngChantierId = tblCompactagePartChantiers.lngChantierId)) INNER JOIN tblCompactageBases
  125. ON tblCompactageIntervs.lngChantierId = tblCompactageBases.lngChantierId) ON tblMateriaux.strMateriauId = tblCompactagePartChantiers.strMateriauRemblaiId)
  126. LEFT JOIN tblMateriaux AS tblMateriaux_1 ON tblCompactagePartChantiers.strMateriauEnrobageId = tblMateriaux_1.strMateriauId)
  127. LEFT JOIN tblMateriaux AS tblMateriaux_2 ON tblCompactagePartChantiers.strMateriauLitId = tblMateriaux_2.strMateriauId
  128. WHERE (((tblCompactageIntervs.sngIntervIdMos)=0 Or (tblCompactageIntervs.sngIntervIdMos) Is Null))
  129. """
  130. def get_type_compactage_interv(observation):
  131. if "ASSAINISEMENT" or "ASSAINISEMENT" in observation:
  132. return "CC3"
  133. elif "CABLE" in observation:
  134. return "CC1"
  135. elif "A.E.P" in observation:
  136. return "CC2"
  137. elif "GAZ" in observation:
  138. return "CC4"
  139. else:
  140. return "CC3"
  141. for data in controles_db.read(sql):
  142. interv = Interv()
  143. interv.strEquipeId = "C{}".format(data.strEquipeId)
  144. interv.strEnginId = data.strEnginId
  145. # TODO: Contrôler si l'engin existe dans tbl_Engin
  146. interv.strEnginId = data.strEnginId
  147. interv.strRapportId = data.strRapportId
  148. interv.strTypeInterventionId = get_type_compactage_interv(data.memTravaux)
  149. interv.strCatégorieInterventionId = "CC"
  150. interv.dblquantite = 1
  151. interv.strunite = "u"
  152. interv.dtmIntervention = data.dtmEssai
  153. interv.dtmDureeIntervention = data.dtmDuree
  154. interv.dtmDureeInstallation = 0 # Les temps d'installation seront recalculés en fin de traitement
  155. interv.strLiaisonControle = "{}/{}/{}".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId)
  156. interv.strArticleId = data.strEnginId
  157. interv.remarques = data.strTrcRegard
  158. interv.strgrandeur1 = data.strMatériau
  159. interv.strgrandeur2 = data.strMatériau
  160. interv.strgrandeur3 = data.strMatériau
  161. interv.strcaracteristique1 = "Matériau remblai"
  162. interv.strcaracteristique2 = "Matériau lit de pose"
  163. interv.strcaracteristique3 = "Matériau enrobage"
  164. interv.dtmImportation = "{}".format(datetime.now().strftime("%Y-%m-%d"))
  165. interv.strTest = "{}/{}/{}/{}".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId, data.bytPartChantierId)
  166. interv.LienAff = "{}/{}".format(data.lngChantierId, data.bytCommandeId)
  167. with open(intervs_file, 'a') as f:
  168. f.write(interv.to_csv())
  169. # *** 3- Import des interventions de contrôle d'étanchéité dans le fichier intervs.csv
  170. sql = """SELECT tblEtancheiteIntervs.lngChantierId, tblEtancheiteIntervs.bytCommandeId, tblEtancheiteIntervs.bytIntervId, tblEtancheiteIntervs.strEquipeId,
  171. tblEtancheiteIntervs.lngRapportId, tblEtancheitePartChantiers.bytTypeEssai, tblMateriaux.strMateriauId, tblMateriaux.strMatériau,
  172. tblEtancheitePartChantiers.intDiametre, tblEtancheitePartChantiers.sngLgHt, tblEtancheitePartChantiers.intNbJoint, tblEtancheiteResultats.dtmDuree,
  173. tblEtancheiteResultats.dtmEssai, tblEtancheitePartChantiers.strTrcRegard, tblEtancheiteResultats.bytPartChantierId
  174. FROM ((tblEtancheiteIntervs INNER JOIN tblEtancheiteResultats ON (tblEtancheiteIntervs.lngChantierId = tblEtancheiteResultats.lngChantierId)
  175. AND (tblEtancheiteIntervs.bytIntervId = tblEtancheiteResultats.bytIntervId)) INNER JOIN tblEtancheitePartChantiers
  176. ON (tblEtancheiteResultats.lngChantierId = tblEtancheitePartChantiers.lngChantierId)
  177. AND (tblEtancheiteResultats.bytPartChantierId = tblEtancheitePartChantiers.bytPartChantierId)) INNER JOIN tblMateriaux
  178. ON tblEtancheitePartChantiers.strMateriauId = tblMateriaux.strMateriauId
  179. WHERE (((tblEtancheiteIntervs.sngIntervIdMos)=0 Or (tblEtancheiteIntervs.sngIntervIdMos) Is Null));
  180. """
  181. def get_engin_etancheite(equipe, diametre, materiau, type_essai):
  182. """ retourne l'engin correspondant à l'essai en fonction eds caractéristiques de l'essai """
  183. sql = """SELECT strEnginId FROM tblEtancheiteEngins
  184. WHERE ([strEquipeId] = '{}') AND ([intDiametre] = {}) AND ([strMateriauId] = '{}') AND ([bytTypeEssaiId] ={})
  185. """.format(equipe, diametre, materiau, type_essai)
  186. row = controles_db.first(sql)
  187. return row.strEnginId if row else ""
  188. for data in controles_db.read(sql):
  189. interv = Interv()
  190. interv.strEquipeId = "C{}".format(data.strEquipeId)
  191. interv.strEnginId = get_engin_etancheite(data.strEquipeId, data.intDiametre, data.strMateriauId, data.bytTypeEssai)
  192. interv.strRapportId = data.lngRapportId
  193. interv.strTypeInterventionId = "CE{}".format(data.bytTypeEssai)
  194. interv.strCatégorieInterventionId = "CE"
  195. interv.dblquantite = data.intNbJoint
  196. interv.strunite = "u"
  197. interv.dtmIntervention = data.dtmEssai
  198. interv.dtmDureeIntervention = data.dtmDuree
  199. interv.dtmDureeInstallation = 0 # Les temps d'installation seront recalculés en fin de traitement
  200. interv.strLiaisonControle = "{}/{}/{}".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId)
  201. interv.strArticleId = interv.strEnginId
  202. interv.remarques = data.strTrcRegard
  203. interv.strgrandeur1 = data.strMatériau
  204. interv.strgrandeur2 = data.intDiametre
  205. interv.strgrandeur3 = data.sngLgHt
  206. interv.strcaracteristique1 = "Matériau"
  207. interv.strcaracteristique2 = "Diamètre"
  208. interv.strcaracteristique3 = "Longueur"
  209. interv.strunite2 = "mm"
  210. interv.strunite3 = "m"
  211. interv.dtmImportation = "{}".format(datetime.now().strftime("%Y-%m-%d"))
  212. interv.strTest = "{}/{}/{}/{}".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId, data.bytPartChantierId)
  213. interv.LienAff = "{}/{}".format(data.lngChantierId, data.bytCommandeId)
  214. with open(intervs_file, 'a') as f:
  215. f.write(interv.to_csv())
  216. # *** 4- Import des interventions d'inspection vidéo dans le fichier intervs.csv
  217. sql = """SELECT tblVideoIntervs.lngChantierId, tblVideoIntervs.bytCommandeId, tblVideoIntervs.bytIntervId, tblVideoIntervs.strEquipeId,
  218. tblVideoEngins.strEnginId, tblVideoIntervs.lngRapportId, First(tblso_rate_Analyse.MateriauCourt) AS strmateriau, tblVideoIntervs.lngTroncon,
  219. tblVideoIntervs.sngNbJourFact, First(tblso_rate_Analyse.MaxDeDiametre) AS diam, tblVideoIntervs.dtmDuree, tblVideoIntervs.dtmIntervDu,
  220. First(tblVideoIntervs.memObservation) AS memObservation, tblChantiers.strEntrepriseId
  221. FROM ((tblVideoEngins RIGHT JOIN tblVideoIntervs ON tblVideoEngins.strEquipeId = tblVideoIntervs.strEquipeId) INNER JOIN tblso_rate_Analyse ON
  222. (tblVideoIntervs.lngChantierId = tblso_rate_Analyse.lngChantierId) AND (tblVideoIntervs.bytIntervId = tblso_rate_Analyse.bytIntervId)) INNER JOIN
  223. tblChantiers ON tblVideoIntervs.lngChantierId = tblChantiers.lngChantierId
  224. WHERE (((tblVideoIntervs.sngIntervIdMos) Is Null Or (tblVideoIntervs.sngIntervIdMos)=0))
  225. GROUP BY tblVideoIntervs.lngChantierId, tblVideoIntervs.bytCommandeId, tblVideoIntervs.bytIntervId, tblVideoIntervs.strEquipeId,
  226. tblVideoIntervs.lngRapportId, tblVideoIntervs.lngTroncon, tblVideoIntervs.sngNbJourFact, tblVideoIntervs.dtmDuree,
  227. tblVideoIntervs.dtmIntervDu, tblVideoEngins.strEnginId, tblChantiers.strEntrepriseId
  228. """
  229. for data in controles_db.read(sql):
  230. interv = Interv()
  231. interv.strEquipeId = "C{}".format(data.strEquipeId)
  232. interv.strEnginId = data.strEnginId
  233. interv.strRapportId = data.lngRapportId
  234. interv.strTypeInterventionId = "CI1" if data.strEntrepriseId != 195 else "CI2"
  235. interv.strCatégorieInterventionId = "CI"
  236. interv.dblquantite = data.sngNbJourFact
  237. interv.strunite = "j"
  238. interv.dtmIntervention = data.dtmIntervDu
  239. interv.dtmDureeIntervention = data.dtmDuree
  240. interv.dtmDureeInstallation = 0 # Les temps d'installation seront recalculés en fin de traitement
  241. interv.strLiaisonControle = "{}/{}/{}".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId)
  242. interv.strArticleId = data.strEnginId
  243. interv.remarques = data.memObservation
  244. interv.strgrandeur1 = data.strmateriau
  245. interv.strgrandeur2 = data.diam
  246. interv.strgrandeur3 = data.lngTroncon
  247. interv.strcaracteristique1 = "Matériau"
  248. interv.strcaracteristique2 = "Diamètre"
  249. interv.strcaracteristique3 = "Longueur inspectée"
  250. interv.strunite2 = "mm"
  251. interv.strunite3 = "m"
  252. interv.dtmImportation = "{}".format(datetime.now().strftime("%Y-%m-%d"))
  253. interv.strTest = "{}/{}/{}/1".format(data.lngChantierId, data.bytCommandeId, data.bytIntervId)
  254. interv.LienAff = "{}/{}".format(data.lngChantierId, data.bytCommandeId)
  255. with open(intervs_file, 'a') as f:
  256. f.write(interv.to_csv())
  257. # *** 5- Mises à jours et contrôles des erreurs