""" Ce fichier permet le stockage des email interne """ import ast from calendar import monthrange from zipfile import ZipFile import bson import pymongo import xlsxwriter from pymongo import MongoClient import json from bson import ObjectId import re from datetime import datetime, date, timedelta import Session_Formation import module_editique import partner_base_setup import partner_client import partner_order import prj_common as mycommon import secrets import inspect import sys, os import csv import pandas as pd from pymongo import ReturnDocument import GlobalVariable as MYSY_GV from math import isnan import GlobalVariable as MYSY_GV import ela_index_bdd_classes as eibdd import email_mgt as email import jinja2 from flask import send_file from xhtml2pdf import pisa from email.message import EmailMessage from email.mime.text import MIMEText from email import encoders import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.base import MIMEBase from email import encoders import survey_mgt as survey_mgt import attached_file_mgt import Inscription_mgt as Inscription_mgt """ Cette fonction permet de créer un email à vide, jute pour recuperer un _id """ def Create_Empty_Internal_Mail(diction): try: diction = mycommon.strip_dictionary(diction) """ Verification des input acceptés """ field_list = ['token', ] incom_keys = diction.keys() for val in incom_keys: if val not in field_list and val.startswith('my_') is False: mycommon.myprint(str( inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé") return False, " Les informations fournies sont incorrectes" """ Verification des champs obligatoires """ field_list_obligatoire = ['token', ] for val in field_list_obligatoire: if val not in diction: mycommon.myprint( str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ") return False, " Les informations fournies sont incorrectes" """ Verification de l'identité et autorisation de l'entité qui appelle cette API """ token = "" if ("token" in diction.keys()): if diction['token']: token = diction['token'] local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) if (local_status is not True): return local_status, my_partner new_data = {} new_data['valide'] = "1" new_data['locked'] = "0" new_data['statut'] = "0" new_data['is_read'] = "0" new_data['creation_date'] = str(datetime.now()) new_data['creation_by'] = str(my_partner['_id']) new_data['partner_owner_recid'] = str(my_partner['recid']) inserted_id = MYSY_GV.dbname['internal_mail'].insert_one(new_data).inserted_id if (not inserted_id): mycommon.myprint( " Impossible d'ajouter le message dans la collection internal_email (2) ") return False, " Impossible d'ajouter le message dans la collection internal_email (2) " return True, str(inserted_id) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) return False, "Impossible d'ajouter le message dans la collection internal_email " """ Important : actuellement le login se fait via la collection 'user_account' ou 'partnair_account' de ce fait, le champ 'related_collection' permettra de connaitre la collection associée et le champ 'related_collection_recid' permettra de connaitre l'_id le champs 'is_read' => 0 (pas lu), 1 (lu) """ def Add_Message_To_Internal_Mail(tab_files, diction): try: diction = mycommon.strip_dictionary(diction) """ Verification des input acceptés """ field_list = ['token', 'from', 'cc', 'bcc', 'subject', 'to', 'message', 'tab_saved_file_full_path', 'smtp_account_password', 'smtp_account_smtpsrv', 'smtp_account_user', 'smtp_account_From_User', 'smtp_account_port', 'related_collection', 'related_collection_recid'] incom_keys = diction.keys() for val in incom_keys: if val not in field_list and val.startswith('my_') is False: mycommon.myprint(str( inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé") return False, " Les informations fournies sont incorrectes" """ Verification des champs obligatoires """ field_list_obligatoire = ['token', 'from', 'cc', 'bcc', 'subject', 'to', 'message', 'tab_saved_file_full_path', 'smtp_account_password', 'smtp_account_smtpsrv', 'smtp_account_user', 'smtp_account_From_User', 'smtp_account_port', 'related_collection', 'related_collection_recid'] for val in field_list_obligatoire: if val not in diction: mycommon.myprint( str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ") return False, " Les informations fournies sont incorrectes" """ Verification de l'identité et autorisation de l'entité qui appelle cette API """ token = "" if ("token" in diction.keys()): if diction['token']: token = diction['token'] local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) if (local_status is not True): return local_status, my_partner """ Verifier la validité des related_collection et related_collection_recid """ if( "related_collection" in diction.keys() and diction['related_collection'] and "related_collection_recid" in diction.keys() and diction['related_collection_recid'] ): login_count = MYSY_GV.dbname[str(diction['related_collection'])].count_documents({'_id':ObjectId(str(diction['related_collection_recid'])), 'partner_owner_recid':str(my_partner['recid'])}) if(login_count != 1 ): mycommon.myprint("L'utilisateur destinataire de l'email est invalide ") return False, "L'utilisateur destinataire de l'email est invalide" # Sauvegarde des fichiers joints depuis le front if (len(tab_files) > MYSY_GV.EMAIL_MAX_PJ): mycommon.myprint("Vous ne pouvez pas envoyer plus de " + str(MYSY_GV.EMAIL_MAX_PJ) + " pièces jointes.") return False, "Vous ne pouvez pas envoyer plus de " + str(MYSY_GV.EMAIL_MAX_PJ) + " pièces jointes. " tab_saved_file_full_path = [] for file in tab_files: status, saved_file_full_path = mycommon.Upload_Save_PDF_IMG_File(file, MYSY_GV.TEMPORARY_DIRECTORY_V2) if (status is False): mycommon.myprint("Impossible de récupérer correctement le fichier à importer") return False, "Impossible de récupérer correctement le fichier à importer" tab_saved_file_full_path.append(saved_file_full_path) new_data = diction del diction['token'] # Initialisation des champs non envoyés à vide for val in field_list: if val not in diction.keys(): new_data[str(val)] = "" new_data['valide'] = "1" new_data['locked'] = "0" new_data['statut'] = "0" new_data['is_read'] = "0" new_data['attached_files_path'] = tab_saved_file_full_path new_data['creation_date'] = str(datetime.now()) new_data['creation_by'] = str(my_partner['_id']) new_data['partner_owner_recid'] = str(my_partner['recid']) inserted_id = MYSY_GV.dbname['internal_mail'].insert_one(new_data).inserted_id if (not inserted_id): mycommon.myprint( " Impossible d'ajouter le message dans la collection internal_email (2) ") return False, " Impossible d'ajouter le message dans la collection internal_email (2) " message_id = "" return True, str(message_id) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) return False, "Impossible d'ajouter le message dans la collection internal_email " """ Mise à jour d'un message, par exemple les status """ def Update_Message_To_Internal_Mail(diction): try: diction = mycommon.strip_dictionary(diction) """ Verification des input acceptés """ field_list = ['token', 'from', 'cc', 'bcc', 'subject', 'to', 'message', 'status', 'tab_message_id', 'smtp_account_password', 'smtp_account_smtpsrv', 'smtp_account_user', 'smtp_account_From_User', 'smtp_account_port', 'is_read'] incom_keys = diction.keys() for val in incom_keys: if val not in field_list and val.startswith('my_') is False: mycommon.myprint(str( inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé") return False, " Les informations fournies sont incorrectes" """ Verification des champs obligatoires """ field_list_obligatoire = ['token', 'tab_message_id'] for val in field_list_obligatoire: if val not in diction: mycommon.myprint( str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ") return False, " Les informations fournies sont incorrectes" """ Verification de l'identité et autorisation de l'entité qui appelle cette API """ token = "" if ("token" in diction.keys()): if diction['token']: token = diction['token'] local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) if (local_status is not True): return local_status, my_partner tab_message_id_split = str(diction['tab_message_id']).split(",") tab_message_id = [] for tmp in tab_message_id_split: if( tmp ): tab_message_id.append(tmp) for local_message_id in tab_message_id : """ Verifier la validité du message """ is_massage_valide = MYSY_GV.dbname['internal_mail'].count_documents({'_id':ObjectId(str(local_message_id)), 'valide':'1', 'locked':'0', 'partner_owner_recid':str(my_partner['recid']), 'statut':{'$ne':'1'}}) if( is_massage_valide != 1): mycommon.myprint( str(inspect.stack()[0][3]) + " L'identifiant du message "+str(local_message_id)+" n'est pas valide") return False, " L'identifiant du message "+str(local_message_id)+" n'est pas valide " del diction['token'] del diction['tab_message_id'] for local_message_id in tab_message_id: local_id = str(local_message_id) new_data = diction new_data['date_update'] = str(datetime.now()) new_data['update_by'] = str(my_partner['_id']) data_cle = {} data_cle['_id'] = ObjectId(local_id) data_cle['partner_owner_recid'] = str(my_partner['recid']) data_cle['statut'] = {'$ne': '1'} result = MYSY_GV.dbname['internal_mail'].find_one_and_update( data_cle, {"$set": new_data}, upsert=False, return_document=ReturnDocument.AFTER ) return True, "Le message a été mis à jour" except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) return False, "Impossible de mettre à jour le message " """ Supprimer un message donnée """ def Delete_Message_To_Internal_Mail(diction): try: diction = mycommon.strip_dictionary(diction) """ Verification des input acceptés """ field_list = ['token', 'tab_message_id',] incom_keys = diction.keys() for val in incom_keys: if val not in field_list and val.startswith('my_') is False: mycommon.myprint(str( inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé") return False, " Les informations fournies sont incorrectes" """ Verification des champs obligatoires """ field_list_obligatoire = ['token', 'tab_message_id',] for val in field_list_obligatoire: if val not in diction: mycommon.myprint( str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ") return False, " Les informations fournies sont incorrectes" """ Verification de l'identité et autorisation de l'entité qui appelle cette API """ token = "" if ("token" in diction.keys()): if diction['token']: token = diction['token'] local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) if (local_status is not True): return local_status, my_partner tab_message_id_work = str(diction['tab_message_id']).split(",") tab_message_id_ObjectId = [] for tmp in tab_message_id_work: if( tmp ): tab_message_id_ObjectId.append(ObjectId(str(tmp))) delete = MYSY_GV.dbname['internal_mail'].delete_many({'_id': {'$in':tab_message_id_ObjectId}, 'partner_owner_recid': str(my_partner['recid']), }, ) return True, str(delete.deleted_count)+" message(s) supprimé(s) " except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) return False, " Impossible de supprimer les messages " """ Recuperer la liste des message d'un user """ def Get_List_User_Internal_Mail(diction): try: diction = mycommon.strip_dictionary(diction) """ Verification des input acceptés """ field_list = ['token', 'related_collection_recid'] incom_keys = diction.keys() for val in incom_keys: if val not in field_list and val.startswith('my_') is False: mycommon.myprint(str( inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas") return False, " Les informations fournies sont incorrectes", """ Verification des champs obligatoires """ field_list_obligatoire = ['token', 'related_collection_recid'] for val in field_list_obligatoire: if val not in diction: mycommon.myprint( str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ") return False, " Les informations fournies sont incorrectes", """ Verification de l'identité et autorisation de l'entité qui appelle cette API """ token = "" if ("token" in diction.keys()): if diction['token']: token = diction['token'] local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) if (local_status is not True): return local_status, my_partner """ Clés de mise à jour """ data_cle = {} data_cle['partner_owner_recid'] = str(my_partner['recid']) data_cle['valide'] = "1" data_cle['locked'] = "0" data_cle['related_collection_recid'] = str(diction['related_collection_recid']) print(" ### data_cle = ", data_cle) RetObject = [] val_tmp = 0 for retval in MYSY_GV.dbname['internal_mail'].find(data_cle).sort([("_id", pymongo.DESCENDING), ]): user = retval user['id'] = str(val_tmp) val_tmp = val_tmp + 1 RetObject.append(mycommon.JSONEncoder().encode(user)) return True, RetObject except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) return False, " Impossible de récupérer la liste des messages " """ Recuperer la liste des message ENVOYES par un user """ def Get_List_Internal_Mail_Sent_By_User(diction): try: diction = mycommon.strip_dictionary(diction) """ Verification des input acceptés """ field_list = ['token', 'creation_by'] incom_keys = diction.keys() for val in incom_keys: if val not in field_list and val.startswith('my_') is False: mycommon.myprint(str( inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas") return False, " Les informations fournies sont incorrectes", """ Verification des champs obligatoires """ field_list_obligatoire = ['token', 'creation_by'] for val in field_list_obligatoire: if val not in diction: mycommon.myprint( str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ") return False, " Les informations fournies sont incorrectes", """ Verification de l'identité et autorisation de l'entité qui appelle cette API """ token = "" if ("token" in diction.keys()): if diction['token']: token = diction['token'] local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) if (local_status is not True): return local_status, my_partner """ Clés de mise à jour """ data_cle = {} data_cle['partner_owner_recid'] = str(my_partner['recid']) data_cle['valide'] = "1" data_cle['locked'] = "0" data_cle['creation_by'] = str(diction['creation_by']) print(" ### data_cle = ", data_cle) RetObject = [] val_tmp = 0 for retval in MYSY_GV.dbname['internal_mail'].find(data_cle).sort([("_id", pymongo.DESCENDING), ]): user = retval user['id'] = str(val_tmp) val_tmp = val_tmp + 1 RetObject.append(mycommon.JSONEncoder().encode(user)) return True, RetObject except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) return False, " Impossible de récupérer la liste des messages " """ Cette fonction recupere le nombre d'email non lu pour un user """ def Get_Nb_User_Internal_Mail_Not_Read(diction): try: diction = mycommon.strip_dictionary(diction) """ Verification des input acceptés """ field_list = ['token', 'related_collection_recid'] incom_keys = diction.keys() for val in incom_keys: if val not in field_list and val.startswith('my_') is False: mycommon.myprint(str( inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas") return False, " Les informations fournies sont incorrectes", """ Verification des champs obligatoires """ field_list_obligatoire = ['token', 'related_collection_recid'] for val in field_list_obligatoire: if val not in diction: mycommon.myprint( str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ") return False, " Les informations fournies sont incorrectes", """ Verification de l'identité et autorisation de l'entité qui appelle cette API """ token = "" if ("token" in diction.keys()): if diction['token']: token = diction['token'] local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) if (local_status is not True): return local_status, my_partner """ Clés de mise à jour """ data_cle = {} data_cle['partner_owner_recid'] = str(my_partner['recid']) data_cle['valide'] = "1" data_cle['locked'] = "0" data_cle['is_read'] = "0" data_cle['related_collection_recid'] = str(diction['related_collection_recid']) nb_no_read_internal_mail = MYSY_GV.dbname['internal_mail'].count_documents(data_cle) return True, str(nb_no_read_internal_mail) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) return False, " Impossible de récupérer le nombre de messages non lu(s)" """ Récuperation des données d'un email """ def Get_Given_Internal_Mail(diction): try: diction = mycommon.strip_dictionary(diction) """ Verification des input acceptés """ field_list = ['token', 'internal_mail_id'] incom_keys = diction.keys() for val in incom_keys: if val not in field_list and val.startswith('my_') is False: mycommon.myprint(str( inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas") return False, " Les informations fournies sont incorrectes" """ Verification des champs obligatoires """ field_list_obligatoire = ['token', 'internal_mail_id'] for val in field_list_obligatoire: if val not in diction: mycommon.myprint( str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ") return False, " Les informations fournies sont incorrectes" """ Verification de l'identité et autorisation de l'entité qui appelle cette API """ token = "" if ("token" in diction.keys()): if diction['token']: token = diction['token'] local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) if (local_status is not True): return local_status, my_partner RetObject = [] val_tmp = 0 print(" ### data_cle = ", {'_id':ObjectId(str(diction['internal_mail_id'])), 'valide':'1', 'locked':'0'}) for retval in MYSY_GV.dbname['internal_mail'].find({'_id':ObjectId(str(diction['internal_mail_id'])), 'valide':'1', 'locked':'0'}): user = retval user['id'] = str(val_tmp) val_tmp = val_tmp + 1 RetObject.append(mycommon.JSONEncoder().encode(user)) return True, RetObject except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) return False, " Impossible de récuperer les données du mail " """ Cette fonction permet de renvoyer un email """ def Send_List_Internal_Mail(diction): try: field_list_obligatoire = ['token', 'tab_internal_mail_id'] for val in field_list_obligatoire: if val not in diction: mycommon.myprint( str(inspect.stack()[0][ 3]) + " La valeur '" + val + "' n'est pas presente dans la liste des arguments ") return False, " La valeur '" + val + "' n'est pas presente dans la liste des arguments" tab_internal_mail_id_ObjectId = [] tab_internal_mail_id = [] tab_internal_mail_id_split = str(diction['tab_internal_mail_id']).split(",") for tmp in tab_internal_mail_id_split: if( tmp ): tab_internal_mail_id.append(str(tmp)) tab_internal_mail_id_ObjectId.append(ObjectId(str(tmp))) if(len(tab_internal_mail_id) > 0 ): a=2 return True, "Email(s) reenvoyés " except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) return False, " Impossible de renvoyer les emails " """ Cette fonction recupere la liste des emails possible comme destinataire Il s'agit des emails repertoriés par dans les collection "partnaire_account" et "user_account" """ def Get_List_Internal_Destinataire(diction): try: diction = mycommon.strip_dictionary(diction) """ Verification des input acceptés """ field_list = ['token'] incom_keys = diction.keys() for val in incom_keys: if val not in field_list and val.startswith('my_') is False: mycommon.myprint(str( inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas") return False, " Les informations fournies sont incorrectes", """ Verification des champs obligatoires """ field_list_obligatoire = ['token',] for val in field_list_obligatoire: if val not in diction: mycommon.myprint( str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ") return False, " Les informations fournies sont incorrectes", """ Verification de l'identité et autorisation de l'entité qui appelle cette API """ token = "" if ("token" in diction.keys()): if diction['token']: token = diction['token'] local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) if (local_status is not True): return local_status, my_partner """ Clés de mise à jour """ data_cle = {} data_cle['partner_owner_recid'] = str(my_partner['recid']) data_cle['active'] = "1" data_cle['locked'] = "0" print(" ### data_cle = ", data_cle) RetObject = [] val_tmp = 0 for retval in MYSY_GV.dbname['partnair_account'].find(data_cle).sort([("_id", pymongo.DESCENDING), ]): user = {} user['id'] = str(val_tmp) user['_id'] = str(retval['_id']) if( "nom" in retval.keys()): user['nom'] = retval['nom'] else: user['nom'] = "" if ("prenom" in retval.keys()): user['prenom'] = retval['prenom'] else: user['prenom'] = "" if ("email" in retval.keys()): user['email'] = retval['email'] val_tmp = val_tmp + 1 RetObject.append(mycommon.JSONEncoder().encode(user)) for retval in MYSY_GV.dbname['user_account'].find(data_cle).sort([("_id", pymongo.DESCENDING), ]): user = {} user['id'] = str(val_tmp) user['_id'] = str(retval['_id']) if( "nom" in retval.keys()): user['nom'] = retval['nom'] else: user['nom'] = "" if ("prenom" in retval.keys()): user['prenom'] = retval['prenom'] else: user['prenom'] = "" if ("email" in retval.keys()): user['email'] = retval['email'] val_tmp = val_tmp + 1 RetObject.append(mycommon.JSONEncoder().encode(user)) return True, RetObject except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) return False, " Impossible de récupérer la liste adresse email "