23/11/22 - 22h30

master
cherif 2022-11-23 22:24:31 +01:00
parent 2d6cbc94f2
commit bcbd0c22fb
10 changed files with 4087 additions and 176 deletions

View File

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="1122d9e2-679f-46d6-8c4f-97e9ae4041b5" name="Changes" comment="22/11/22 - 11h30">
<list default="true" id="1122d9e2-679f-46d6-8c4f-97e9ae4041b5" name="Changes" comment="22/11/22 - 22h30">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Inscription_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/Inscription_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Log/log_file.log" beforeDir="false" afterPath="$PROJECT_DIR$/Log/log_file.log" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Template/MySy_Demande_Info_Class_tpl.html" beforeDir="false" afterPath="$PROJECT_DIR$/Template/MySy_Demande_Info_Class_tpl.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Session_Formation.py" beforeDir="false" afterPath="$PROJECT_DIR$/Session_Formation.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Template/MySy_confirmation_Pre_inscription_formation.html" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/class_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/class_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/data_indexees.csv" beforeDir="false" afterPath="$PROJECT_DIR$/data_indexees.csv" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ela_factures_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/ela_factures_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ela_output_test_file_pandas_2.txt" beforeDir="false" afterPath="$PROJECT_DIR$/ela_output_test_file_pandas_2.txt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/email_inscription_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/email_inscription_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/email_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/email_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -105,7 +105,14 @@
<option name="project" value="LOCAL" />
<updated>1669114207155</updated>
</task>
<option name="localTasksCounter" value="6" />
<task id="LOCAL-00006" summary="22/11/22 - 22h30">
<created>1669153439012</created>
<option name="number" value="00006" />
<option name="presentableId" value="LOCAL-00006" />
<option name="project" value="LOCAL" />
<updated>1669153439012</updated>
</task>
<option name="localTasksCounter" value="7" />
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
@ -124,7 +131,8 @@
<MESSAGE value="sss - init new pc" />
<MESSAGE value="18/11/22 - 23h30" />
<MESSAGE value="22/11/22 - 11h30" />
<option name="LAST_COMMIT_MESSAGE" value="22/11/22 - 11h30" />
<MESSAGE value="22/11/22 - 22h30" />
<option name="LAST_COMMIT_MESSAGE" value="22/11/22 - 22h30" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>

View File

@ -562,6 +562,11 @@ def SendPre_InscriptionEmail(diction):
# 1 - Recuperation des données de la formation
local_class = MYSY_GV.dbname['myclass'].find({'internal_url':str(diction['class_internal_url'])})
data_mail['title'] = local_class[0]['title']
partner_recid = local_class[0]['partner_owner_recid']
# 1-BIS : Recuperation des donnees de l'editeur de la formation
local_partner = MYSY_GV.dbname['partnair_account'].find_one({'recid':str(partner_recid)})
data_mail['partner_mail'] = local_partner['email']
# 2 - Recuperation des données de l'inscription
@ -575,9 +580,18 @@ def SendPre_InscriptionEmail(diction):
data_mail['date_du'] = local_session[0]['date_du']
data_mail['date_au'] = local_session[0]['date_au']
data_mail['adresse'] = local_session[0]['adresse']
data_mail['employeur'] = local_session[0]['employeur']
data_mail['telephone'] = local_session[0]['telephone']
# Envoi de l'email de confirmation au demandeur de la formation
local_status, local_message = email_session.Pre_incription_training_confirmation_mail(data_mail)
# Envoi de l'email de notification au formateur
local_status, local_message = email_session.Notification_partner_Pre_incription_mail(data_mail)
return local_status, "La confirmation de la pre-inscription a bien ete envoyée"
except Exception as e:

File diff suppressed because one or more lines are too long

View File

@ -268,7 +268,7 @@ def GetActiveSessionFormation_List(diction):
myquery['session_status'] = "true"
print(" ##### myquery = "+str(myquery))
#print(" ##### myquery = "+str(myquery))
RetObject = []
for retval in coll_session.find(myquery):

