16/02/26 - 18h30

Signed-off-by: Cherif <cbalde@mysy-training.com>
master_Elyos_FI
Cherif 2026-02-16 18:27:24 +01:00
parent cff867654d
commit 6ba4292ae3
12 changed files with 4239 additions and 64 deletions

View File

@ -4,19 +4,19 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="12/02/26 - 10h30">
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="15/02/26 - 18h30">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Dashbord_queries/BPF.py" beforeDir="false" afterPath="$PROJECT_DIR$/Dashbord_queries/BPF.py" 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$/activite_pedagogique.py" beforeDir="false" afterPath="$PROJECT_DIR$/activite_pedagogique.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/bloc_competence.py" beforeDir="false" afterPath="$PROJECT_DIR$/bloc_competence.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/groupe_inscrit_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/groupe_inscrit_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/jury_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/jury_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Session_Formation.py" beforeDir="false" afterPath="$PROJECT_DIR$/Session_Formation.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/code_promo_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/code_promo_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" />
<change beforePath="$PROJECT_DIR$/note_evaluation_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/note_evaluation_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/notes_apprenant_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/notes_apprenant_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ressources_materiels.py" beforeDir="false" afterPath="$PROJECT_DIR$/ressources_materiels.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/session_admission_fi.py" beforeDir="false" afterPath="$PROJECT_DIR$/session_admission_fi.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/partner_invoice.py" beforeDir="false" afterPath="$PROJECT_DIR$/partner_invoice.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/partners.py" beforeDir="false" afterPath="$PROJECT_DIR$/partners.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/stage_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/stage_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tools_cherif/tools_cherif.py" beforeDir="false" afterPath="$PROJECT_DIR$/tools_cherif/tools_cherif.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -460,7 +460,7 @@
<option name="project" value="LOCAL" />
<updated>1747251650255</updated>
</task>
<option name="localTasksCounter" value="532" />
<option name="localTasksCounter" value="533" />
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
@ -502,7 +502,6 @@
</option>
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="22/10*2025 - 22h" />
<MESSAGE value="26/10/2025 - 15h" />
<MESSAGE value="29/10/2025 - 22h" />
<MESSAGE value="04/11/2025 - 12h" />
@ -527,6 +526,7 @@
<MESSAGE value="10/02/26 - 20h" />
<MESSAGE value="12/02/26 - 10h" />
<MESSAGE value="12/02/26 - 10h30" />
<option name="LAST_COMMIT_MESSAGE" value="12/02/26 - 10h30" />
<MESSAGE value="15/02/26 - 18h30" />
<option name="LAST_COMMIT_MESSAGE" value="15/02/26 - 18h30" />
</component>
</project>

View File

@ -358,7 +358,7 @@ def Get_Qery_Generate_BPF_From_partner_invoice_header(diction):
bpf_c2_type_apprenant = []
total_bpf_c_type_apprenant = 0
for retval in MYSY_GV.dbname['partner_invoice_header'].aggregate(C2_pipe_qry_invoice_header_partner__invoice_line_detail__partner_type_organisme_financement__type_apprenant):
print(" ### retval = ", retval)
#print(" ### retval = ", retval)
node = {}
node['Type_Apprenant_Code'] = retval['_id']['Type_Apprenant']
node['Type_Apprenant_Desc'] = retval['_id']['Type_Apprenant_Description']
@ -480,7 +480,7 @@ def Get_Qery_Generate_BPF_From_partner_invoice_header(diction):
total_bpf_c3_c8_type_pouvoir_public = 0
for retval in MYSY_GV.dbname['partner_invoice_header'].aggregate(
C3_C8_pipe_qry_invoice_header_partner__invoice_line_detail__partner_type_pouvoir_public):
print(" bpf_c3_c8_type_pouvoir_public ### retval = ", retval)
#print(" bpf_c3_c8_type_pouvoir_public ### retval = ", retval)
node = {}
node['Type_pouvoir_public_desc'] = retval['_id']['Type_pouvoir_public_desc']
node['TotalAmount_HT'] = retval['TotalAmount_HT']
@ -1593,7 +1593,7 @@ def Prepare_and_Print_BPF_PDF(diction):
total_bpf_c_type_apprenant = 0
for retval in MYSY_GV.dbname['partner_invoice_header'].aggregate(
C2_pipe_qry_invoice_header_partner__invoice_line_detail__partner_type_organisme_financement__type_apprenant):
print(" ### retval = ", retval)
#print(" ### retval = ", retval)
node = {}
node['Type_Apprenant_Code'] = retval['_id']['Type_Apprenant']
node['Type_Apprenant_Desc'] = retval['_id']['Type_Apprenant_Description']
@ -1711,7 +1711,7 @@ def Prepare_and_Print_BPF_PDF(diction):
total_bpf_c3_c8_type_pouvoir_public = 0
for retval in MYSY_GV.dbname['partner_invoice_header'].aggregate(
C3_C8_pipe_qry_invoice_header_partner__invoice_line_detail__partner_type_pouvoir_public):
print(" bpf_c3_c8_type_pouvoir_public ### retval = ", retval)
#print(" bpf_c3_c8_type_pouvoir_public ### retval = ", retval)
node = {}
node['Type_pouvoir_public_desc'] = retval['_id']['Type_pouvoir_public_desc']
node['TotalAmount_HT'] = retval['TotalAmount_HT']

View File

