finition générer dossier à partir d'un email

This commit is contained in:
2020-01-13 17:14:17 +01:00
parent 703791fe4d
commit a490992988
10 changed files with 498 additions and 296 deletions

View File

@@ -83,7 +83,7 @@ def dossier_lookup(request):
# construire la liste
for item in chantiers:
d = ('%s-%s' % (societe, item.numero),item.date.strftime('%d-%m-%Y'), item.nomcli, item.chantier, to_euro(item.montant),
item.nosin, item.status)
item.nosin, item.status, item.usermaj)
liste.append(d)
if len(name) == 0 :
@@ -258,7 +258,10 @@ def dossier_edit(request):
if not dossier:
request.session.flash(u"Le dossier no %s est introuvable" % (nodossier), 'danger')
return HTTPFound(location=request.route_url('dossier_lookup'))
# lire table expert
experts = get_experts(request, dossier.CABINET, 0)
if 'form.submitted' in request.params:
new_values = {}
for param, db_value in dossier.items():
@@ -275,6 +278,7 @@ def dossier_edit(request):
'url': url,
'dossier': dossier,
'nodossier': nodossier,
'experts': experts,
}
@view_config(route_name='upload_doc', renderer='../templates/dossier/upload_doc.pt', permission='view')
@@ -533,7 +537,7 @@ def rdf_view(request):
# lire tous les photos attachées
photos = get_photos(request, rapport.nochantier, norapport)
if 'form.generate' in request.params:
if 'form.generate' in request.params:
options = {
'page-size': 'A4',
'margin-top': '0.65in',
@@ -550,7 +554,7 @@ def rdf_view(request):
dest = "mondumas/static/DEVFAC/DOCS_ATTACHES/PL/%s/%s" % (str(rapport.nochantier), filename)
# developpement ou production
if request.registry.settings["mail.host"] == "smtp.orange.fr":
if request.registry.settings["mail.username"] == "sas.dumas@orange.fr":
origin = 'https://gestion.entreprise-dumas.com/rdf_rapport/%s' % norapport
pdfkit.from_url(origin, dest, options=options)
else:
@@ -683,229 +687,248 @@ def rdf_bill(request):
@view_config(route_name='demandes', renderer='../templates/dossier/demandes.pt', permission='view')
def demandes(request):
logged_in = request.authenticated_userid.upper()
url = request.route_url('demandes')
societes = ['PE','ME','PL']
societe = 'PE'
# prendre en compte les paramètres de saisie
if 'societe' in request.params:
societe = request.params["societe"]
# sélection du mailbox selon la societe
if societe == 'PE':
mbx_name = 'peinture-dumas@entreprise-dumas.com'
mbx_pwd = 'sasdumas'
elif societe == 'ME':
mbx_name = 'menuiserie-dumas@entreprise-dumas.com'
mbx_pwd = 'sasdumas'
elif societe == 'PL':
mbx_name = 'versanit-dumas@entreprise-dumas.com'
mbx_pwd = 'sasdumas'
else:
mbx_name = 'polynet-dumas@entreprise-dumas.com'
mbx_pwd = 'sasdumas'
# lire les demandes d'interventions arrivées par email
mbx_search1 = 'FROM gestionsinistre@maif.fr SUBJECT "Missionnement r"'
mbx_search2 = 'FROM service.sinistres@domus-services.fr SUBJECT "Ordre de mission DOMUS - Dossier"'
conn = imaplib.IMAP4_SSL('imap.entreprise-dumas.com')
try:
# se connecter à la mailbox
conn.login(mbx_name, mbx_pwd)
except imaplib.IMAP4.error:
request.session.flash("ERREUR connexion au compte %s" % mbx_name, 'danger')
return HTTPFound(location=request.route_url('home'))
# lire le INBOX
rv, data = conn.select('INBOX', readonly =True)
# if 'form.submitted' in request.params:
# traiter les demandes de la MAIF puis de DOMUS
# demandes_generer(request, conn, societe, mbx_search1)
# demandes_generer(request, conn, societe, mbx_search2)
liste=[]
# lire les demandes de la MAIF puis de DOMUS
demandes_afficher(conn, mbx_name, mbx_search1, liste)
demandes_afficher(conn, mbx_name, mbx_search2, liste)
# messages lus
msglus = bool(liste)
conn.logout()
return {
'page_title': 'Liste des demandes pour la société ' + societe,
'url': url,
'societe': societe,
'societes': societes,
'dt_data': json.dumps(liste),
'msglus': msglus,
}
def demandes_afficher(conn, mbx_name, search_criteria, liste):
# créer la liste des entêtes des messages à afficher
rv, data = conn.search(None, search_criteria)
if rv != 'OK':
request.session.flash("ERREUR de lecture de la boîte de réception", 'danger')
return HTTPFound(location=request.route_url('home'))
mail_ids = data[0]
for num in mail_ids.split():
rv, msg_data = conn.fetch(num, '(RFC822)')
if rv != 'OK':
request.session.flash("ERREUR de lecture du message %s" % num, 'danger')
def mailbox_connect(societe):
# connecter au serveur IMAP de la societe
if societe == 'PE':
mbx_name = 'peinture-dumas@entreprise-dumas.com'
mbx_pwd = 'sasdumas'
elif societe == 'ME':
mbx_name = 'menuiserie-dumas@entreprise-dumas.com'
mbx_pwd = 'sasdumas'
elif societe == 'PL':
mbx_name = 'versanit-dumas@entreprise-dumas.com'
mbx_pwd = 'sasdumas'
else:
request.session.flash("Cette société est inconnue ou non traitée : %s" % societe, 'danger')
return HTTPFound(location=request.route_url('home'))
msg = email.message_from_bytes(msg_data[0][1])
hdr = email.header.make_header(email.header.decode_header(msg['Subject']))
email_subject = str(hdr)
email_from = email.utils.parseaddr(msg['from'])[1]
# Now convert to local date-time
date_tuple = email.utils.parsedate_tz(msg['Date'])
if date_tuple:
email_date = datetime.fromtimestamp(email.utils.mktime_tz(date_tuple))
else:
email_date = datetime.now()
d = (str(int(num)), email_date.strftime('%d-%m-%Y %H:%M:%S'), email_from, mbx_name.replace('entreprise-dumas.com', ''), email_subject)
liste.append(d)
return liste
def demandes_generer(request, conn, societe, mbx_search):
def generer_mission(request, societe, mbx_search, extracted_file, temp_file_path):
conn = imaplib.IMAP4_SSL('imap.entreprise-dumas.com')
try:
# se connecter à la mailbox
conn.login(mbx_name, mbx_pwd)
except imaplib.IMAP4.error:
request.session.flash("ERREUR connexion au compte %s" % mbx_name, 'danger')
return HTTPFound(location=request.route_url('home'))
if 'maif.fr' in mbx_search:
return conn
def demandes_lister(societe, search_criteria):
# connecter au serveur de mail
conn = mailbox_connect(societe)
# select INBOX
rv, data = conn.select('INBOX', readonly =True)
# créer la liste des entêtes des messages à afficher
liste = []
for criteria in search_criteria:
rv, data = conn.search(None, criteria)
if rv != 'OK':
request.session.flash("ERREUR de lecture de la boîte de réception", 'danger')
return HTTPFound(location=request.route_url('home'))
mail_ids = data[0]
for num in mail_ids.split():
rv, msg_data = conn.fetch(num, '(RFC822)')
if rv != 'OK':
request.session.flash("ERREUR de lecture du message %s" % num, 'danger')
return HTTPFound(location=request.route_url('home'))
msg = email.message_from_bytes(msg_data[0][1])
hdr = email.header.make_header(email.header.decode_header(msg['Subject']))
email_subject = str(hdr)
email_from = email.utils.parseaddr(msg['from'])[1]
# Now convert to local date-time
date_tuple = email.utils.parsedate_tz(msg['Date'])
if date_tuple:
email_date = datetime.fromtimestamp(email.utils.mktime_tz(date_tuple))
else:
email_date = datetime.now()
d = (societe, email_date.strftime('%d-%m-%Y %H:%M:%S'), email_from, email_subject)
liste.append(d)
# deconnexion du serveur
conn.close()
conn.logout()
return liste
def demandes_generer(request, societe, search_criteria):
def generer_mission(request, societe, mbx_search, extracted_file, temp_file_path):
if 'maif.fr' in mbx_search:
# extraire les infos de la demmande MAIF
dem_info = get_pdf_infos1(extracted_file)
if societe == 'PE':
cd_cli = 2813
elif societe == 'ME':
cd_cli = 3428
else:
# VERSANIT
cd_cli = 1743
elif 'domus-services.fr' in mbx_search:
# extraire les infos de la demmande DOMUS
dem_info = get_pdf_infos2(extracted_file)
if societe == 'PE':
cd_cli = 8991
elif societe == 'ME':
cd_cli = 5276
else:
# VERSANIT
cd_cli = 3209
# extraction OK ? oui, créer une dem_devis et récupèrer son no_id
if dem_info['c_nom'] != '':
nochantier = insert_dossier(request, societe, cd_cli, dem_info['c_nom'], dem_info['c_adr'], dem_info['c_adr2'], \
dem_info['c_cp'], dem_info['c_ville'], dem_info['c_telp'], dem_info['no_sinistre'], dem_info['c_obs'], dem_info['tx_trav'])
nodossier = "%s-%s" % (societe, nochantier)
# récupère le nom du fichier et ajouter le no de dossier
filename = os.path.basename(temp_file_path)
filename = '%s-DD%s-%s' % (societe, nochantier, filename)
tempFile2Dossier(request, societe, nochantier, '0', temp_file_path, filename, 'EMAIL')
return
def generer_annul_maif(request, societe, extracted_file, temp_file_path):
# extraire les infos de la demmande MAIF
dem_info = get_pdf_infos1(extracted_file)
if societe == 'PE':
cd_cli = 2813
elif societe == 'ME':
cd_cli = 3428
else:
# VERSANIT
cd_cli = 1743
elif 'domus-services.fr' in mbx_search:
# extraire les infos de la demmande DOMUS
dem_info = get_pdf_infos2(extracted_file)
if societe == 'PE':
cd_cli = 8991
elif societe == 'ME':
cd_cli = 5276
else:
# VERSANIT
cd_cli = 3209
# extraction OK ? oui, créer une dem_devis et récupèrer son no_id
if dem_info['c_nom'] != '':
nochantier = insert_dossier(request, societe, cd_cli, dem_info['c_nom'], dem_info['c_adr'], dem_info['c_adr2'], \
dem_info['c_cp'], dem_info['c_ville'], dem_info['c_telp'], dem_info['no_sinistre'], dem_info['c_obs'], dem_info['tx_trav'])
nodossier = "%s-%s" % (societe, nochantier)
# extraction OK ? oui, rechercher la dem_devis concerné
# récupère le nom du fichier et ajouter le no de dossier
filename = os.path.basename(temp_file_path)
filename = '%s-DD%s-%s' % (societe, nochantier, filename)
tempFile2Dossier(request, societe, nochantier, '0', temp_file_path, filename, 'AUTO')
return
# import pdb;pdb.set_trace()
if dem_info['c_nom'] != '':
# oui, rechercher la dem_devis concerné par le no de sinistre
nosin = dem_info['no_sinistre']
dem_devis = get_dossier_by_sinistre(request,societe, nosin)
if dem_devis:
nodossier = "%s-%s" % (societe, dem_devis.NO_ID)
# récupère le nom du fichier et ajouter le no de dossier
filename = '%s-DD%s-%s' % (societe, dem_devis.NO_ID, 'ANNULATION.pdf')
tempFile2Dossier(request, societe, dem_devis.NO_ID, '0', temp_file_path, filename, 'EMAIL')
# insérer une ligne de suivi ANNULATION
insert_suivi(request, nodossier, '!!MISSION ANNULEE PAR la MAIF')
return
def generer_annulation1(request, societe, extracted_file, temp_file_path):
# extraire les infos de la demmande MAIF
dem_info = get_pdf_infos1(extracted_file)
# extraction OK ? oui, rechercher la dem_devis concerné
if dem_info['c_nom'] != '':
def generer_annul_domus(request, societe, nosin, temp_file_path):
# import pdb;pdb.set_trace()
# oui, rechercher la dem_devis concerné par le no de sinistre
dem_devis = get_dossier_by_sinistre(request,societe, nosin)
nodossier = "%s-%s" % (societe, dem_devis.NO_ID)
if dem_devis:
nodossier = "%s-%s" % (societe, dem_devis.NO_ID)
# récupère le nom du fichier et ajouter le no de dossier
filename = '%s-DD%s-%s' % (societe, dem_devis.NO_ID, 'ANNULATION.pdf')
tempFile2Dossier(request, societe, dem_devis.NO_ID, '0', temp_file_path, filename, 'EMAIL')
# insérer une ligne de suivi ANNULATION
insert_suivi(request, nodossier, '!!MISSION ANNULEE PAR DOMUS')
return
# connecter au serveur de mail
conn = mailbox_connect(societe)
# select INBOX
rv, data = conn.select('INBOX', readonly =True)
for criteria in search_criteria:
# rechercher les emails de demandes dans le INBOX
rv, data = conn.search(None, criteria)
if rv != 'OK':
request.session.flash("ERREUR de lecture de la boîte de réception", 'danger')
return HTTPFound(location=request.route_url('home'))
# récupère le nom du fichier et ajouter le no de dossier
filename = '%s-DD%s-%s' % (societe, dem_devis.NO_ID, 'ANNULATION.pdf')
tempFile2Dossier(request, societe, dem_devis.NO_ID, '0', temp_file_path, filename, 'AUTO')
# insérer une ligne de suivi ANNULATION
insert_suivi(request, nodossier, '!!MISSION ANNULEE PAR la MAIF')
return
def generer_annulation2(request, societe, nosin, temp_file_path):
mail_ids = data[0]
nbMessages = len(mail_ids)
for num in mail_ids.split():
rv, msg_data = conn.fetch(num, '(RFC822)')
if rv != 'OK':
request.session.flash("ERREUR de lecture du message %s" % num, 'danger')
return HTTPFound(location=request.route_url('home'))
raw_email = msg_data[0][1]
# converts byte literal to string removing b''
raw_email_string = raw_email.decode('utf-8')
email_message = email.message_from_string(raw_email_string)
# oui, rechercher la dem_devis concerné par le no de sinistre
dem_devis = get_dossier_by_sinistre(request,societe, nosin)
nodossier = "%s-%s" % (societe, dem_devis.NO_ID)
# get the message's body
body = ''
for part in email_message.walk():
ctype = part.get_content_type()
cdispo = str(part.get('Content-Disposition'))
# skip any text/plain (txt) attachments
if ctype == 'text/html' and 'attachment' not in cdispo:
body = part.get_payload(decode=True) # decode
break
# downloading attachment
temp_file_path = download_pdf_to_tmp(email_message)
# récupère le nom du fichier et ajouter le no de dossier
filename = '%s-DD%s-%s' % (societe, dem_devis.NO_ID, 'ANNULATION.pdf')
tempFile2Dossier(request, societe, dem_devis.NO_ID, '0', temp_file_path, filename, 'AUTO')
# insérer une ligne de suivi ANNULATION
insert_suivi(request, nodossier, '!!MISSION ANNULEE PAR DOMUS')
return
# rechercher les emails de demandes dans le INBOX
rv, data = conn.search(None, mbx_search)
if rv != 'OK':
request.session.flash("ERREUR de lecture de la boîte de réception", 'danger')
return HTTPFound(location=request.route_url('home'))
mail_ids = data[0]
for num in mail_ids.split():
rv, msg_data = conn.fetch(num, '(RFC822)')
if rv != 'OK':
request.session.flash("ERREUR de lecture du message %s" % num, 'danger')
return HTTPFound(location=request.route_url('home'))
# convertir le fichier pdf en texte
texte, extracted_file = pdf_convert_to_txt(temp_file_path)
# mission annulée ?
if 'Objet : ANNULATION MISSION' in texte :
# genere ANNULATION mission MAIF
# import pdb;pdb.set_trace()
generer_annul_maif(request, societe, extracted_file, temp_file_path)
# conn.store(num, '+FLAGS', r'(\Deleted)')
elif 'ANNULATION ORDRE DE MISSION' in texte:
# genere ANNULATION mission DOMUS
nosin = str(body)[84:95]
# import pdb;pdb.set_trace()
generer_annul_domus(request, societe, nosin, temp_file_path)
# conn.store(num, '+FLAGS', r'(\Deleted)')
else:
# genere le dossier d'après le mail
# import pdb;pdb.set_trace()
generer_mission(request, societe, criteria, extracted_file, temp_file_path)
# marquer le message comme supprimé
# conn.store(num, '+FLAGS', r'(\Deleted)')
raw_email = msg_data[0][1]
# converts byte literal to string removing b''
raw_email_string = raw_email.decode('utf-8')
email_message = email.message_from_string(raw_email_string)
# get the message's body
body = ''
for part in email_message.walk():
ctype = part.get_content_type()
cdispo = str(part.get('Content-Disposition'))
# skip any text/plain (txt) attachments
if ctype == 'text/html' and 'attachment' not in cdispo:
body = part.get_payload(decode=True) # decode
break
# downloading attachment
temp_file_path = download_pdf_to_tmp(email_message)
# convertir le fichier pdf en texte
texte, extracted_file = pdf_convert_to_txt(temp_file_path)
conn.expunge()
conn.close()
# deconnexion du serveur
conn.logout()
# mission annulée ?
if 'Objet : ANNULATION MISSION' in texte :
# genere ANNULATION mission MAIF
generer_annulation1(request, societe, extracted_file, temp_file_path)
elif 'ANNULATION ORDRE DE MISSION' in texte:
# genere ANNULATION mission DOMUS
nosin = str(body)[84:95]
generer_annulation2(request, societe, nosin, temp_file_path)
else:
# genere le dossier d'après le mail
generer_mission(request, societe, mbx_search, extracted_file, temp_file_path)
return nbMessages
return
def resize_photos(image_file):
# using the Python Image Library (PIL) to resize an image
img_org = Image.open(image_file)
# get the size of the original image
width_org, height_org = img_org.size
# set the resizing factor so the aspect ratio can be retained
# factor > 1.0 increases size
# factor < 1.0 decreases size
factor = 1
width = int(width_org * factor)
height = int(height_org * factor)
# best down-sizing filter
img_anti = img_org.resize((width, height), Image.ANTIALIAS)
# split image filename into name and extension
name, ext = os.path.splitext(image_file)
# create a new file name for saving the result
img_anti.save(image_file)
# ------- main -------
logged_in = request.authenticated_userid.upper()
url = request.route_url('demandes')
message = ''
societes = ['PE','ME','PL']
# critères de recherche des demandes d'interventions de la MAIF
# search_criteria = ['FROM service.sinistres@domus-services.fr SUBJECT "Ordre de mission DOMUS - Dossier"']
search_criteria = ['FROM gestionsinistre@maif.fr SUBJECT "Intervention entreprise partenaire"',
'FROM service.sinistres@domus-services.fr SUBJECT "Ordre de mission DOMUS - Dossier"']
if 'form.submitted' in request.params:
# traiter les demandes de la MAIF puis de DOMUS pour toutes les sociétes
nbMessages = 0
for societe in societes:
nb = demandes_generer(request, societe, search_criteria)
nbMessages = nbMessages + nb
message = "%s demandes de devis a été crées." % nbMessages
liste=[]
# lister les demandes par societe
for societe in societes:
liste = liste + demandes_lister(societe, search_criteria)
# messages lus
msglus = bool(liste)
return {
'page_title': "Liste des emails de demandes d'intervention",
'url': url,
'dt_data': json.dumps(liste),
'msglus': msglus,
'message': message,
}
return
def downloadFile2Temp(input_file, input_name, ext_allowed):
# récupère son extension
@@ -999,7 +1022,7 @@ def pdf_convert_to_txt(path):
fh.close()
# ecrire le texte dans un fichier
extracted_file = '/tmp/log_file.txt'
with open(extracted_file, "w") as my_log:
with open(extracted_file, "w", encoding="utf-8") as my_log:
my_log.write(extracted_text)
my_log.close()
@@ -1008,11 +1031,11 @@ def pdf_convert_to_txt(path):
def get_pdf_infos1(extracted_file):
# à partir du fichier texte du pdf
# parcourir les lignes pour retrouver les infos utiles
with open(extracted_file) as fp:
with open(extracted_file, encoding="utf-8") as fp:
cnt = 1
line = fp.readline()
# première ligne doit être "MAIF"
if line[:-1] != 'MAIF':
if line[:-1] not in ['MAIF', 'FILIA-MAIF']:
return {'c_nom': ''}
c_obs = ''
@@ -1074,7 +1097,7 @@ def get_pdf_infos1(extracted_file):
def get_pdf_infos2(extracted_file):
# à partir du fichier texte du pdf de DOMUS
# parcourir les lignes pour retrouver les infos utiles
with open(extracted_file) as fp:
with open(extracted_file, encoding="utf-8") as fp:
cnt = 1
line = fp.readline()
# première ligne doit être :
@@ -1130,6 +1153,23 @@ def get_pdf_infos2(extracted_file):
'no_sinistre': no_sinistre,
}
def resize_photos(image_file):
# using the Python Image Library (PIL) to resize an image
img_org = Image.open(image_file)
# get the size of the original image
width_org, height_org = img_org.size
# set the resizing factor so the aspect ratio can be retained
# factor > 1.0 increases size
# factor < 1.0 decreases size
factor = 1
width = int(width_org * factor)
height = int(height_org * factor)
# best down-sizing filter
img_anti = img_org.resize((width, height), Image.ANTIALIAS)
# split image filename into name and extension
name, ext = os.path.splitext(image_file)
# create a new file name for saving the result
img_anti.save(image_file)
return