Files
dumas_gestion/mondumas/views/utils.py
2021-06-24 11:15:34 +02:00

368 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- 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')
update_chantiers_delais(request, date(TODAY.year, TODAY.month, 1))
update_chantiers_delais(request, date(TODAY.year, TODAY.month-1, 1))
update_chantiers_delais(request, date(TODAY.year, TODAY.month-2, 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 = """
<html><body>
<p>Bonjour %s %s,</p>
<p>Lentreprise %s vous rappelle votre prochain rendez-vous, pris d'un commun accord</p>
<p>le <b>%s</b><br />
%s<br />
%s<br />
%s<br /><p>
<p>En cas d'empêchement, veuillez nous contacter au <b>%s</b></p>
<p>Veuillez agréer nos sincères salutations.</p>
<p>L'entreprise %s</p></body></html>
""" % (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
else:
expediteur = "peinture@entreprise-dumas.com"
# envoyer le rappel
error = send_mail(request, expediteur, destinataire, "[Ent. Dumas] " + objet, corps)
return error
def email_rapport(request):
NOW = datetime.now()
corps = "<html><body><p>=============================================</p>"
corps += "<p>Rapport du traitement de nuit du " + NOW.strftime('%d/%m/%Y - %H:%M') + "</p>"
corps += "<p>=============================================</p><p></p><p>"
# 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 + "<br />"
corps += "</p><p></p><p>=============================================</p><p></p>"
expediteur = request.registry.settings['mondumas.admin_email']
destinataire = ["phuoc@caotek.fr","peinture@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)
# import pdb;pdb.set_trace()
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...
if hasattr(e, 'message'):
msg = e.message
else:
msg = e
# logguer l'erreur
insert_log(request, 'MAILER', "- ERROR : %s, TO : %s" % (msg, destinataires))
return len(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')
# à revoir
update_chantiers_status(request)
TODAY = date.today()
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_status(request):
"""
Ce traitement parcourt tous les chantiers de chacune des 5 sociétés
pour mettre à jour son STATUS selon l'avancement du chantier.
"""
societes = ['PE','ME','PL','PO','CD']
for ste in societes:
# lire tous les chantiers
chantiers = get_all_chantiers(request, ste)
for item in chantiers:
status = item.STATUS
# si le chantier est annulé, ne rien faire
if status <= 10:
# lire la dernière facture du chantier
facture = get_last_facture(request, ste, item.NO_ID)
if facture :
# remonte le status de la facture ('','Régl part.', 'Réglée')
status = facture.STATUS
else:
# lire le dernier devis du chantier ('','Commandé, 'Facturé')
devis = get_last_devis(request, ste, item.NO_ID)
if devis:
# remonte le status de la facture
status = devis.STATUS
else:
if item.DATEVI:
status = 2
# maj le status du chantier
if status != item.STATUS:
update_chantier_status(request, ste, item.NO_ID, status)
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 la facture la + récente
facture = get_last_facture_client(request, client.societe, client.CD_CLI)
if facture:
dern_operation = facture.DATE
else:
# lire le réglemnet le + récent
payment = get_last_payment_client(request, client.societe, client.CD_CLI)
if payment:
dern_operation = payment.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 chantier le + récent
chantier = get_last_chantier_client(request, client.societe, client.CD_CLI)
if chantier:
dern_operation = chantier.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