@ -9670,6 +9670,444 @@ def Get_Statgaire_List_Partner_with_filter(diction):
"""
Cette fonction récupérer la liste des stagiaire d'un partenaire.
On y ajoute la formation concernée - version light pour alleger la recherche
"""
def Get_Statgaire_List_Partner_with_filter_light(diction):
try:
field_list = ['token', 'session_id', 'archive', 'with_alert']
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é, Creation partenaire annulée")
return False, "Toutes les informations fournies ne sont pas valables"
"""
Verification de la liste 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, "Toutes les informations necessaires n'ont pas été fournies"
# Recuperation du recid du partner
mydata = {}
mytoken = ""
if ("token" in diction.keys()):
if diction['token']:
mytoken = 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
partner_recid = my_partner['recid']
"""
30/07/2024 - Pour la gestion du recyclage, recuperer les paramettres du partner dans la collection "base_partner_setup"
- recyclage_warning
- recyclage_warning_lead_time
"""
recyclage_warning = "0"
recyclage_warning_lead_time = "0"
partner_base_setup_recyclage_warning = MYSY_GV.dbname['base_partner_setup'].find_one({"config_name":'recyclage_warning',
'valide':'1', 'locked':'0',
'partner_owner_recid':my_partner['recid']})
if( partner_base_setup_recyclage_warning and "config_value" in partner_base_setup_recyclage_warning.keys() ):
recyclage_warning = partner_base_setup_recyclage_warning['config_value']
if( recyclage_warning == "1"):
partner_base_setup_recyclage_warning_lead_time = MYSY_GV.dbname['base_partner_setup'].find_one(
{"config_name": 'recyclage_warning_lead_time',
'valide': '1', 'locked': '0',
'partner_owner_recid': my_partner['recid']})
if (partner_base_setup_recyclage_warning_lead_time and "config_value" in partner_base_setup_recyclage_warning_lead_time.keys()):
recyclage_warning_lead_time = str(mycommon.tryInt(str(partner_base_setup_recyclage_warning_lead_time['config_value'])))
"""
Etape 1 : si on a le champ 'code session' saisie par l'utilisateur,
alors on va commencer par aller cherche toutes les session avec un regex de la valeur saisie filter sur le partner_recid
"""
filt_session_code = {}
list_session_id = []
if ("code_session" in diction.keys()):
filt_code_session = {'code_session': {'$regex': str(diction['code_session']), "$options": "i"}}
"""
qry_list_session_id = { { '$and' :[ {'code_session': {'$regex': str(diction['code_session']), "$options": "i"}},
{'partner_owner_recid': str(partner_recid)} ]}, {'_id':1}}
"""
qry_list_session_id = {"$and": [{'code_session': {'$regex': str(diction['code_session']), "$options": "i"}},
{'partner_owner_recid': str(partner_recid)}]}
#print(" ### qry_list_session_id aa = ", qry_list_session_id)
list_session_id_count = MYSY_GV.dbname['session_formation'].count_documents(qry_list_session_id)
if( list_session_id_count <= 0 ):
# Aucune session
return True, []
for val in MYSY_GV.dbname['session_formation'].find(qry_list_session_id):
list_session_id.append(str(val['_id']))
#print(" ### liste des Id des sessions eligible list_session_id = ", list_session_id)
filt_session_code = {'session_id': {'$in': list_session_id, }}
filt_archive = {}
if ("archive" in diction.keys() and (diction["archive"] == "0" or diction["archive"] == "")):
filt_archive = {'archive': {'$ne': '1'}}
elif ("archive" in diction.keys() and diction["archive"] == "1"):
filt_archive = {'archive': '1'}
elif ("archive" not in diction.keys()):
filt_archive = {'archive': {'$ne': '1'}}
filt_session_id = {}
if ("session_id" in diction.keys()):
filt_session_id = {'session_id': str(diction['session_id'])}
filt_class_partner_recid = {'partner_owner_recid': str(partner_recid)}
#----
query = [{'$match':{ '$and' : [ filt_archive, filt_session_code,
filt_session_id, {'partner_owner_recid':str(partner_recid), 'valide':'1'}] } },
{'$sort': {'_id': -1}},
{'$lookup':
{
'from': 'myclass',
'localField': 'class_internal_url',
'foreignField': 'internal_url',
'pipeline': [{'$match':{ '$and' : [ filt_class_partner_recid] } }, {'$project': {'title': 1, 'domaine': 1,
'duration': 1,
'duration_unit': 1,
'_id':1,
'recyclage_delai':1,
'recyclage_periodicite':1,
'recyclage_alert':1}}],
'as': 'myclass_collection'
}
},
]
print("#### Get_Statgaire_List_Partner_with_filter laa 01 : query = ", query)
RetObject = []
cpt = 0
for retVal in MYSY_GV.dbname['inscription'].aggregate(query):
val = {}
## Ne prendre que les lignes qui on un session valide
# Recuperation des informations de la session
local_qry = {'_id': ObjectId(retVal['session_id']), 'valide': '1'}
# print(" #### local_qry zzz = ", local_qry)
count_session = MYSY_GV.dbname['session_formation'].count_documents(local_qry)
if( count_session == 1 ):
# Verifier si le client est valide
client_valide = "1"
if( "client_rattachement_id" in retVal.keys() and retVal['client_rattachement_id']):
client_rattachement_id_count = MYSY_GV.dbname['partner_client'].count_documents({'_id':ObjectId(retVal['client_rattachement_id']),
'valide':'1',
'locked':'0',
'partner_owner_recid':str(my_partner['recid'])})
if( client_rattachement_id_count <= 0 ):
client_valide = "0"
# Verifier si le client de facturation est valide
client_facturation_valide = "1"
if ("facture_client_rattachement_id" in retVal.keys() and retVal['facture_client_rattachement_id']):
facture_client_rattachement_id_id_count = MYSY_GV.dbname['partner_client'].count_documents(
{'_id': ObjectId(retVal['facture_client_rattachement_id']),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (facture_client_rattachement_id_id_count <= 0):
client_facturation_valide = "0"
if ('myclass_collection' in retVal.keys() and len(retVal['myclass_collection']) > 0 and client_valide == "1" and client_facturation_valide == "1"):
val['id'] = str(cpt)
cpt = cpt + 1
val['_id'] = retVal['_id']
val['session_id'] = retVal['session_id']
val['class_internal_url'] = retVal['class_internal_url']
val['nom'] = retVal['nom']
val['partner_owner_recid'] = retVal['partner_owner_recid']
val['prenom'] = retVal['prenom']
val['email'] = retVal['email']
if ("civilite" in retVal.keys()):
val['civilite'] = str(retVal['civilite']).lower()
else:
val['civilite'] = ""
if (str(val['civilite']) not in MYSY_GV.CIVILITE):
val['civilite'] = "neutre"
if( str(val['civilite']).strip() == ""):
val['civilite'] = "neutre"
if( "modefinancement" in retVal.keys()):
val['modefinancement'] = retVal['modefinancement']
else:
val['modefinancement'] = ""
if ("archive" not in retVal.keys()):
val['archive'] = "0"
if ("opco" in retVal.keys()):
val['opco'] = retVal['opco']
else:
val['opco'] = ""
if ("employeur" in retVal.keys()):
val['employeur'] = retVal['employeur']
else:
val['employeur'] = ""
if ("telephone" in retVal.keys()):
val['telephone'] = retVal['telephone']
else:
val['telephone'] = ""
if ("date_naissance" in retVal.keys() and retVal['date_naissance']):
val['date_naissance'] = retVal['date_naissance']
else:
val['date_naissance'] = ""
if ("adresse" in retVal.keys()):
val['adresse'] = retVal['adresse']
else:
val['adresse'] = ""
if ("code_postal" in retVal.keys()):
val['code_postal'] = retVal['code_postal']
else:
val['code_postal'] = ""
if ("ville" in retVal.keys()):
val['ville'] = retVal['ville']
else:
val['ville'] = ""
if ("pays" in retVal.keys()):
val['pays'] = retVal['pays']
else:
val['pays'] = ""
val['status'] = retVal['status']
val['class_id'] = str(retVal['myclass_collection'][0]['_id'])
val['title'] = retVal['myclass_collection'][0]['title']
if("domaine" in retVal['myclass_collection'][0].keys() ):
val['domaine'] = retVal['myclass_collection'][0]['domaine']
else:
val['domaine'] = ""
client_rattachement_id = ""
client_rattachement_nom = ""
# Si il a un client rattacher, recuperation des information du client
#print(" ### retVal = ", retVal )
if( "client_rattachement_id" in retVal.keys()):
if( retVal['client_rattachement_id'] and str(retVal['client_rattachement_id'] ) != 'undefined'):
client_retval = MYSY_GV.dbname['partner_client'].find_one({'_id':ObjectId( retVal['client_rattachement_id']),
'valide':'1', 'locked':'0'})
if( client_retval is not None):
client_rattachement_id= client_retval['_id']
client_rattachement_nom = client_retval['nom']
val['client_rattachement_id'] = client_rattachement_id
val['client_rattachement_nom'] = client_rattachement_nom
if ("facture_client_rattachement_id" in retVal.keys()):
val['facture_client_rattachement_id'] = retVal['facture_client_rattachement_id']
else:
val['facture_client_rattachement_id'] = ""
# ----
invoiced = ""
if ("invoiced" in retVal.keys()):
invoiced = retVal['invoiced']
val['invoiced'] = invoiced
invoiced_ref = ""
if ("invoiced_ref" in retVal.keys()):
invoiced_ref = retVal['invoiced_ref']
val['invoiced_ref'] = invoiced_ref
invoiced_date = ""
if ("invoiced_date" in retVal.keys()):
invoiced_date = str(retVal['invoiced_date'])[0:10]
val['invoiced_date'] = invoiced_date
financeur_rattachement_id = ""
financeur_rattachement_nom = ""
# Si il a un client rattacher, recuperation des information du client
# print(" ### retVal = ", retVal )
if ("financeur_rattachement_id" in retVal.keys()):
if (retVal['financeur_rattachement_id'] and str(retVal['financeur_rattachement_id']) != 'undefined'):
client_retval = MYSY_GV.dbname['partner_client'].find_one(
{'_id': ObjectId(retVal['financeur_rattachement_id']),
'valide': '1', 'locked': '0'})
if (client_retval is not None):
financeur_rattachement_id = client_retval['_id']
financeur_rattachement_nom = client_retval['nom']
val['financeur_rattachement_id'] = financeur_rattachement_id
val['financeur_rattachement_nom'] = financeur_rattachement_nom
if(count_session != 1 ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de récupérer la liste des stagiaires, Il y a une incohérence sur la session : " + str(
retVal['session_id']))
return False, "Impossible de récupérer la liste des stagiaires, Les informations d'identification sont incorrectes. Il y a une incohérence sur la session : " + str(
retVal['session_id'])
#qry2 = {'class_internal_url':str(retVal['class_internal_url']), 'code_session':str(retVal['session_id']), 'valide':'1'}
#print(" ### qry 2 =", qry2)
session_retval = {} #MYSY_GV.dbname['session_formation'].find_one({'_id':ObjectId(str(retVal['session_id'])), 'valide':'1'})
if ("code_session" in session_retval.keys()):
val['code_session'] = str(session_retval['code_session'])
else:
val['code_session'] = ""
if ("date_debut" in session_retval.keys()):
val['date_du'] = str(session_retval['date_debut'])[0:10]
else:
val['date_du'] = ""
if ("date_fin" in session_retval.keys()):
val['date_au'] = str(session_retval['date_fin'])[0:10]
else:
val['date_au'] = ""
if ("code_postal" in session_retval.keys()):
val['code_postal'] = session_retval['code_postal']
else:
val['code_postal'] = ""
if ("prix_session" in session_retval.keys()):
val['price'] = session_retval['prix_session']
else:
val['price'] = ""
if ("presentiel" in session_retval.keys()):
val['presentiel'] = session_retval['presentiel']
else:
val['presentiel'] = "0"
if ("distantiel" in session_retval.keys()):
val['distantiel'] = session_retval['distantiel']
else:
val['distantiel'] = "0"
if ("session_ondemande" in session_retval.keys()):
val['session_ondemande'] = session_retval['session_ondemande']
else:
val['session_ondemande'] = "0"
"""
Gestion du recyclage d'un apprenant si la formation a laquelle il a participer
necessite un recyclage.
On ne fait ce controle que sur l'inscription 'recyclage_managed' != "1" ou est
"""
val['class_recyclage_delai'] = ""
val['class_recyclage_periodicite'] = ""
val['class_recyclage_alert'] = ""
val['nb_jour_avant_recyclage'] = ""
val['warning_recyclage'] = "0"
if( "with_alert" in diction.keys() and diction['with_alert'] == "1"):
if(retVal['status'] == "1" and ("recyclage_managed" not in retVal.keys() or retVal['recyclage_managed'] != "1") ):
if ("recyclage_delai" in retVal['myclass_collection'][0].keys()):
val['class_recyclage_delai'] = retVal['myclass_collection'][0]['recyclage_delai']
if ("recyclage_periodicite" in retVal['myclass_collection'][0].keys()):
val['class_recyclage_periodicite'] = retVal['myclass_collection'][0]['recyclage_periodicite']
if ("recyclage_alert" in retVal['myclass_collection'][0].keys()):
val['class_recyclage_alert'] = retVal['myclass_collection'][0]['recyclage_alert']
if (str(val['class_recyclage_delai']) != "" and str(val['class_recyclage_periodicite']) != "" and str(val['class_recyclage_alert']) != "" ):
session_date_debut = str(session_retval['date_debut'])[0:10]
session_date_debut_datetime = datetime.strptime(str(session_date_debut).strip(), '%d/%m/%Y')
if (str(val['class_recyclage_periodicite']) == "mois"):
class_recyclage_delai_int = mycommon.tryInt(str(val['class_recyclage_delai']))
session_date_debut_datetime = session_date_debut_datetime + relativedelta( months=+class_recyclage_delai_int)
elif (str(val['class_recyclage_periodicite']) == "annee"):
class_recyclage_delai_int = mycommon.tryInt(str(val['class_recyclage_delai']))
session_date_debut_datetime = session_date_debut_datetime + relativedelta( years=+class_recyclage_delai_int)
mytoday = datetime.today().strftime("%d/%m/%Y")
mytoday_datetime = datetime.strptime(str(mytoday).strip(), '%d/%m/%Y')
local_delta = session_date_debut_datetime - mytoday_datetime
val['nb_jour_avant_recyclage'] = str(local_delta.days)
if( local_delta.days < mycommon.tryInt(str(val['class_recyclage_alert'])) ):
val['warning_recyclage'] = "1"
RetObject.append(mycommon.JSONEncoder().encode(val))
#print(" ### RetObject = ", 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) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de récupérer la liste des stagiaires"
"""
Gestion du recyclage :
Cette fonction permet d'acquiter la gestion du recyclage d'une inscription