View File

@ -1,152 +0,0 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!--[if gtemso 9]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml><![endif]-->
<title>MySy Prise en compte de votre demande inscription </title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width">
<style>
html, body {
font-family: 'Arial', sans-serif;
}
</style>
</head>
<body bgcolor="#fff" style="margin:0px; padding:0px; -webkit-text-size-adjust:none;"><!--[if gtemso 9]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml><![endif]-->
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width"><!--[if gtemso 9]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml><![endif]-->
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width">
<table bgcolor="#fff" border="0" cellpadding="0" cellspacing="0" height="100%" style="margin:0 auto;" width="100%">
<tbody>
<tr>
<td align="center" bgcolor="#C0C0C0" height="100%" width="600">
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td bgcolor="#104277" height="69" style="height:69px;" width="600">
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td align="center" height="69" style="height:69px;" valign="middle" width="600"><img alt="Mysy Training Logo" src="https://img.mysy-training.com/MYSY-LOGO-WHITE.png" alt="Mysy Training Logo" width="18%" style="display: block;" /></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td bgcolor="#fff" height="165" style="height:165px;" width="600">
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td align="center" height="165" style="height:165px; padding-left: 10px; padding-right: 10px;" valign="middle" width="600">
<div style="display: block;">
<div style="margin-left: auto; margin-right: auto">
<div style="text-align: center; font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: small; line-height: 1.4rem;color: #3b3e40;">
<p style="font-size:small; font-weight:bold; margin-top: 1rem;">Votre demande d'inscription à la formation : {{ params.title }}</p>
<p> Bonjour {{params.nom}} {{params.prenom}}</p>
<p style="text-align:justify">
<p style="text-align:justify">
Votre demande d'inscription à la session de formation :
<font color="green"
weight="bold"> {{params.title}} </font> qui se tiendra
<font color="green"
weight="bold">du {{params.date_du}} au {{params.date_fin}} </font> a bien été prise en compte.
</p>
{% if params.adresse == "enligne" %}
<p style="text-align:justify">­
Pour rappel, il s'agit d'une formation <font color="green"
weight="bold">en ligne. </font>
</p>
{% else %}
<p style="text-align:justify">­
Cette formation se tiendra au <font color="green"
weight="bold"> {{ params.adresse }}. </font>
</p>
{% endif %}
<p style="text-align:justify">
Notre équipe pédagogique prendra rapidement contact avec vous pour finaliser votre inscription.
</p>
<p style="text-align:justify">
Nous vous remercions d'avoir choisi notre formation.
</p>
</p>
<p style="font-size:x-small;margin-top: 1rem; line-height: normal; margin-bottom: 1rem;">
Cordialement<br/>
MySy Training Technology<br/>
Contact : +337 69 20 39 45<br/>
Email : contact@mysy-training.com<br/>
</p>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td bgcolor="#104277" width="600">
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td align="center" valign="middle" width="600">
<div style="
padding: 10px 20px;
margin-bottom: 1rem;
color: #ffffff;
">
<p style="font-size:xx-small; text-align: center;font-family: Verdana, Geneva, Tahoma, sans-serif;">
Cet email a été envoyé à {{params.email}} <br />
Ce mail vous est adressé par MYSY Training dont le siège social est situé au 1 Cr du Havre, 75008 Paris. Conformément à la Loi Informatique et Liberté Loi n° 78-17 du 6 janvier 1978 modifiée et au Règlement Général sur la Protection des Données Règlement (UE) 2016/679 du Parlement européen et du Conseil du 27 avril 2016 dit RGPD, vous disposez d'un droit d'accès, de rectification, d'effacement, de limitation et d'opposition au traitement de vos données. Vous pouvez exercer vos droits par courrier postal envoyé à : MYSY Training 1 Cr du Havre, 75008 Paris ou par mail : contact@mysy-training.com.
<br/>
<a href="#">Se désinscrire</a><br/>
</p>
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</body>
</html>

View File

