# -*- coding: utf8 -*- from pyramid.response import Response from pyramid.view import ( view_config, ) from pyramid_mailer import get_mailer from pyramid_mailer.message import Message, Attachment from time import sleep from datetime import * from dateutil.relativedelta import * from ..models.utils import * @view_config(route_name='batch_nuit') def batch_nuit(request): """ Traitement est lancé chaque nuit, sur le serveur du site web, par un cron job : - Execute cron job as : root - Command : wget http://localhost:9180/batch_nuit/JonSn0w - When to execute : 02:00 each day Par sécurité, ce view ne peut être appelé qu'avec un paramètre secret 'JonSn0w' """ # contrôle : paramètre correct ? non, terminer par = request.matchdict['param'] if par != 'JonSn0w': return Response('Erreur : paramètre incorrect') # ----- effacer le log truncate_log(request) # ----- PURGE des données obsolètes insert_log(request, 'PURGE','- Début PURGE DES DONNEES OBSOLETES') TODAY = date.today() # purger tous les 1er du mois if TODAY.day == 1 : # données de + 10 ans until_date = date(TODAY.year - 10, TODAY.month, 1) # purge_mensuelle(request, until_date) # purge_clients(request) # delete_orphan_attached_files(request) # ----- MAJ STATS DELAIS de traitements des dossiers sur 1 an insert_log(request, 'STATS', '- Début MAJ STATS DES PERFORMANCES') datejour = TODAY for i in range(12): update_chantiers_delais(request, datejour) datejour = datejour + relativedelta(months=-1) societes = ['PL', 'ME', 'PE'] datejour = TODAY groupes = ['MAIF', 'AXA', 'X'] for i in range(4): for societe in societes: for groupe in groupes: update_stats_delais(request, societe, datejour.strftime('%Y-%m-%d'), groupe) # recule d'un mois datejour = datejour + relativedelta(months=-1) # ----- RAPPELS DES RENDEZ-VOUS update_rappels(request) # attendre 3 secondes sleep(3) # ----- envoyer les rappels notifier_rappels(request) # ----- ENVOI RAPPORTS di traitement email_rapport(request) return Response('FIN Batch nuit') def notifier_rappels(request): # log : Début ENVOI emails insert_log(request, 'RAPPELS','- Début ENVOI emails') # lire les rappels non encore envoyés rappels = get_email_rappels(request) nbLus = 0 nbEnvoyes = 0 for item in rappels: nbLus += 1 error = 0 if len(item.c_email) == 0 : insert_log(request, 'RAPPELS', '--> email vide : %s-%s - %s %s' % (item.societe, item.nochantier, item.c_qualite, item.c_nom)) else: # RDV ayant une heure date_heure = item.rdv_date.strftime('%d/%m/%Y - %H:%M') szBody = """
Bonjour %s %s,
L’entreprise %s vous rappelle votre prochain rendez-vous, pris d'un commun accord
le %s
%s
%s
%s
En cas d'empêchement, veuillez nous contacter au %s
Veuillez agréer nos sincères salutations.
L'entreprise %s
""" % (item.c_qualite, item.c_nom, item.nom_societe, date_heure, item.c_adr, item.c_adr2, item.c_ville, item.tel, item.nom_societe) error = email_rappels(request, "RAPPEL : rendez-vous le " + date_heure, szBody, [item.c_email,], item.societe) nbEnvoyes += 1 # attendre 3 secondes, envoi de 20 emails par minute sleep(3) # si envoi OK, marquer le rdv comme envoyé ou traité if error == 0: update_email_rappels(request, item.no_id) if nbLus > 0: pc = str(round(nbEnvoyes * 100 / nbLus, 0)) + ' %' else: pc = '0 %' insert_log(request, 'RAPPELS', "- Fin ENVOI emails : %s rdv lus, %s rappels envoyés, soit %s envoyés." % (str(nbLus), str(nbEnvoyes), pc)) return def email_rappels(request, objet, corps, destinataire, societe): # lire la societe soc = get_societes(request, societe) if soc: # expediteur = soc.email_from # seul admin_email peut envoyer des mails avec Office3 expediteur = request.registry.settings['mondumas.admin_email'] else: expediteur = request.registry.settings['mondumas.admin_email'] # envoyer le rappel error = send_mail(request, expediteur, destinataire, "[Ent. Dumas] " + objet, corps) return len(error) def email_rapport(request): NOW = datetime.now() corps = "=============================================
" corps += "Rapport du traitement de nuit du " + NOW.strftime('%d/%m/%Y - %H:%M') + "
" corps += "=============================================
"
# Lire le fichier log
items = get_log(request)
for item in items:
corps += " - " + item.date.strftime('%d/%m/%Y - %H:%M') + " - " + item.proc + " : " + item.msg + "
"
corps += "
=============================================
" expediteur = request.registry.settings['mondumas.admin_email'] destinataire = ["phuoc@caotek.fr","peinture-dumas@entreprise-dumas.com"] send_mail(request, expediteur, destinataire, "[DEV_NUIT] Rapport des traitements de nuit", corps) return def send_mail(request, expediteur, destinataires, objet, corps): body = """ %s """ % (corps) message = Message(subject=objet, sender=expediteur, recipients=destinataires, html=body) mailer = get_mailer(request) msg = '' try: mailer.send_immediately(message) except Exception as e: # Just print(e) is cleaner and more likely what you want, # but if you insist on printing message specifically whenever possible... msg = repr(e)[0:400]) insert_log(request, 'MAILER', "- ERROR : %s, TO : %s" % (msg, destinataires)) return str(msg) @view_config(route_name='batch_test') def batch_test(request): """ Traitement est lancé pour tester des traitements batch URL = /batch_test/Sansa5tark Par sécurité, ce view ne peut être appelé qu'avec un paramètre secret 'Sansa5tark' """ # contrôle : paramètre correct ? non, terminer par = request.matchdict['param'] if par != 'Sansa5tark': return Response('Erreur : paramètre incorrect') TODAY = date.today() # ------ UPDATE statut DEVIS COMMANDE # update_devis_statut_4(request) """ # ----- MAJ STATS DELAIS de traitements des dossiers sur 1 an datejour = TODAY for i in xrange(12): update_chantiers_delais(request, datejour) datejour = datejour + relativedelta(months=-1) """ # données de + 10 ans until_date = date(TODAY.year - 10, TODAY.month, 1) # purge_mensuelle(request, until_date) purge_clients(request) # delete_orphan_attached_files(request) # update_chantiers_delais(request, date(TODAY.year - 1, TODAY.month, 1)) insert_log(request, 'TEST','- Fin -') return Response('TEST OK') def delete_orphan_attached_files(request): """ Ce traitement parcourt le répertoire DOCS_ATTACHES de chacune des 5 sociétés et controle que le dossier sur le filesystem existe dans la BD. S'il n'existe plus, on supprime les fichiers du dossier """ import os import shutil societes = ['CD', 'ME', 'PE', 'PL', 'PO'] for ste in societes: # Scan the directiory of attached files # and get an iterator of os.DirEntry objets path = request.registry.settings['mondumas.devfac_dir'] + '/' + ste obj = os.scandir(path) # List all diretories in the specified path nbLus = 0 nbSupp = 0 for entry in obj : if entry.is_dir(): nbLus += 1 # le chantier existe ? if chantierExiste(request,ste, entry.name) == False : # non, supprimer les docs attaches shutil.rmtree(path+ '/' + entry.name) nbSupp += 1 if nbLus > 0: insert_log(request, 'DELETE', '%s : %d Répertoires lues, %d supprimées' % (ste, nbLus, nbSupp)) def update_chantiers_delais(request, date): """ Ce traitement calcul les delais : - delai_contact : le nombre de jours entre la réception de la DD et la création d'un 1er RDV - delai_rdv : le nombre de jours entre la réception de la DD et la date d'un 1er RDV - delai_devis : le nombre de jours entre la réception de la DD et la date d'un 1er devis - delai_facture : le nombre de jours entre la réception de la DD et la date d'une 1ere facture """ societes = ['PE','ME','PL','PO','CD'] for societe in societes: # lire tous les chantiers chantiers = get_chantiers_month(request, societe, date) for item in chantiers: dt_dossier = datetime.combine(item.DATE, datetime.min.time()) # lire les dates 1er contact, 1er rdv, 1er devis, 1er facture du chantiers date_contact, date_rdv, date_devis, date_facture = get_chantiers_dates(request, societe, item.NO_ID) # calculer le delai contact en jours if date_contact == None: delai_contact = 0 else: dt = datetime.combine(date_contact, datetime.min.time()) delai_contact = (dt - dt_dossier).days + 1 # delai négatif, ignorer if delai_contact < 0: delai_contact = 0 # calculer le delai rdv en jours if date_rdv == None: delai_rdv = 0 else: dt = datetime.combine(date_rdv, datetime.min.time()) delai_rdv = (dt - dt_dossier).days + 1 # delai négatif, ignorer if delai_rdv < 0: delai_rdv = 0 # calculer le delai contact en jours if date_devis == None: delai_devis = 0 else: dt = datetime.combine(date_devis, datetime.min.time()) delai_devis = (dt - dt_dossier).days + 1 # delai négatif, ignorer if delai_devis < 0: delai_devis = 0 # calculer le delai facture en jours if date_facture == None: delai_facture = 0 else: dt = datetime.combine(date_facture, datetime.min.time()) delai_facture = (dt - dt_dossier).days + 1 # delai négatif, ignorer if delai_facture < 0: delai_facture = 0 update_chantier_delais(request, societe, item.NO_ID, delai_contact, delai_rdv, delai_devis, delai_facture) def purge_clients(request): # lire tous les clients clients = get_all_clients(request) for client in clients: dern_operation = None # lire le chantier le + récent chantier = get_last_chantier_client(request, client.societe, client.CD_CLI) if chantier: dern_operation = chantier.DATE else: # lire le devis le + récent devis = get_last_devis_client(request, client.societe, client.CD_CLI) if devis: dern_operation = devis.DATE else: # lire le proforma le + récent proforma = get_last_proforma_client(request, client.societe, client.CD_CLI) if proforma: dern_operation = proforma.DATE else: # lire la facture la + récente facture = get_last_facture_client(request, client.societe, client.CD_CLI) if facture: dern_operation = facture.DATE # mémoriser dernière opération update_client_dern_operation(request, client.societe, client.CD_CLI, dern_operation) # supprimer clients ayant aucun dossier delete_client_unused(request) return