File diff suppressed because one or more lines are too long

View File

@ -1365,7 +1365,7 @@ def GetActiveSessionFormation_List(diction):
final_qry = {"$and":[myquery,filt_archive, filt_type_session, filt_class_id, filt_class_internal_url]}
print(" ### GetActiveSessionFormation_List final_qry = ", final_qry)
for retval in coll_session.find({"$and":[myquery,filt_archive, filt_type_session, filt_class_id, filt_class_internal_url]} ):
print(" ### retval = ", retval)
#print(" ### retval = ", retval)
local_tmp = retval
if ("archive" not in local_tmp.keys()):
@ -1585,7 +1585,7 @@ def GetActiveSession_Cities_And_Distance_Formation_List(diction):
RetObject = []
print(" ### GetActiveSession_Cities_And_Distance_Formation_List myquery = ", myquery)
print(" ### GetActiveSession_Cities_And_Distance_Formation_List myquery = ", )
for retval in coll_session.find(myquery):
local_tmp = retval
@ -12281,8 +12281,8 @@ def Invoice_Inscrption_With_Split_Session_By_Inscription_Id( tab_files, diction)
local_diction_for_NOT_INVOICE_SPLIT)
print(" ### status = ", status)
print(" ### retval = ", retval)
#print(" ### status = ", status)
#print(" ### retval = ", retval)
print(" ### local_diction_for_NOT_INVOICE_SPLIT invoice_ref = ", invoice_ref)
if (status is False):
return False, str(retval), False
@ -12308,8 +12308,8 @@ def Invoice_Inscrption_With_Split_Session_By_Inscription_Id( tab_files, diction)
print(" ### local_diction_for_WITH_INVOICE_SPLIT = ", local_diction_for_WITH_INVOICE_SPLIT)
status, retval, invoice_ref = Invoice_Splited_Partner_From_Session_By_Inscription_Id( local_diction_for_WITH_INVOICE_SPLIT)
print(" ### status = ", status)
print(" ### retval = ", retval)
#print(" ### status = ", status)
#print(" ### retval = ", retval)
print(" ### local_diction_for_WITH_INVOICE_SPLIT invoice_ref = ", invoice_ref)
list_splited_invoice = str(invoice_ref).replace('[', '').replace(']', '').replace("'", "")
@ -14963,7 +14963,7 @@ def Invoice_Create_Secure_E_Document(diction):
for retval in MYSY_GV.dbname['partner_invoice_line'].aggregate(query):
if ('myclass_collection' in retval.keys() and len(retval['myclass_collection']) > 0):
print(" ### retval = ", retval)
#print(" ### retval = ", retval)
user = {}
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1