@ -458,6 +458,10 @@ def add_class(diction):
mydata['indexed_desc'] = '0'
mydata['indexed_obj'] = '0'
# A supprimer apres
mydata['freeacces'] = '1'
# fin à supprimer
# Create internal ref. of class
mydata['internal_code'] = mycommon.Create_internal_call_ref()
@ -873,6 +877,11 @@ def update_class(diction):
mydata['datelieu'] = tab_dl
mydata['date_update'] = str(datetime.now())
# A supprimer apres
mydata['freeacces'] = '1'
# fin à supprimer
mydata['indexed'] = '0'
mydata['indexed_title'] = '0'
mydata['indexed_desc'] = '0'
@ -2000,6 +2009,168 @@ def get_partner_class(diction):
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e)+" - Line : "+ str(exc_tb.tb_lineno) )
return False, " Impossible de recuperer la formation"
"""
Cette fonction recherche des formations avec une recherche large (like %value%)
"""
def find_partner_class_like(diction):
try:
'''
# Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
# Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
# Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
# field_list.
'''
field_list = ['internal_url', 'token', 'title', 'valide', 'locked', 'external_code']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - get_partner_class : Le champ '" + val + "' n'existe pas, Creation formation annulée")
return False, " Impossible de recuperer la formation"
'''
Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
On controle que les champs obligatoires sont presents dans la liste
'''
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 liste ")
return False, " Impossible de recuperer la formation"
# recuperation des paramettre
mydata = {}
my_external_code = ""
my_token = ""
my_internal_url = ""
if ("internal_url" in diction.keys()):
if diction['internal_url']:
my_internal_url = diction['internal_url']
if ("external_code" in diction.keys()):
if diction['external_code']:
my_external_code = diction['external_code']
if ("token" in diction.keys()):
if diction['token']:
my_token = diction['token']
'''
Gestion des filters.
'''
internal_url_crit = {}
if ("internal_url" in diction.keys()):
if diction['internal_url']:
internal_url_crit['internal_url'] = diction['internal_url']
external_code_crit = {}
if ("external_code" in diction.keys()):
if diction['external_code']:
external_code_crit['external_code'] = diction['external_code']
title_crit = {}
if ("title" in diction.keys()):
if diction['title']:
title_crit['title'] = diction['title']
coll_name = MYSY_GV.dbname['myclass']
# verifier que le token et l'email sont ok
coll_token = MYSY_GV.dbname['user_token']
# Verification de la validité du token dans le cas des user en mode connecté
'''
/!\ Important : le token ne doit jamais etre vide car cette fonction a pour objectif
de retourner les formation edité par un partenaire.
Il dont obligatoirement est en mode connecté
'''
user_recid = "None"
# Verification de la validité du token/mail dans le cas des user en mode connecté
if (len(str(my_token)) > 0):
retval = mycommon.check_partner_token_validity("", my_token)
if retval is False:
mycommon.myprint(str(inspect.stack()[0][3]) + " - Le token n'est pas valide")
return False, " Impossible de recuperer la formation"
# Recuperation du recid de l'utilisateur
user_recid = mycommon.get_parnter_recid_from_token(my_token)
if user_recid is False:
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de recuperer le token de l'utilisateur")
return False, " Impossible de recuperer la formation"
if (len(str(my_token)) <= 0):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Le token est vide")
return False, " Impossible de recuperer la formation"
RetObject = []
filt_external_code = {}
if ("external_code" in diction.keys()):
filt_external_code = {'external_code':{'$regex': str(diction['external_code'])}}
# print(" GRRRRRRRRRRRRR "+str(filt_external_code))
filt_title = {}
if ("title" in diction.keys()):
filt_title = {'title': {'$regex': str(diction['title'])}}
filt_internal_url = {}
if ("internal_url" in diction.keys()):
filt_internal_url = {'internal_url': {'$regex': str(diction['internal_url'])}}
# print(" filt_internal_url GRRRRRRRRRRRRRRRRRRRRrr "+str(filt_internal_url))
print(
" ATTTTENNTION : GESTION DU CAS OU LA PERSONNE QUI CHERCHE LE COURS EST UN UTILISATEUR : PB avec : partner_owner_recid ")
print(" #### avant requete get partner_owner_recid =" + str(user_recid) +
" filt_external_code = " + str(filt_external_code) +
" filt_internal_url = " + str(filt_internal_url) +
" filt_title = " + str(filt_title))
val_tmp = 1
for retVal in coll_name.find({"$and": [{'valide': '1'}, {'locked': '0'},
{'partner_owner_recid': user_recid},
filt_external_code, filt_title, filt_internal_url]},
):
# mycommon.myprint(str(retVal))
user = retVal
user['id'] = str(val_tmp)
'''
Pour des facilité d'affichage coté front
on va reformater le champ "zone_diffusion" de sorte à le renvoyer
sous la forme "code_pays-ville"
'''
i = 0
tmp_zone_diffusion = ""
if ("zone_diffusion" in user.keys()):
if (user['zone_diffusion'] and user['zone_diffusion']["city"]):
for tmp_val in user['zone_diffusion']["city"]:
tmp_zone_diffusion = tmp_zone_diffusion + str(user['zone_diffusion']["country"][i]) + "-" + str(
user['zone_diffusion']["city"][i]) + ";"
i = i + 1
user['zone_diffusion_str'] = str(tmp_zone_diffusion[:-1])
RetObject.append(JSONEncoder().encode(user))
val_tmp = val_tmp + 1
# print(str(RetObject))
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 recuperer la formation"
"""
Cette fonction retrourne
- le code externe,

View File

@ -1,4 +1,4 @@
,index,mots,occurence,moyenne,id_formation,source_field
0,0,effect,1,0.33,VP14120,title
1,1,essentiel,1,0.33,VP14120,title
2,2,after,1,0.33,VP14120,title
0,0,connecte,1,0.33,Edu_10003,title
1,1,objet,1,0.33,Edu_10003,title
2,2,iot,1,0.33,Edu_10003,title

1 index mots occurence moyenne id_formation source_field
2 0 0 effect connecte 1 0.33 VP14120 Edu_10003 title
3 1 1 essentiel objet 1 0.33 VP14120 Edu_10003 title
4 2 2 after iot 1 0.33 VP14120 Edu_10003 title

View File

@ -1,4 +1,4 @@
mots occurence moyenne id_formation source_field
0 effect 1 0.33 VP14120 title
1 essentiel 1 0.33 VP14120 title
2 after 1 0.33 VP14120 title
mots occurence moyenne id_formation source_field
0 connecte 1 0.33 Edu_10003 title
1 objet 1 0.33 Edu_10003 title
2 iot 1 0.33 Edu_10003 title

View File

@ -267,14 +267,7 @@ def Pre_incription_training_confirmation_mail(diction):
print(" ### Adresse = "+str(diction['adresse']) )
"""send_smtp_email = sib_api_v3_sdk.SendSmtpEmail(template_id=2, params={ "nom": str(diction['nom']),
"prenom":str(diction['prenom']),
"date_du": str(diction['date_du']),
"date_fin": str(diction['date_au']),
"adresse": str(diction['adresse']),
"title":str(diction['title'])},
to=to, bcc=bcc )
"""
# msg = MIMEMultipart("alternative")
msg = EmailMessage()
smtpserver = smtplib.SMTP(MYSY_GV.O365_SMTP_COUNT_smtpsrv, MYSY_GV.O365_SMTP_COUNT_port)
@ -283,7 +276,7 @@ def Pre_incription_training_confirmation_mail(diction):
# JINJA2
templateLoader = jinja2.FileSystemLoader(searchpath="./")
templateEnv = jinja2.Environment(loader=templateLoader)
TEMPLATE_FILE = "Template/MySy_confirmation_Pre_inscription_formation.html"
TEMPLATE_FILE = "Template/MySy_confirmation_Pre_inscription_formation_tpl.html"
template = templateEnv.get_template(TEMPLATE_FILE)
# This data can come from database query
body = {
@ -319,3 +312,86 @@ def Pre_incription_training_confirmation_mail(diction):
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, " Impossible d'envoyer l'email de notification "
"""
Cet email envoie une notfication au l'institut de formation (partenair)
Pour l'informer qu'un utilisateur s'est pre-inscrit
"""
def Notification_partner_Pre_incription_mail(diction):
try:
print(" ### Notification_partner_Pre_incription_mail = "+str(diction))
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['nom', 'prenom', 'email', 'date_du', 'date_au', 'adresse', 'title',
'partner_mail', 'employeur', 'telephone']
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 liste ")
return False, "Impossible d'envoyer l'email de confirmation de l'inscritpion"
tomorrow = datetime.date.today() + datetime.timedelta(days=1)
tomorrow_day = tomorrow.strftime("%A")
print("debut envoi mail de test ")
# on rentre les renseignements pris sur le site du fournisseur
msg = MIMEMultipart("alternative")
msg['Subject'] = 'MySy Training : pre-inscription formation'
msg['From'] = MYSY_GV.O365_SMTP_COUNT_From_User
msg['To'] = str(diction['email'])
print(" ### Adresse = "+str(diction['adresse']) )
# msg = MIMEMultipart("alternative")
msg = EmailMessage()
smtpserver = smtplib.SMTP(MYSY_GV.O365_SMTP_COUNT_smtpsrv, MYSY_GV.O365_SMTP_COUNT_port)
# JINJA2
templateLoader = jinja2.FileSystemLoader(searchpath="./")
templateEnv = jinja2.Environment(loader=templateLoader)
TEMPLATE_FILE = "Template/MySy_Notif_Partner_Pre_inscription_formation_tpl.html"
template = templateEnv.get_template(TEMPLATE_FILE)
# This data can come from database query
body = {
"params":{"nom": str(diction['nom']),
"prenom": str(diction['prenom']),
"date_du": str(diction['date_du']),
"date_fin": str(diction['date_au']),
"adresse": str(diction['adresse']),
"title": str(diction['title']),
"employeur": str(diction['employeur']),
"telephone": str(diction['telephone']),
"email": str(diction['email'])},
}
sourceHtml = template.render(params=body["params"])
msg.set_content(sourceHtml, subtype='html')
msg['From'] = MYSY_GV.O365_SMTP_COUNT_From_User
msg['Cc'] = 'contact@mysy-training.com'
msg['Subject'] = '[MySy Training] : pre-inscription à la formation '+str(diction['title'])
msg['To'] = str(diction['partner_mail'])
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.login(MYSY_GV.O365_SMTP_COUNT_user, MYSY_GV.O365_SMTP_COUNT_password)
val = smtpserver.send_message(msg)
smtpserver.close()
print(" Email envoyé " + str(val))
return True, " Email bien envoyé"
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, " Impossible d'envoyer l'email de notification "

16
main.py
View File

@ -330,10 +330,24 @@ elle est appelée exclusivement en mode connecté
def get_partner_class():
# On recupere le corps (payload) de la requete
payload = request.form.to_dict()
print(" ### payload = ",str(payload)+" IP requester = "+str(request.remote_addr))
print(" ### get_partner_class payload = ",str(payload)+" IP requester = "+str(request.remote_addr))
status, retval = cm.get_partner_class(payload)
return jsonify(status=status, message=retval)
"""
Cette API fait une recherche au sens large avec des like
"""
@app.route('/myclass/api/find_partner_class_like/', methods=['POST','GET'])
@crossdomain(origin='*')
def find_partner_class_like():
# On recupere le corps (payload) de la requete
payload = request.form.to_dict()
print(" ### find_partner_class_like payload = ",str(payload)+" IP requester = "+str(request.remote_addr))
status, retval = cm.find_partner_class_like(payload)
return jsonify(status=status, message=retval)
"""
Cette API retourne le code externe de toutes les formations