View File

@ -508,7 +508,7 @@ def Get_Given_Code_Promo(diction):
nb_val = 0
is_code_promo_expired = "0"
for retval in coll_session.find(myquery):
print(" ##### retval = " + str(retval))
#print(" ##### retval = " + str(retval))
debut_debut = datetime.strptime(str(retval['date_debut']).strip(), '%d/%m/%Y')
date_fin = datetime.strptime(str(retval['date_fin']).strip(), '%d/%m/%Y')
if (debut_debut <= datetime.now() and date_fin >= datetime.now() and retval['type'] in ['fix', 'percent'] ):

View File

@ -2512,7 +2512,7 @@ def ManualSendInvoiceEmailRIB_CIC_JMJFormation(diction):
body = {
"params": {"order_id": "MTT/2025_N°0012/JMJ FORMATION",
"date_order": ": 14/07/2025",
"periode":"14/01/2026 au 13/02/2026",
"periode":"13/02/2026 au 14/03/2026",
"total_ht": "130",
"tva": "11.05",
"total_ttc": "141,05 ",
@ -2528,9 +2528,9 @@ def ManualSendInvoiceEmailRIB_CIC_JMJFormation(diction):
"montant": "130 €",
"invoice_id": "FACT_20260116",
"invoice_date": "18/01/2026",
"due_date": "18/01/2026",
"invoice_id": "FACT_20260217",
"invoice_date": "15/02/2026",
"due_date": "15/02/2026",
"orign_order": "Contrat MTT/2025_N°0012/JMJ FORMATION",
}
}
@ -2614,56 +2614,44 @@ def ManualSendInvoiceEmailRIB_CIC_Xcelia(diction):
# JINJA2
templateLoader = jinja2.FileSystemLoader(searchpath="./")
templateEnv = jinja2.Environment(loader=templateLoader)
TEMPLATE_FILE = "Template/MySy_Invoice_RIB_PortCities_Perso_tpl.html"
TEMPLATE_FILE = "Template/invoice_RIB_Xcelia_perso_tpl.html"
template = templateEnv.get_template(TEMPLATE_FILE)
body = {
"params": {"order_id": "N/A",
"date_order": ": 29/10/2025",
"periode":"",
"total_ht": "130",
"tva": "11.05",
"total_ttc": "141,05 ",
"total_ht": "4 690",
"tva": "TVA non applicable Prestations situées hors UE",
"total_ttc": "4 690 ",
"client_name": "XCELIA Consulting",
"client_address": "KOBAYA",
"client_zip_ville": "C/RATOMA",
"client_pays": "CONAKRY-GUINEE",
"packs": "ELYOS - Initialisation de la plateforme de démonstration client ",
"packs": "ELYOS - Initialisation et configuration de la plateforme de démonstration client ",
"detail_packs": "Mise à disposition dune plateforme standard opérationnelle"
"Location et maintenance du serveur sur 12 mois ",
"Prestation de location et maintenance du serveur période de 12 mois ",
"qty": "1",
"unit_price": "130 €",
"montant": "130 €",
"unit_price": "4 690 €",
"montant": "4 690 €",
"invoice_id": "FACT_20251215",
"invoice_date": "21/12/2025",
"due_date": "21/12/2025",
"orign_order": "Contrat MTT/2025_N°0012/JMJ FORMATION",
"invoice_id": "FACT_20260220",
"invoice_date": "15/02/2026",
"due_date": "15/02/2026",
"orign_order": "PROTOCOLE DENTENTE MTT & XCELIA CONSULTING du le 29 Octobre 2025",
}
}
#print(" ### body 1 = ", body)
sourceHtml = template.render(params=body["params"])
#sourceHtml = template.render(params=body["params"])
sourceHtml = template.render(json_data=body["params"])
"""msg.set_content(sourceHtml, subtype='html')
msg['From'] = MYSY_GV.O365_SMTP_COUNT_From_User
msg['Bcc'] = 'contact@mysy-training.com'
msg['Subject'] = "[MySy Training Technology] : Votre facture N° FACT_230500030"
msg['To'] = 'billardman1@gmail.com'
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))
### CREATION DE LA FACTION PDF
templateLoader = jinja2.FileSystemLoader(searchpath="./")
templateEnv = jinja2.Environment(loader=templateLoader)
#TEMPLATE_FILE = "Template/MySy_Invoice_RIB_tpl.html"
TEMPLATE_FILE = "Template/invoice_RIB_PortCities_perso_tpl.html"
TEMPLATE_FILE = "Template/invoice_RIB_Xcelia_perso_tpl.html"
template = templateEnv.get_template(TEMPLATE_FILE)
# This data can come from database query
@ -2671,7 +2659,7 @@ def ManualSendInvoiceEmailRIB_CIC_Xcelia(diction):
#print(" ### body 22 = ", body)
sourceHtml = template.render(json_data=body["params"])
orig_file_name = "invoice_FACT_20251215.pdf"
orig_file_name = "invoice_FACT_20260220.pdf"
outputFilename = str(MYSY_GV.INVOICE_DIRECTORY) + str(orig_file_name)
# open output file for writing (truncated binary)

55
main.py
View File

@ -941,6 +941,22 @@ def update_partner_account():
return jsonify(status=status, message=retval)
'''
Cette fonction modifie/MAJ les donnes d'un employé utilisateut du systeme
'''
@app.route('/myclass/api/update_partner_account_employee_account/', methods=['POST','GET'])
@crossdomain(origin='*')
def update_partner_account_employee_account():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### update_partner_account_employee_account payload = ",payload)
status, retval = pa.update_partner_account_employee_account(payload)
return jsonify(status=status, message=retval)
"""
API de suppression d'une image enregistrer dans la collection 'mysy_images"
en input, on prend le recid
@ -2073,7 +2089,7 @@ par exemple lorsqu'une personne lambda affiche les formation
def getRecodedClassImage_no_token():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### getRecodedClassImage_no_token payload = ",payload)
print(" ### getRecodedClassImage_no_token payload = ",)
status, myimg= mycommon.getRecodedClassImage_no_token(payload)
return jsonify(status=status, message=myimg)
@ -2533,7 +2549,7 @@ API de recuperation des villes les sessions de formation valides et actives
def GetActiveSession_Cities_And_Distance_Formation_List():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### GetActiveSession_Cities_And_Distance_Formation_List : payload = ",str(payload))
print(" ### GetActiveSession_Cities_And_Distance_Formation_List : payload = ",)
localStatus, message= SF.GetActiveSession_Cities_And_Distance_Formation_List(payload)
return jsonify(status=localStatus, message=message )
@ -3254,6 +3270,25 @@ def ManualSendInvoiceEmailRIB_CIC_JMJFormation():
"""
API Creation manuelle d'une facture avec RIB CIC pour Xcelia - perso
"""
@app.route('/myclass/api/ManualSendInvoiceEmailRIB_CIC_Xcelia/', methods=['POST','GET'])
@crossdomain(origin='*')
def ManualSendInvoiceEmailRIB_CIC_Xcelia():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### ManualSendInvoiceEmailRIB_CIC_Xcelia : payload = ",str(payload))
localStatus, message= emails.ManualSendInvoiceEmailRIB_CIC_Xcelia(payload)
return jsonify(status=localStatus, message=message )
"""
API Creation manuelle d'une facture avec RIB CIC pour France Active - perso
"""
@ -5425,6 +5460,22 @@ def Get_Statgaire_List_Partner_with_filter():
return jsonify(status=status, message=retval)
"""
API qui recupere la liste complete des stagaire d'un partener - version light pour alleger la recherche
"""
@app.route('/myclass/api/Get_Statgaire_List_Partner_with_filter_light/', methods=['POST','GET'])
@crossdomain(origin='*')
def Get_Statgaire_List_Partner_with_filter_light():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Get_Statgaire_List_Partner_with_filter_light payload = ",payload)
status, retval = inscription.Get_Statgaire_List_Partner_with_filter_light(payload)
return jsonify(status=status, message=retval)
"""
API qui recupere la liste complete des stagaire d'un partener pour seulement les inscription
on ne fait pas de lien avec la collection des apprenant

View File

@ -1346,7 +1346,7 @@ def Get_Given_Partner_Invoice_Lines(diction):
for retval in MYSY_GV.dbname['partner_invoice_line'].aggregate(query):
if ('myclass_collection' in retval.keys() and len(retval['myclass_collection']) > 0):
print(" ### retval = ", retval)
#print(" ### retval = ", retval)
user = {}
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1

View File

@ -935,6 +935,321 @@ def update_partner_account(file_logo=None, file_cachet=None, Folder=None, dictio
return False, "Impossible de mettre à jour le partenaire"
'''
MAJ d'un partenaire.
la clé est l'adresse email principale
'''
def update_partner_account_employee_account(diction=None):
try:
# Dictionnaire des champs utilisables
'''
# 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 = ['contact_nom', 'contact_prenom', 'adr_street', 'adr_city', 'adr_zip', 'adr_country', 'link_linkedin',
'email', 'pwd', 'telephone', 'token', 'link_facebook', 'link_twitter',
'partner_account_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, " Le champ '" + val + "' n'est pas accepté "
'''
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 la liste des arguments ")
return False, " La valeur '" + val + "' n'est pas presente dans la liste des arguments "
# recuperation des paramettre
my_email = ""
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_token = diction['token']
# Verifier la validité du token
retval = mycommon.check_partner_token_validity("", my_token)
if retval is False:
return False, " La session de connexion n'est pas valide"
# Recuperation du recid de l'utilisateur
partner_recid = mycommon.get_parnter_recid_from_token(str(my_token))
if partner_recid is False:
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer le recid du partenaire")
return False, " Impossible de mettre à jour le partenaire "
partner_account_id = ""
if ("partner_account_id" in diction.keys()):
partner_account_id = diction['partner_account_id']
# Verification de la validité du compte
is_count_valide = MYSY_GV.dbname['partnair_account'].count_documents(
{'_id': ObjectId(partner_account_id), 'active': '1', 'locked': '0',
'recid': partner_recid})
if (is_count_valide <= 0):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Le compte partner_account_id :" + str(
partner_account_id) + " est invalide")
return False, " Le compte partner_account_id :" + str(partner_account_id) + " est invalide "
if (is_count_valide > 1):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Le compte partner_account_id :" + str(
partner_account_id) + " correspond à plusieurs utilisateurs (" + str(is_count_valide) + ")")
return False, " Le compte partner_account_id :" + str(
partner_account_id) + " correspond à plusieurs utilisateurs "
is_partner_admin_account = "0"
if ("is_partner_admin_account" in diction.keys()):
partner_account_id = diction['is_partner_admin_account']
# print(" #### partner_account_id = ", partner_account_id)
mydata = {}
if ("nom" in diction.keys()):
mydata['nom'] = diction['nom']
if ("subdomaine_catalog_pub" in diction.keys()):
mydata['subdomaine_catalog_pub'] = diction['subdomaine_catalog_pub']
if ("adr_street" in diction.keys()):
mydata['adr_street'] = diction['adr_street']
if ("adr_city" in diction.keys()):
mydata['adr_city'] = diction['adr_city']
if ("adr_zip" in diction.keys()):
mydata['adr_zip'] = diction['adr_zip']
if ("adr_country" in diction.keys()):
mydata['adr_country'] = diction['adr_country']
if ("siret" in diction.keys()):
mydata['siret'] = diction['siret']
if ("num_nda" in diction.keys()):
mydata['num_nda'] = diction['num_nda']
if ("iscertitrace" in diction.keys()):
mydata['iscertitrace'] = diction['iscertitrace']
if ("isbureaucertitrace" in diction.keys()):
mydata['isbureaucertitrace'] = diction['isbureaucertitrace']
if ("iscertifvoltaire" in diction.keys()):
mydata['iscertifvoltaire'] = diction['iscertifvoltaire']
if ("isdatadock" in diction.keys()):
mydata['isdatadock'] = diction['isdatadock']
if ("isqualiopi" in diction.keys()):
mydata['isqualiopi'] = diction['isqualiopi']
if ("website" in diction.keys()):
mydata['website'] = diction['website']
if ("email" in diction.keys()):
my_email = diction['email']
if ("telephone" in diction.keys()):
mydata['telephone'] = diction['telephone']
if ("pwd" in diction.keys()):
mydata['pwd'] = diction['pwd']
if ("contact_nom" in diction.keys()):
mydata['contact_nom'] = diction['contact_nom']
if ("contact_prenom" in diction.keys()):
mydata['contact_prenom'] = diction['contact_prenom']
if ("contact_tel" in diction.keys()):
mydata['contact_tel'] = diction['contact_tel']
if ("contact_mail" in diction.keys()):
mydata['contact_mail'] = diction['contact_mail']
if ("link_linkedin" in diction.keys()):
mydata['link_linkedin'] = diction['link_linkedin']
if ("link_facebook" in diction.keys()):
mydata['link_facebook'] = diction['link_facebook']
if ("link_twitter" in diction.keys()):
mydata['link_twitter'] = diction['link_twitter']
if ("invoice_vat_num" in diction.keys()):
mydata['invoice_vat_num'] = diction['invoice_vat_num']
if ("invoice_taux_vat" in diction.keys()):
mydata['invoice_taux_vat'] = diction['invoice_taux_vat']
if ("invoice_nom" in diction.keys()):
mydata['invoice_nom'] = diction['invoice_nom']
if ("invoice_adr_street" in diction.keys()):
mydata['invoice_adr_street'] = diction['invoice_adr_street']
if ("invoice_adr_city" in diction.keys()):
mydata['invoice_adr_city'] = diction['invoice_adr_city']
if ("invoice_adr_zip" in diction.keys()):
mydata['invoice_adr_zip'] = diction['invoice_adr_zip']
if ("invoice_adr_zip" in diction.keys()):
mydata['invoice_adr_country'] = diction['invoice_adr_country']
if ("invoice_email" in diction.keys()):
mydata['invoice_email'] = diction['invoice_email']
if ("invoice_telephone" in diction.keys()):
mydata['invoice_telephone'] = diction['invoice_telephone']
mydata['update_date'] = str(datetime.now())
# print(str(datetime.now()) + " webservice : diction = " + str(mydata))
coll_name = MYSY_GV.dbname['partnair_account']
"""
Si le compte partenaire n'as pas de compte de payement stripe, alors on profite de cette mise à jour pour le faire
"""
tmp = coll_name.find({'_id': ObjectId(partner_account_id), 'active': '1', 'locked': '0',
'recid': partner_recid})
is_admin_account = "0"
if ("is_partner_admin_account" in tmp[0].keys()):
is_admin_account = tmp[0]['is_partner_admin_account']
if (is_admin_account == "1"):
partnair_stripe_id = ""
if ("stripe_account_id" in tmp[0].keys()):
if tmp[0]['stripe_account_id']:
partnair_stripe_id = tmp[0]['stripe_account_id']
if (partnair_stripe_id is None or len(partnair_stripe_id) < 5):
print('### le partenaire = ' + str(tmp[0]['nom']) + " n'as pas de compte Stripe. on va le créer")
"""
Creation du compte de payement Stripe
"""
my_stripe_data = {}
my_stripe_data['email'] = str(tmp[0]['email'])
my_stripe_data['name'] = str(tmp[0]['nom'])
my_stripe_data['city'] = ""
if ("adr_city" in tmp[0].keys()):
if tmp[0]['adr_city']:
my_stripe_data['city'] = str(tmp[0]['adr_city'])
my_stripe_data['country'] = ""
if ("adr_country" in tmp[0].keys()):
if tmp[0]['adr_country']:
my_stripe_data['country'] = str(tmp[0]['adr_country'])
local_status, part_stripe_account_id = Stripe.create_customer(my_stripe_data)
mydata['stripe_account_id'] = part_stripe_account_id
mydata['stripe_paymentmethod_id'] = ""
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - WARNING : Impossible de créer le compte STRIPE du Client " + str(
tmp[0]['nom']))
ret_val = coll_name.find_one_and_update(
{'_id': ObjectId(partner_account_id), 'locked': '0', 'active': '1'},
{"$set": mydata},
upsert=False,
return_document=ReturnDocument.AFTER
)
if (ret_val is None or '_id' not in ret_val.keys()):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - Impossible de mettre à jour le partenaire recid= : " + str(
partner_recid))
return False, " Impossible de mettre à jour le partenaire"
"""
A present que le partenaire est mis à jour / créé, on va mettre à jour les image logo et image cachet s'il y en a.
Mais seulement pour les comptes admin
"""
if (is_admin_account == "1" and file_logo):
recordimage_diction = {}
recordimage_diction['token'] = diction['token']
recordimage_diction['related_collection'] = "partnair_account"
recordimage_diction['type_img'] = "logo"
recordimage_diction['related_collection_recid'] = str(partner_recid)
recordimage_diction['image_recid'] = diction['file_logo_recid']
# print(" ### recordimage_diction 1 = ", recordimage_diction)
local_status, local_message = mycommon.recordClassImage_v2(file_logo, MYSY_GV.upload_folder,
recordimage_diction)
if (local_status is False):
return local_status, local_message
if (is_admin_account == "1" and file_cachet):
recordimage_diction = {}
recordimage_diction['token'] = diction['token']
recordimage_diction['related_collection'] = "partnair_account"
recordimage_diction['type_img'] = "cachet"
recordimage_diction['related_collection_recid'] = str(partner_recid)
recordimage_diction['image_recid'] = diction['file_cachet_recid']
# print(" ### recordimage_diction 2 = ", recordimage_diction)
local_status, local_message = mycommon.recordClassImage_v2(file_cachet, MYSY_GV.upload_folder,
recordimage_diction)
if (local_status is False):
return local_status, local_message
"""
Update du 28/09/2023 :
On verifie le compte a un 'ressource_humaine_id', si ce n'est pas le cas,
cela veut dire le compte RH associé au compte admin n'a pas été crée.
Il faut donc le faire.
"""
is_valide_rh_compte = False
Parnter_Data = MYSY_GV.dbname['partnair_account'].find_one(
{'recid': str(partner_recid), 'locked': '0', 'active': '1'}, )
if ("ressource_humaine_id" in Parnter_Data.keys()):
if (len(str(Parnter_Data['ressource_humaine_id'])) > 2):
is_valide_rh_compte = True
if (is_valide_rh_compte is False):
data_employe_admin = {}
data_employe_admin['partner_recid'] = str(Parnter_Data['recid'])
data_employe_admin['nom'] = str(Parnter_Data['nom'])
data_employe_admin['email'] = str(Parnter_Data['email'])
data_employe_admin['comment'] = "Compte Administrateur"
data_employe_admin['is_partner_admin_account'] = "1"
data_employe_admin['account_partner_id'] = str(Parnter_Data['_id'])
print(" #### data_employe_admin = ", str(data_employe_admin))
local_status, local_retval_inserted_id = ressources_humaines.Add_Partner_Admin_Ressource_Humaine_No_Toke(
data_employe_admin)
return True, "Le partenaire a bien ete mise à jour"
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 de mettre à jour le partenaire"
'''
cette fonction valide un compte partenaire
La modification ne s'effectue que si le compte n'est pas verrouillé.

View File

@ -19,6 +19,28 @@ autre_disposition => Permet de saisir du texte comme 'assurance', 'horaires',
statut :
- 0 : stage non realisé par l'inscrit
- 1 : stage realisé par l'inscrit
6.4 Gestion administrative
Génération des conventions
Circuit de validation et signature
Gestion documentaire
6.5 Suivi du stage
Déclaration du début de stage
Suivi pédagogique
Gestion des incidents
6.6 Évaluation et validation
Évaluation par lorganisme daccueil
Soutenance
Validation académique
Documents :
o Dépôt du rapport de stage
o Grille dévaluation du maître de stage
o Évaluation du tuteur académique
o Organisation de la soutenance
"""
import ast
from zipfile import ZipFile
@ -739,10 +761,8 @@ def Get_Stage_Inscrit_no_filter(diction):
"""
Suppression d'une compétence
Suppression d'un stage
"""
def Delete_Given_Stage_Inscrit(diction):
try:
@ -805,3 +825,10 @@ def Delete_Given_Stage_Inscrit(diction):
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de supprimer le stage "
"""
6.4 Gestion administrative
Génération des conventions
Circuit de validation et signature
Gestion documentaire
"""

View File

@ -775,7 +775,7 @@ def mysylmsdb():
# Rcuperation de la sequence de l'objet "lms_user_id" dans la collection : "mysy_sequence"
retval = MYSY_GV.dbname['mysy_sequence'].find_one({'related_mysy_object':'lms_user_id', 'valide':'1'})
print(" ### retval = ",retval)
#print(" ### retval = ",retval)
mypasswd = 'sekou'.encode('UTF-8')
salt = bcrypt.gensalt()
@ -891,7 +891,7 @@ def test_web_service(diction):
"""
cpt = 0
for retval in MYSY_GV.dbname['session_formation'].find({'date_by':'automatic'}):
print(" ### retval == ", retval)
#print(" ### retval == ", retval)
if( "class_internal_url" in retval.keys() and retval['class_internal_url']):
class_data = MYSY_GV.dbname['myclass'].find_one({'internal_url':str(retval['class_internal_url'])})