30/01/2026 - 18h

Signed-off-by: Cherif <cbalde@mysy-training.com>
master_Elyos_FI
Cherif 2026-01-30 18:14:29 +01:00
parent c2ac3c4a1a
commit de0648a5bd
13 changed files with 1212 additions and 160440 deletions

View File

@ -5,21 +5,19 @@
</component>
<component name="ChangeListManager">
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="09/01/26 - 20h30">
<change afterPath="$PROJECT_DIR$/session_admission_fi.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Activite.py" beforeDir="false" afterPath="$PROJECT_DIR$/Activite.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/GlobalVariable.py" beforeDir="false" afterPath="$PROJECT_DIR$/GlobalVariable.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Job_Cron.py" beforeDir="false" afterPath="$PROJECT_DIR$/Job_Cron.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Inscription_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/Inscription_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Job_Cron_Common.py" beforeDir="false" afterPath="$PROJECT_DIR$/Job_Cron_Common.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$/Session_Formation.py" beforeDir="false" afterPath="$PROJECT_DIR$/Session_Formation.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/admission_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/admission_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apprenant_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/apprenant_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/attached_file_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/attached_file_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/categorie_formation_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/categorie_formation_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$/formulaire_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/formulaire_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$/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/partner_client.py" beforeDir="false" afterPath="$PROJECT_DIR$/partner_client.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/partner_invoice.py" beforeDir="false" afterPath="$PROJECT_DIR$/partner_invoice.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/prj_common.py" beforeDir="false" afterPath="$PROJECT_DIR$/prj_common.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/session_admission_fi.py" beforeDir="false" afterPath="$PROJECT_DIR$/session_admission_fi.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />

View File

@ -216,6 +216,8 @@ def Add_activite(diction):
data['related_collection_recid'] = str(local_tmp_val['recid'])
data['related_collection_id'] = str(local_tmp_val['_id'])
data['valide'] = '1'
data['locked'] = '0'
data['date_update'] = str(datetime.now())
@ -597,7 +599,7 @@ def Get_List_Entity_Activite(diction):
"""
Verification des input acceptés
"""
field_list = ['token', 'related_collection', 'related_collection_owner_email']
field_list = ['token', 'related_collection', 'related_collection_owner_email', 'related_collection_id']
incom_keys = diction.keys()
for val in incom_keys:
@ -645,7 +647,6 @@ def Get_List_Entity_Activite(diction):
data_cle['partner_recid'] = str(my_partner['recid'])
data_cle['related_collection'] = str(diction['related_collection'])
if ("related_collection_owner_email" in diction.keys()):
related_collection_owner_email = str(diction['related_collection_owner_email'])
"""
@ -668,13 +669,16 @@ def Get_List_Entity_Activite(diction):
data_cle['locked'] = "0"
data_cle['creation_by'] = str(my_partner['_id'])
if ("related_collection_id" in diction.keys()):
data_cle['related_collection_id'] = str(diction['related_collection_id'])
RetObject = []
val_tmp = 0
nb_activite_en_retard = 0
print(" ## activite qry = ", data_cle)
for retval in MYSY_GV.dbname['activite'].find(data_cle):
user = retval
user['id'] = str(val_tmp)
@ -714,6 +718,7 @@ def Get_List_Entity_Activite(diction):
nb_new_activite_assigned_to_me = MYSY_GV.dbname['activite'].count_documents(data_cle)
print(" ## RetObject = ", RetObject)
return True, RetObject, str(nb_activite_en_retard), str(nb_new_activite_assigned_to_me)
@ -1059,7 +1064,7 @@ def Get_Given_Activite(diction):
"""
Verification des input acceptés
"""
field_list = ['token', 'activite_recid']
field_list = ['token', 'activite_recid', '_id']
incom_keys = diction.keys()
for val in incom_keys:
@ -1071,7 +1076,7 @@ def Get_Given_Activite(diction):
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', 'activite_recid']
field_list_obligatoire = ['token',]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
@ -1103,7 +1108,12 @@ def Get_Given_Activite(diction):
"""
data_cle = {}
data_cle['partner_recid'] = str(my_partner['recid'])
data_cle['recid'] = str(diction['activite_recid'])
if("activite_recid" in diction.keys() and diction['activite_recid']):
data_cle['recid'] = str(diction['activite_recid'])
if ("_id" in diction.keys() and diction['_id']):
data_cle['_id'] = ObjectId(str(diction['_id']))
data_cle['valide'] = "1"
data_cle['locked'] = "0"
@ -1118,7 +1128,7 @@ def Get_Given_Activite(diction):
val_tmp = val_tmp + 1
# Si le champ 'employee_assigned_to_id' alors on va chercher le nom et prenom de l'employe au quel est assigné la tache (employe)
if ('employee_assigned_to_id' in retval.keys()):
if ('employee_assigned_to_id' in retval.keys() and retval['employee_assigned_to_id']):
Employee_data = MYSY_GV.dbname['ressource_humaine'].find_one(
{'_id': ObjectId(str(retval['employee_assigned_to_id'])), 'valide': '1', 'locked': '0',
'partner_recid': str(my_partner['recid'])})

View File

@ -1108,3 +1108,15 @@ Statut d'acceptation ou de rejet d'un fichier
- "", rien
"""
DOWLOADED_FILE_ACCEPTANCE_STATUS = ['-1', '1', '']
"""
PROCES Admission : les status (formation initiale
- '-1' => Annulé
- '0' => refuse
- 1 => accepté
- 2 => liste d'attente
- '' => en cours de traitement
"""
PROCESS_ADMISSION_STATUS = ['-1', '0', '1', '2', '']

View File

@ -10543,8 +10543,8 @@ def Sent_Convention_Stagiaire_By_Email(tab_files, Folder, diction):
if(len(tab_emails_destinataire) <= 0 ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune adresse email n'a été fourni. ")
return False, " Aucune adresse email n'a été fourni. "
3]) + " Aucune adresse email n'a pas été fournie. ")
return False, " Aucune adresse email n'a pas été fournie. "
#print(" ### tab_emails_destinataire = ", tab_emails_destinataire)
@ -11168,8 +11168,8 @@ def Sent_Convention_Individuelle_Stagiaire_By_Email(tab_files, Folder, diction):
if (len(tab_emails_destinataire) <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune adresse email n'a été fourni. ")
return False, " Aucune adresse email n'a été fourni. "
3]) + " Aucune adresse email n'a pas été fournie. ")
return False, " Aucune adresse email n'a pas été fournie. "
# print(" ### tab_emails_destinataire = ", tab_emails_destinataire)
@ -12533,8 +12533,8 @@ def Sent_Convention_Stagiaire_By_Email_By_Partner_client(tab_files_name_full_pat
else:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune adresse email n'a été fourni. ")
return False, " Aucune adresse email n'a été fourni. "
3]) + " Aucune adresse email n'a pas été fournie. ")
return False, " Aucune adresse email n'a pas été fournie. "
#print(" ## laaa : tab_emails_destinataire lalala = ", tab_emails_destinataire)

View File

@ -522,8 +522,8 @@ def Sent_Convocation_Stagiaire_By_Email(tab_files, Folder, diction):
if (len(tab_emails_destinataire) <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune adresse email n'a été fourni. ")
return False, " Aucune adresse email n'a été fourni. "
3]) + " Aucune adresse email n'a pas été fournie. ")
return False, " Aucune adresse email n'a pas été fournie. "
# print(" ### tab_emails_destinataire = ", tab_emails_destinataire)
@ -2256,8 +2256,8 @@ def Cron_Sent_Attestation_Stagiaire_By_Email(tab_files, Folder, diction):
if (len(tab_emails_destinataire) <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune adresse email n'a été fourni. ")
return False, " Aucune adresse email n'a été fourni. "
3]) + " Aucune adresse email n'a pas été fournie. ")
return False, " Aucune adresse email n'a pas été fournie. "
# print(" ### tab_emails_destinataire = ", tab_emails_destinataire)

File diff suppressed because one or more lines are too long

View File

@ -1100,6 +1100,8 @@ def GetSessionFormation(diction):
return False, "Impossible de récupérer La promotion de formation"
"""
Recuperer les données d'un session de formation à partir du _Id seulement et token
"""
@ -1303,7 +1305,7 @@ Donc faire attention au controle de la connexion
def GetActiveSessionFormation_List(diction):
try:
field_list = ['token', 'class_internal_url', 'archive', 'type_session']
field_list = ['token', 'class_internal_url', 'archive', 'type_session', 'class_id']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
@ -1314,7 +1316,7 @@ def GetActiveSessionFormation_List(diction):
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = [ 'class_internal_url', ]
field_list_obligatoire = [ ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
@ -1338,18 +1340,21 @@ def GetActiveSessionFormation_List(diction):
if ("type_session" in diction.keys()):
filt_type_session = {'type_session': str(diction['type_session']).strip()}
filt_class_id = {}
if ("class_id" in diction.keys()):
filt_class_id = {'class_id': str(diction['class_id']).strip()}
filt_class_internal_url = {}
if ("class_internal_url" in diction.keys()):
filt_type_session = {'class_internal_url': str(diction['class_internal_url']).strip()}
# Recuperation du recid du partner
mydata = {}
class_internal_url = ""
if ("class_internal_url" in diction.keys()):
if diction['class_internal_url']:
class_internal_url = diction['class_internal_url']
coll_session = MYSY_GV.dbname['session_formation']
myquery = {}
myquery['class_internal_url'] = class_internal_url
myquery['valide'] = "1"
myquery['session_status'] = "1"
@ -1357,9 +1362,10 @@ def GetActiveSessionFormation_List(diction):
RetObject = []
print(" ### GetActiveSessionFormation_List myquery = ", myquery)
for retval in coll_session.find({"$and":[myquery,filt_archive, filt_type_session]} ):
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)
local_tmp = retval
if ("archive" not in local_tmp.keys()):
@ -1421,7 +1427,7 @@ d'un partenaire, mais avec une liste reduite de champs
def Get_Partner_Session_Ftion_Reduice_Fields(diction):
try:
field_list = ['token', 'type_session']
field_list = ['token', 'type_session', 'class_id', 'archive', 'type_session']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
@ -1479,12 +1485,19 @@ def Get_Partner_Session_Ftion_Reduice_Fields(diction):
if ("type_session" in diction.keys()):
filt_type_session = {'type_session': str(diction['type_session']).strip()}
filt_class_id = {}
if ("class_id" in diction.keys()):
filt_class_id = {'class_id': str(diction['class_id']).strip()}
RetObject = []
val_tmp = 0
print("## qrty = ", { "$and" : [ {'partner_owner_recid':str(my_partner['recid']),
'valide':'1',},filt_scope_class_id, filt_scope_session_id, filt_archive, filt_type_session, filt_class_id]})
for retval in MYSY_GV.dbname['session_formation'].find({ "$and" : [ {'partner_owner_recid':str(my_partner['recid']),
'valide':'1',},filt_scope_class_id, filt_scope_session_id, filt_archive, filt_type_session]},
'valide':'1',},filt_scope_class_id, filt_scope_session_id, filt_archive, filt_type_session, filt_class_id]},
{'_id':1, 'code_session':1, 'titre':1,
'class_internal_url':1, 'date_debut':1, 'class_id':1,
'date_fin':1}):
@ -2273,7 +2286,7 @@ def GetAllValideSessionPartner_List_filter_like(diction):
field_list = ['token','class_title', 'code_session', 'class_external_code',
'session_start_date', 'session_end_date',
'class_internal_url', 'archive', 'type_session']
'class_internal_url', 'archive', 'type_session', 'class_id']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
@ -2312,6 +2325,11 @@ def GetAllValideSessionPartner_List_filter_like(diction):
if ("class_title" in diction.keys()):
filt_class_title = {'title': {'$regex': mycommon.regex_replace_cartere(str(diction['class_title'])),"$options": "i"}}
filt_class_id = {}
if ("class_id" in diction.keys()):
filt_class_title = {
'class_id': str(diction['class_id'])}
filt_class_internal_url = {}
if ("class_internal_url" in diction.keys()):
@ -2380,7 +2398,7 @@ def GetAllValideSessionPartner_List_filter_like(diction):
coll_session = MYSY_GV.dbname['session_formation']
query = [ {'$match':{ '$and' : [ filt_code_session,{'partner_owner_recid':str(my_partner['recid'])}, filt_scope_class_id, filt_scope_session_id,
filt_archive, filt_type_session] }} ,
filt_archive, filt_type_session, filt_class_id] }} ,
{'$sort': {'_id': -1}},
{'$lookup':
{
@ -9277,8 +9295,8 @@ def Sent_Convocation_Stagiaire_By_Email(tab_files, Folder, diction):
if (len(tab_emails_destinataire) <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune adresse email n'a été fourni. ")
return False, " Aucune adresse email n'a été fourni. "
3]) + " Aucune adresse email n'a pas été fournie. ")
return False, " Aucune adresse email n'a pas été fournie. "
# print(" ### tab_emails_destinataire = ", tab_emails_destinataire)
@ -9979,8 +9997,8 @@ def Sent_Attestation_Stagiaire_By_Email(tab_files, Folder, diction):
if (len(tab_emails_destinataire) <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune adresse email n'a été fourni. ")
return False, " Aucune adresse email n'a été fourni. "
3]) + " Aucune adresse email n'a pas été fournie. ")
return False, " Aucune adresse email n'a pas été fournie. "
# print(" ### tab_emails_destinataire = ", tab_emails_destinataire)
@ -11731,8 +11749,8 @@ def Sent_Facture_Stagiaire_By_Email_By_Partner_client(tab_files_name_full_path,
else:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune adresse email n'a été fourni. ")
return False, " Aucune adresse email n'a été fourni. "
3]) + " Aucune adresse email n'a pas été fournie. ")
return False, " Aucune adresse email n'a pas été fournie. "
#print(" ## laaa : tab_emails_destinataire lalala = ", tab_emails_destinataire)
@ -13587,7 +13605,7 @@ def Prepare_and_Send_SPLITED_Facture_From_Session_By_Inscription_Id(tab_files, F
"""
Creation des factures pour un client avec uniquement la liste des inscriptions concernées.
Ccreation des factures pour un client avec uniquement la liste des inscriptions concernées.
Ex : je veux facturer que 2 des 5 inscrits d'un client donné.

View File

@ -4647,7 +4647,8 @@ par une soutenance du jury
"""
def Send_Jury_Apprenant_Soutenance_Convocation_By_PDF(diction):
try:
field_list_obligatoire = ['token', 'jury_id', 'tab_jury_soutenance_ids', 'courrier_template_id']
field_list_obligatoire = ['token', 'jury_id', 'tab_jury_soutenance_ids',
'courrier_template_id', 'cible']
for val in field_list_obligatoire:
if val not in diction:
@ -4748,7 +4749,7 @@ def Send_Jury_Apprenant_Soutenance_Convocation_By_PDF(diction):
if( tmp['inscription_id'] ):
tab_soutenance_inscrit.append(str(tmp['inscription_id']))
print(" ### tab_soutenance_inscrit = ", tab_soutenance_inscrit)
#print(" ### tab_soutenance_inscrit = ", tab_soutenance_inscrit)
for val in tab_soutenance_inscrit:
local_diction = {}
@ -4758,12 +4759,22 @@ def Send_Jury_Apprenant_Soutenance_Convocation_By_PDF(diction):
local_diction['courrier_template_id'] = diction['courrier_template_id']
local_diction['inscription_id'] = str(val)
print(" ### local_diction === ", local_diction)
local_status, local_full_file_name = Create_Jury_Soutenance_Convocation_By_Inscrit_PDF(local_diction)
if( local_status is False):
return local_status, local_full_file_name
if( "cible" in diction.keys() and diction['cible'] == "admission"):
local_status, local_full_file_name = Create_Jury_Admission_Soutenance_Convocation_By_Inscrit_PDF(
local_diction)
if (local_status is False):
return local_status, local_full_file_name
else:
list_file_name_to_zip.append(str(local_full_file_name))
else:
list_file_name_to_zip.append(str(local_full_file_name))
local_status, local_full_file_name = Create_Jury_Soutenance_Convocation_By_Inscrit_PDF(local_diction)
if( local_status is False):
return local_status, local_full_file_name
else:
list_file_name_to_zip.append(str(local_full_file_name))
# Create a ZipFile Object
@ -4943,6 +4954,32 @@ def Create_Jury_Soutenance_Convocation_By_Inscrit_PDF(diction):
# close output file
resultFile.close()
"""
On met à jour l'inscrit pour dire que la convocation a été envoyée
"""
# print(" #### mydata before inscr = ", mydata)
key_data = {}
key_data['inscription_id'] = diction['inscription_id']
key_data['jury_soutenance_id'] = diction['jury_soutenance_id']
key_data['partner_owner_recid'] = str(my_partner['recid'])
mydata = {}
now = str(datetime.now())
mydata['update_by'] = str(my_partner['_id'])
mydata['update_date'] = now
mydata['convocation_sending_date'] = now
mydata['convocation_sending_mode'] = "pdf"
ret_val = MYSY_GV.dbname['jury_apprenant'].find_one_and_update(
key_data,
{"$set": mydata},
return_document=ReturnDocument.AFTER,
upsert=False,
)
return True, outputFilename
except Exception as e:
@ -4952,6 +4989,170 @@ def Create_Jury_Soutenance_Convocation_By_Inscrit_PDF(diction):
"""
Cette fonction créer une convocation à une soutenance de Jury PDF pour un inscrit et retourne le document
Pour les processus d'admission
"""
def Create_Jury_Admission_Soutenance_Convocation_By_Inscrit_PDF(diction):
try:
field_list_obligatoire = ['token', 'jury_soutenance_id', 'courrier_template_id', 'inscription_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"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
#print(" ##### qry = ", qry)
# 1 - Verifier que le modele de courrier est bien editable par individu
template_courrier_data = MYSY_GV.dbname['courrier_template'].find_one({'_id':ObjectId(str(diction['courrier_template_id'])),
'valide':'1',
'locked':'0',
'ref_interne': 'ADMISSION_JURY_CONVOCATION_CANDIDAT',
'partner_owner_recid':str(my_partner['recid'])})
if( template_courrier_data is None ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant du modèle de courrier est invalide ")
return False, " L'identifiant du modèle de courrier est invalide "
# Verifier que l'inscrit est valide
local_qry = {'_id':ObjectId(str(diction['inscription_id'])),
'partner_owner_recid':str(my_partner['recid'])}
candidat_data = MYSY_GV.dbname['admission_session_inscrit'].find_one({'_id':ObjectId(str(diction['inscription_id'])),
'partner_owner_recid':str(my_partner['recid'])})
if (candidat_data is None ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant du candidat est invalide ")
return False, " L'identifiant du candidat est invalide "
tab_candidat = []
tab_candidat.append(candidat_data['_id'])
# Verifier que la soutenance est valide
jury_soutenance_data = MYSY_GV.dbname['jury_soutenance'].find_one(
{'_id': ObjectId(str(diction['jury_soutenance_id'])), 'valide': '1', 'partner_owner_recid': str(my_partner['recid'])})
if (jury_soutenance_data is None):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la soutenance est invalide ")
return False, " L'identifiant de la soutenance est invalide "
tab_soutenance = []
tab_soutenance.append(jury_soutenance_data['_id'])
# Creation du dictionnaire d'information à utiliser pour la creation du doc
convention_dictionnary_data = {}
new_diction = {}
new_diction['token'] = diction['token']
new_diction['list_stagiaire_id'] = []
new_diction['list_candidat_admission_id'] = tab_candidat
new_diction['list_session_id'] = []
new_diction['list_class_id'] = []
new_diction['list_client_id'] = []
new_diction['list_apprenant_id'] = []
new_diction['list_jury_soutenance_id'] = tab_soutenance
print("### new_diction = ", new_diction)
local_status, local_retval = mycommon.Get_Dictionnary_data_For_Template(new_diction)
if (local_status is False):
return local_status, local_retval
convention_dictionnary_data = local_retval
body = {
"params": convention_dictionnary_data,
}
"""
Creation du ficier PDF
"""
contenu_doc_Template = jinja2.Template(str(template_courrier_data['contenu_doc']))
sourceHtml = contenu_doc_Template.render(params=body["params"])
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-5:]
orig_file_name = "Convoc_Soutenance_" + str(my_partner['recid'])[0:5] + "_" + str(ts) + ".pdf"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)
# open output file for writing (truncated binary)
resultFile = open(outputFilename, "w+b")
# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
src=sourceHtml, # the HTML to convert
dest=resultFile) # file handle to receive result
# close output file
resultFile.close()
"""
On met à jour l'inscrit pour dire que la convocation a été envoyée
"""
key_data = {}
key_data['inscription_id'] = diction['inscription_id']
key_data['jury_soutenance_id'] = diction['jury_soutenance_id']
key_data['partner_owner_recid'] = str(my_partner['recid'])
mydata = {}
now = str(datetime.now())
mydata['update_by'] = str(my_partner['_id'])
mydata['update_date'] = now
mydata['convocation_sending_date'] = now
mydata['convocation_sending_mode'] = "pdf"
ret_val = MYSY_GV.dbname['jury_apprenant'].find_one_and_update(
key_data,
{"$set": mydata},
return_document=ReturnDocument.AFTER,
upsert=False,
)
return True, outputFilename
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 créer le fichier pdf de convocation du jury "
"""
Cette fonction permet d'envoyer par e-mail la convocation des apprenants concernés
par une soutenance du jury
@ -4959,7 +5160,7 @@ par une soutenance du jury
def Send_Jury_Apprenant_Soutenance_Convocation_By_Email(tab_files, Folder, diction):
try:
field_list_obligatoire = ['token', 'jury_id', 'tab_jury_soutenance_ids',
'courrier_template_id', 'email_test', 'email_production']
'courrier_template_id', 'email_test', 'email_production', 'cible']
for val in field_list_obligatoire:
if val not in diction:
@ -5083,9 +5284,17 @@ def Send_Jury_Apprenant_Soutenance_Convocation_By_Email(tab_files, Folder, dicti
local_diction['email_test'] = diction['email_test']
local_diction['email_production'] = diction['email_production']
local_status, local_full_file_name = Create_Jury_Soutenance_Convocation_By_Inscrit_Email(tab_saved_file_full_path, Folder, local_diction)
if (local_status is False):
mycommon.myprint(" WARNING impossible d'envoyer la convocation a l'apprenant : " + str(val) )
if( "cible" in diction.keys() and diction['cible'] == "admission"):
local_status, local_full_file_name = Create_Jury_Admission_Soutenance_Convocation_By_Inscrit_Email(
tab_saved_file_full_path, Folder, local_diction)
if (local_status is False):
mycommon.myprint(" WARNING impossible d'envoyer la convocation au candidat : " + str(val))
else:
local_status, local_full_file_name = Create_Jury_Soutenance_Convocation_By_Inscrit_Email(tab_saved_file_full_path, Folder, local_diction)
if (local_status is False):
mycommon.myprint(" WARNING impossible d'envoyer la convocation a l'apprenant : " + str(val) )
"""
Mise à jour des date d'envoie
@ -5306,8 +5515,8 @@ def Create_Jury_Soutenance_Convocation_By_Inscrit_Email(tab_files, Folder, dicti
if (len(tab_emails_destinataire) <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune adresse email n'a été fourni. ")
return False, " Aucune adresse email n'a été fourni. "
3]) + " Aucune adresse email n'a pas été fournie. ")
return False, " Aucune adresse email n'a pas été fournie. "
tab_soutenance = []
tab_soutenance.append(jury_soutenance_data['_id'])
@ -5435,6 +5644,30 @@ def Create_Jury_Soutenance_Convocation_By_Inscrit_Email(tab_files, Folder, dicti
print(" Email envoyé " + str(val))
"""
On met à jour l'inscrit pour dire que la convocation a été envoyée
"""
# print(" #### mydata before inscr = ", mydata)
key_data = {}
key_data['inscription_id'] = diction['inscription_id']
key_data['jury_soutenance_id'] = diction['jury_soutenance_id']
key_data['partner_owner_recid'] = str(my_partner['recid'])
mydata = {}
now = str(datetime.now())
mydata['update_by'] = str(my_partner['_id'])
mydata['update_date'] = now
mydata['convocation_sending_date'] = now
mydata['convocation_sending_mode'] = "email"
ret_val = MYSY_GV.dbname['jury_apprenant'].find_one_and_update(
key_data,
{"$set": mydata},
return_document=ReturnDocument.AFTER,
upsert=False,
)
return True, "L'email a été correctement envoyé "
@ -5445,6 +5678,324 @@ def Create_Jury_Soutenance_Convocation_By_Inscrit_Email(tab_files, Folder, dicti
"""
Cette fonction créer une convocation à une soutenance de Jury Email pour un candidat
Pour les processus d'admission
"""
def Create_Jury_Admission_Soutenance_Convocation_By_Inscrit_Email(tab_files, Folder, diction):
try:
field_list_obligatoire = ['token', 'jury_soutenance_id', 'courrier_template_id', 'inscription_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"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# 1 - Verifier que le modele de courrier est bien editable par individu
template_courrier_data = MYSY_GV.dbname['courrier_template'].find_one({'_id':ObjectId(str(diction['courrier_template_id'])),
'valide':'1',
'locked':'0',
'ref_interne': 'ADMISSION_JURY_CONVOCATION_CANDIDAT',
'partner_owner_recid':str(my_partner['recid'])})
if( template_courrier_data is None ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant du modèle de courrier est invalide ")
return False, " L'identifiant du modèle de courrier est invalide "
# Recuperation des eventuelles pièces jointes du modèle que courrier
local_dic = {}
local_dic['token'] = str(diction['token'])
local_dic['object_owner_collection'] = "courrier_template"
local_dic['object_owner_id'] = str(template_courrier_data['_id'])
local_status, local_retval = attached_file_mgt.Get_List_object_owner_collection_Stored_Files(local_dic)
if (local_status is False):
return local_status, local_retval
# Traitement de l'eventuel fichier joint
tab_files_to_attache_to_mail = []
# Recuperation des fichiers attachés au modele de courrier, s'il y en a
for file in local_retval:
local_JSON = ast.literal_eval(file)
saved_file = local_JSON['full_path']
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(saved_file, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(os.path.basename(saved_file)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
#--------
candidat_data = MYSY_GV.dbname['admission_session_inscrit'].find_one(
{'_id': ObjectId(str(diction['inscription_id'])),
'partner_owner_recid': str(my_partner['recid'])})
if (candidat_data is None):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant du candidat est invalide ")
return False, " L'identifiant du candidat est invalide "
tab_candidat = []
tab_candidat.append(candidat_data['_id'])
# Verifier que la soutenance est valide
jury_soutenance_data = MYSY_GV.dbname['jury_soutenance'].find_one(
{'_id': ObjectId(str(diction['jury_soutenance_id'])), 'valide': '1', 'partner_owner_recid': str(my_partner['recid'])})
if (jury_soutenance_data is None):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la soutenance est invalide ")
return False, " L'identifiant de la soutenance est invalide "
for saved_file in tab_files:
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(saved_file, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(os.path.basename(saved_file)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
send_in_production = 0
tab_emails_destinataire = []
if ("email_test" in diction.keys() and diction['email_test']):
send_in_production = 0
tab_email_test = str(diction['email_test']).replace(";", ",").split(",")
for email in tab_email_test:
email = email.strip()
if (mycommon.isEmailValide(email) is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'adresse email " + str(email) + " est invalide ")
return False, " L'adresse email " + str(email) + " est invalide "
tab_emails_destinataire = tab_email_test
elif ("email_production" in diction.keys() and diction['email_production']):
send_in_production = 1
if (str(diction['email_production']) != "default"):
tab_email_prod = str(diction['email_production']).replace(";", ",").split(",")
for email in tab_email_prod:
email = email.strip()
if (mycommon.isEmailValide(str(email)) is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'adresse email '" + str(email) + "' est invalide ")
return False, " L'adresse email " + str(email) + " est invalide "
tab_emails_destinataire = tab_email_prod
else:
send_in_production = 1
"""
29/10/2026 - il s'agit d'une candidature à l'admission
on va donc prendre l'adresse email du candidat comme email de communication
"""
if ("email" in candidat_data.keys()):
tab_emails_destinataire.append(candidat_data['email'])
if (len(tab_emails_destinataire) <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune adresse email n'a pas été fournie. ")
return False, " Aucune adresse email n'a pas été fournie. "
tab_soutenance = []
tab_soutenance.append(jury_soutenance_data['_id'])
# Creation du dictionnaire d'information à utiliser pour la creation du doc
convention_dictionnary_data = {}
new_diction = {}
new_diction['token'] = diction['token']
new_diction['list_stagiaire_id'] = []
new_diction['list_candidat_admission_id'] = tab_candidat
new_diction['list_session_id'] = []
new_diction['list_class_id'] = []
new_diction['list_client_id'] = []
new_diction['list_apprenant_id'] = []
new_diction['list_jury_soutenance_id'] = tab_soutenance
local_status, local_retval = mycommon.Get_Dictionnary_data_For_Template(new_diction)
if (local_status is False):
return local_status, local_retval
convention_dictionnary_data = local_retval
body = {
"params": convention_dictionnary_data,
}
orig_file_name = None
outputFilename = None
# Verifier s'il s'agit d'un document à envoyer avec une version de pièce jointe.
if ("joint_pdf" in template_courrier_data.keys() and str(template_courrier_data['joint_pdf']) == "1"):
# Il s'agit bien d'un envoie avec 'contenu_doc' en pièce jointe PDF
"""
1 - Creation du PDF
"""
contenu_doc_Template = jinja2.Template(str(template_courrier_data['contenu_doc']))
sourceHtml = contenu_doc_Template.render(params=body["params"])
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-5:]
orig_file_name = "Convoc_Soutenance_" + str(my_partner['recid'])[0:5] + "_" + str(ts) + ".pdf"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)
# open output file for writing (truncated binary)
resultFile = open(outputFilename, "w+b")
# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
src=sourceHtml, # the HTML to convert
dest=resultFile) # file handle to receive result
# close output file
resultFile.close()
# Attachement du fichier joint
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(outputFilename, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(os.path.basename(outputFilename)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
## Creation du mail au format email
corps_mail_Template = jinja2.Template(str(template_courrier_data['corps_mail']))
sourceHtml = corps_mail_Template.render(params=body["params"])
html_mime = MIMEText(sourceHtml, 'html')
# Traitement du sujet du mail
sujet_mail_Template = jinja2.Template(str(template_courrier_data['sujet']))
sujetHtml = sujet_mail_Template.render(params=body["params"])
# Creation de l'email à enoyer
msg = MIMEMultipart("alternative")
else:
## Creation du mail au format email
corps_mail_Template = jinja2.Template(str(template_courrier_data['contenu_doc']))
sourceHtml = corps_mail_Template.render(params=body["params"])
html_mime = MIMEText(sourceHtml, 'html')
# Traitement du sujet du mail
sujet_mail_Template = jinja2.Template(str(template_courrier_data['sujet']))
sujetHtml = sujet_mail_Template.render(params=body["params"])
# Creation de l'email à enoyer
msg = MIMEMultipart("alternative")
# Recuperation des donnes smpt
local_stpm_status, partner_SMTP_COUNT_smtpsrv, partner_own_smtp_value, partner_SMTP_COUNT_password, partner_SMTP_COUNT_user, partner_SMTP_COUNT_From_User,\
partner_SMTP_COUNT_port = mycommon.Get_Partner_SMTP_Param(
str(my_partner['recid']))
if (local_stpm_status is False):
return local_stpm_status, partner_SMTP_COUNT_smtpsrv
msg.attach(html_mime)
msg['From'] = partner_SMTP_COUNT_From_User
msg['Bcc'] = 'contact@mysy-training.com'
msg['Subject'] = sujetHtml
# Attacher l'eventuelle pièces jointes
for myfile in tab_files_to_attache_to_mail:
msg.attach(myfile['attached_file'])
# msg['to'] = "billardman01@hotmail.com"
toaddrs = ",".join(tab_emails_destinataire)
msg['to'] = str(toaddrs)
smtpserver = smtplib.SMTP(partner_SMTP_COUNT_smtpsrv, partner_SMTP_COUNT_port)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.login(partner_SMTP_COUNT_user, partner_SMTP_COUNT_password)
val = smtpserver.send_message(msg)
smtpserver.close()
print(" Email envoyé " + str(val))
"""
On met à jour l'inscrit pour dire que la convocation a été envoyée
"""
# print(" #### mydata before inscr = ", mydata)
key_data = {}
key_data['inscription_id'] = diction['inscription_id']
key_data['jury_soutenance_id'] = diction['jury_soutenance_id']
key_data['partner_owner_recid'] = str(my_partner['recid'])
mydata = {}
now = str(datetime.now())
mydata['update_by'] = str(my_partner['_id'])
mydata['update_date'] = now
mydata['convocation_sending_date'] = now
mydata['convocation_sending_mode'] = "email"
ret_val = MYSY_GV.dbname['jury_apprenant'].find_one_and_update(
key_data,
{"$set": mydata},
return_document=ReturnDocument.AFTER,
upsert=False,
)
return True, "L'email a été correctement envoyé "
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'envoyer par email convocation du jury "
"""
Cette fonction permet de telecharger (PDF) la convocation des membres du jury concernés
par une soutenance du jury
@ -6123,8 +6674,8 @@ def Create_Jury_Convocation_By_Membre_Email(tab_files, Folder, diction):
if (len(tab_emails_destinataire) <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune adresse email n'a été fourni. ")
return False, " Aucune adresse email n'a été fourni. "
3]) + " Aucune adresse email n'a pas été fournie. ")
return False, " Aucune adresse email n'a pas été fournie. "
# Creation du dictionnaire d'information à utiliser pour la creation du doc

69
main.py
View File

@ -14059,6 +14059,42 @@ def Send_Jury_Apprenant_Soutenance_Convocation_By_PDF(token, jury_id, tab_jury_s
else:
return False
"""
API pour generer les convocation jury (apprenant) soutenance par PDF
"""
@app.route('/myclass/api/Send_Jury_Apprenant_Soutenance_Admission_Convocation_By_PDF/<token>/<jury_id>/<tab_jury_soutenance_ids>/<courrier_template_id>', methods=['POST','GET'])
@crossdomain(origin='*')
def Send_Jury_Apprenant_Soutenance_Admission_Convocation_By_PDF(token, jury_id, tab_jury_soutenance_ids, courrier_template_id):
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
payload = {}
payload['token'] = str(token)
if (str(jury_id) != "-"):
payload['jury_id'] = str(jury_id)
if( str(tab_jury_soutenance_ids) != "-"):
payload['tab_jury_soutenance_ids'] = str(tab_jury_soutenance_ids)
if (str(courrier_template_id) != "-"):
payload['courrier_template_id'] = str(courrier_template_id)
payload['cible'] = "admission"
print(" ### Send_Jury_Apprenant_Soutenance_Convocation_By_PDF : payload = ",str(payload))
localStatus, response= jury_mgt.Send_Jury_Apprenant_Soutenance_Convocation_By_PDF(payload)
if(localStatus ):
return response
else:
return False
"""
API pour generer les convocation jury (apprenants) soutenance par email
"""
@ -15464,6 +15500,25 @@ def Update_Stagiaire_To_Admission_Session():
"""
API pour Mettre à jour une personne à une session d'admission JUSTE l'ETAPE DE LA SESSION d'ADMISSION
"""
@app.route('/myclass/api/Update_Stagiaire_Only_Process_Step_Admission_Session/', methods=['POST','GET'])
@crossdomain(origin='*')
def Update_Stagiaire_Only_Process_Step_Admission_Session():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Update_Stagiaire_Only_Process_Step_Admission_Session : payload = ",payload)
localStatus, message = session_admission_fi.Update_Stagiaire_Only_Process_Step_Admission_Session(payload)
return jsonify(status=localStatus, message=message )
"""
API pour Mettre à jour le statut d'acceptation d'une personne à une session d'admission (PROCESS_ADMISSION_STATUS)
- accepté
- rejeté
- liste attente
- etc
"""
@app.route('/myclass/api/Update_Stagiaire_Only_Status_Admission_Session/', methods=['POST','GET'])
@crossdomain(origin='*')
def Update_Stagiaire_Only_Status_Admission_Session():
@ -15476,6 +15531,7 @@ def Update_Stagiaire_Only_Status_Admission_Session():
"""
API pour Suppression de l'inscription d'une personne à une session d'admission
"""
@ -15593,6 +15649,19 @@ def Get_Pourcentage_Candidat_Document():
return jsonify(status=status, message=retval)
"""
API retourne une synthèse
des candidats à une session d'admission.
"""
@app.route('/myclass/api/Get_Synthese_Candidat_Process_Admission/', methods=['POST','GET'])
@crossdomain(origin='*')
def Get_Synthese_Candidat_Process_Admission():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Get_Synthese_Candidat_Process_Admission payload = ",payload)
status, retval = session_admission_fi.Get_Synthese_Candidat_Process_Admission(payload)
return jsonify(status=status, message=retval)
if __name__ == '__main__':

View File

@ -47,7 +47,7 @@ def Add_Partner_Client(diction):
'adr_adresse', 'adr_code_postal', 'adr_ville', 'adr_pays',
'invoice_email', 'invoice_nom', 'invoice_siret',
'invoice_tva', 'invoice_condition_paiement_id', 'invoice_adresse', 'invoice_ville',
'invoice_code_postal', 'invoice_pays', "client_type_id",
'invoice_code_postal', 'invoice_pays', 'invoice_telephone', "client_type_id",
'is_fournisseur', 'is_client', 'is_financeur', 'is_company', 'invoice_automatique',
'type_financeur_id', 'type_pouvoir_public_id', 'partner_groupe_client_id',
@ -387,6 +387,12 @@ def Add_Partner_Client(diction):
invoice_pays = diction['invoice_pays']
data['invoice_pays'] = invoice_pays
invoice_telephone = ""
if ("invoice_telephone" in diction.keys()):
if diction['invoice_telephone']:
invoice_telephone = diction['invoice_telephone']
data['invoice_telephone'] = invoice_telephone
list_adress = []
line = 0
if ("address" in diction.keys()):
@ -413,6 +419,65 @@ def Add_Partner_Client(diction):
"""
30/01/26 -
Pour reduire les saisie, on va ajouter par defaut ls données de facturations à la creation s'il ne sont pas
fourni
"""
if( "invoice_email" not in diction.keys() ):
data['invoice_email'] = diction['email']
invoice_nom = ""
if ("invoice_nom" not in diction.keys()):
if( "nom" in diction.keys()):
invoice_nom = diction['nom']
data['invoice_nom'] = str(invoice_nom)
invoice_adresse = ""
if ("invoice_adresse" not in diction.keys()):
if( "adr_adresse" in diction.keys()):
invoice_adresse = diction['adr_adresse']
data['invoice_adresse'] = str(invoice_adresse)
invoice_ville = ""
if ("invoice_ville" not in diction.keys()):
if( "adr_ville" in diction.keys()):
invoice_ville = diction['adr_ville']
data['invoice_ville'] = str(invoice_ville)
invoice_code_postal = ""
if ("invoice_ville" not in diction.keys()):
if ("adr_code_postal" in diction.keys()):
invoice_code_postal = diction['adr_code_postal']
data['invoice_code_postal'] = str(invoice_code_postal)
invoice_pays = ""
if ("invoice_ville" not in diction.keys()):
if ("adr_pays" in diction.keys()):
invoice_pays = diction['adr_pays']
data['invoice_code_postal'] = str(invoice_pays)
invoice_telephone = ""
if ("invoice_telephone" not in diction.keys()):
if ("telephone" in diction.keys()):
invoice_telephone = diction['telephone']
data['invoice_telephone'] = str(invoice_telephone)
invoice_condition_paiement_id = ""
if ("invoice_condition_paiement_id" not in diction.keys()):
# On force les condition de paiement avec la 1er valeur trouvé
paiement_ction_data = MYSY_GV.dbname['base_partner_paiement_condition'].find_one(
{'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if(paiement_ction_data ):
invoice_condition_paiement_id = str(paiement_ction_data['_id'])
data['invoice_condition_paiement_id'] = str(invoice_condition_paiement_id)
list_contact = ""
if ("list_contact" in diction.keys()):
@ -516,6 +581,54 @@ def Add_Partner_Client(diction):
str(inspect.stack()[0][3]) + " WARNING : Impossible d'ajouter le contact au nouveau client " + str(
inserted_id))
else:
"""
Si aucun contact n'est fourni, on en créé un par defaut
"""
new_contact_diction = {}
new_contact_diction['email'] = diction['email']
new_contact_diction['nom'] = diction['nom']
new_contact_diction['token'] = diction['token']
new_contact_diction['related_collection'] = "partner_client"
new_contact_diction['related_collection_owner_id'] = str(inserted_id)
new_contact_diction['civilite'] = ""
new_contact_diction['prenom'] = diction['nom']
new_contact_diction['include_com'] = "1"
new_contact_diction['fonction'] = ""
new_contact_diction['telephone_mobile'] = ""
if ("telephone" in diction.keys()):
new_contact_diction['telephone'] = diction['telephone']
else:
new_contact_diction['telephone'] = ""
if ("adr_code_postal" in diction.keys()):
new_contact_diction['adr_code_postal'] = diction['adr_code_postal']
else:
new_contact_diction['adr_code_postal'] = ""
if ("adr_ville" in diction.keys()):
new_contact_diction['adr_ville'] = diction['adr_ville']
else:
new_contact_diction['adr_ville'] = ""
if ("adr_pays" in diction.keys()):
new_contact_diction['adr_pays'] = diction["adr_pays"]
else:
new_contact_diction['adr_pays'] = ""
new_contact_diction['siret'] = ""
new_contact_diction['tva'] = ""
local_add_contact_status, local_add_contact_retval = contact.Add_Contact(new_contact_diction)
if (local_add_contact_status is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " WARNING : Impossible d'ajouter le contact au nouveau client " + str(
inserted_id))
return True, " Le client a été correctement créé"
@ -1035,7 +1148,7 @@ def Update_Partner_Client(diction):
'adr_adresse', 'adr_code_postal', 'adr_ville', 'adr_pays',
'invoice_email', 'invoice_nom', 'invoice_siret',
'invoice_tva','invoice_condition_paiement_id', 'invoice_adresse', 'invoice_ville',
'invoice_code_postal', 'invoice_pays', 'client_type_id',
'invoice_code_postal', 'invoice_pays', 'invoice_telephone', 'client_type_id',
'is_fournisseur', 'is_client', 'is_financeur', 'is_company', 'invoice_automatique',
'type_financeur_id', 'type_pouvoir_public_id', 'partner_groupe_client_id', 'archive']
@ -1323,6 +1436,11 @@ def Update_Partner_Client(diction):
invoice_code_postal = diction['invoice_code_postal']
data_update['invoice_code_postal'] = diction['invoice_code_postal']
invoice_telephone = ""
if ("invoice_telephone" in diction.keys()):
invoice_telephone = diction['invoice_telephone']
data_update['invoice_telephone'] = diction['invoice_telephone']
invoice_pays = ""
if ("invoice_pays" in diction.keys()):
invoice_pays = diction['invoice_pays']

View File

@ -310,6 +310,7 @@ def Invoice_Partner_Order(diction):
" Impossible de créer l'entete de la facture ")
return False, "Impossible de créer l'entete de la facture ", False
tab_session_3001 = []
for new_invoice_data_line in MYSY_GV.dbname['partner_order_line'].find( {'order_header_id': str(diction['order_id']), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner['recid']}, {'_id':0, 'order_line_type':0, 'order_line_status':0,
@ -320,6 +321,10 @@ def Invoice_Partner_Order(diction):
new_invoice_data_line['invoice_header_id'] = str(inserted_invoice_id)
new_invoice_data_line['update_by'] = str(my_partner['_id'])
if( "order_line_session_id" in new_invoice_data_line.keys() and new_invoice_data_line['order_line_session_id']):
tab_session_3001.append(str(new_invoice_data_line['order_line_session_id']))
work_tab = []
if ("order_line_tab_inscrit_id" in new_invoice_data_line.keys()):
for tmp in new_invoice_data_line['order_line_tab_inscrit_id']:
@ -341,6 +346,8 @@ def Invoice_Partner_Order(diction):
#print(" ### inserted_line_id de la ligne inserée = ", inserted_line_id)
if (not inserted_line_id):
# Vu quil y a un souci avec l'une des lignes, on fait un roll back complet de la facturation
@ -509,8 +516,38 @@ def Invoice_Partner_Order(diction):
"""
Ajout l'action dans l'historique
"""
30/01/2026 -
Après avoir créer la facture, on va aller mettre à jour les EVENTUELLE Session concernée avec les clients concernés.
C'est a dire, si le client facturé à des apprenants dans la session, je vais aller dire qu'ils sont facturés
les lignes sont facturés, je vais juste le num de facture comme ca depuis la session, on vera qu'il y a 2 facturer.
"""
if( "order_header_client_id" in new_invoice_data_header.keys() and new_invoice_data_header['order_header_client_id']
and "invoice_header_ref_interne" in new_invoice_data_header.keys() and new_invoice_data_header['invoice_header_ref_interne']
and "invoice_date" in new_invoice_data_header.keys() and new_invoice_data_header['invoice_date'] ):
now = str(datetime.now())
update_data = {}
update_data['invoiced'] = "1"
update_data['invoiced_ref'] = str(new_invoice_data_header['invoice_header_ref_interne'])
update_data['invoiced_date'] = new_invoice_data_header['invoice_date']
update_data['date_update'] = str(now)
update_data['update_by'] = str(my_partner['_id'])
update = MYSY_GV.dbname['inscription'].update_many({'partner_owner_recid': str(my_partner['recid']),
'session_id': {'$in':tab_session_3001},
'facture_client_rattachement_id': str(new_invoice_data_header['order_header_client_id']),
},
{'$set': update_data})
"""
Ajout l'action dans l'historique
"""
## Add to log history pour la facture
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}

View File

@ -4473,6 +4473,7 @@ convention_dictionnary_data =
{'class_data':{....}}
{'list_session_data':{....}}
{'list_stagiaire_data':[{...}]}
{'list_candidat_admission_id':[{...}]}
{'list_apprenant_data':[{...}]}
{'list_client_data':{'raison_sociale':'xxx', 'nom':'yyy', list_contact_communication[{'civilite':'aa', 'nom':'bbb', ....'telephone_mobile':'01222'}, {'civilite':'aa', 'nom':'bbb', ....'telephone_mobile':'01222'} .... ]}
{'systeme':{'date_jour':'11/02/2023'}}
@ -4490,7 +4491,7 @@ def Get_Dictionnary_data_For_Template(diction):
Verification des input acceptés
"""
field_list = ['token', 'list_stagiaire_id', 'list_session_id', 'list_class_id', 'list_client_id',
'list_apprenant_id', 'list_sequence_session_id', 'list_jury_soutenance_id']
'list_apprenant_id', 'list_sequence_session_id', 'list_jury_soutenance_id', 'list_candidat_admission_id']
incom_keys = diction.keys()
for val in incom_keys:
@ -4844,6 +4845,38 @@ def Get_Dictionnary_data_For_Template(diction):
dictionnary_data['list_stagiaire_data'] = list_stagiaire_data
"""
Recuperartion des champs d'un candidat a un process admission
"""
list_candidat_data = []
if( "list_candidat_admission_id" in diction.keys() and diction['list_candidat_admission_id']):
tab_candidat_id = diction['list_candidat_admission_id']
candidat_liste_champ = ['email', 'nom', 'prenom', 'telephone', 'client_rattachement_id', 'employeur',
'modefinancement', 'civilite', 'adresse', 'code_postal', 'ville', 'pays',
'memo', 'comment']
for candidat_data in MYSY_GV.dbname['admission_session_inscrit'].find({'_id': {'$in': tab_candidat_id, },
'partner_owner_recid': str(my_partner['recid'])
}):
new_candidat_data = {}
for champ in candidat_liste_champ:
if (champ in candidat_data):
new_champ_name = "stagiaire_" + str(champ)
new_field = {new_champ_name: str(candidat_data[champ])}
new_candidat_data.update(new_field)
else:
new_champ_name = "stagiaire_" + str(champ)
new_field = {new_champ_name: ""}
new_candidat_data.update(new_field)
list_candidat_data.append(new_candidat_data)
dictionnary_data['list_candidat_data'] = list_candidat_data
"""
Recuperartion des champs des formations

View File

@ -985,27 +985,27 @@ def Add_Stagiaire_To_Admission_Session(diction):
history_event_dict['related_collection'] = "admission_session_inscrit"
history_event_dict['related_collection_recid'] = str(inserted_data.inserted_id)
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Inscription de la personnes "+str(new_data['nom'])+" "+str(new_data['prenom'])+" "+str(inserted_data.inserted_id)
history_event_dict['action_description'] = "Inscription du candidat "+str(new_data['nom'])+" "+str(new_data['prenom'])+" "+str(inserted_data.inserted_id)
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
return True, " La personne a été correctement ajoutée"
return True, " Le candidat a été correctement ajouté"
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'ajouter la personne"
return False, "Impossible d'ajouter le candidat"
"""
Mettre à jour le statut d'une personne à une session d'admission
Mettre à jour le session_etape d'une personne à une session d'admission
"""
def Update_Stagiaire_Only_Status_Admission_Session(diction):
def Update_Stagiaire_Only_Process_Step_Admission_Session(diction):
try:
# Dictionnaire des champs utilisables
'''
@ -1054,8 +1054,8 @@ def Update_Stagiaire_Only_Status_Admission_Session(diction):
if (is_existe_inscrit != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant de la personne est invalide ")
return False, " L'identifiant de la personne est invalide "
str(inspect.stack()[0][3]) + " L'identifiant du candidat est invalide ")
return False, " L'identifiant du candidat est invalide "
@ -1105,8 +1105,8 @@ def Update_Stagiaire_Only_Status_Admission_Session(diction):
if (not result or "_id" not in result.keys()):
mycommon.myprint(
" Impossible de mettre à jour la personne (2) ")
return False, " Impossible de mettre à jour la personne (2) "
" Impossible de mettre à jour le candidat (2) ")
return False, " Impossible de mettre à jour le candidat (2) "
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
@ -1122,13 +1122,143 @@ def Update_Stagiaire_Only_Status_Admission_Session(diction):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
return True, " La personne a été correctement ajoutée"
return True, " Le candidat a été correctement 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 la personne "
return False, "Impossible de mettre à jour le candidat "
"""
Mettre à jour le statut d'acceptation d'une personne à une session d'admission (PROCESS_ADMISSION_STATUS)
- accepté
- rejeté
- liste attente
"""
def Update_Stagiaire_Only_Status_Admission_Session(diction):
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 = ['token', '_id', 'new_status' ]
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, "Toutes les informations fournies ne sont pas valables"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', '_id', 'new_status' ]
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, "Impossible de créer le stagiaire. La valeur '" + val + "' n'est pas presente dans la liste des arguments"
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 validé de l'inscrit
"""
is_existe_inscrit = MYSY_GV.dbname['admission_session_inscrit'].count_documents(
{'_id': ObjectId(str(diction['_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_existe_inscrit != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant du candidat est invalide ")
return False, " L'identifiant du candidat est invalide "
is_existe_inscrit_data = MYSY_GV.dbname['admission_session_inscrit'].find_one(
{'_id': ObjectId(str(diction['_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
old_statut = is_existe_inscrit_data['status']
if( diction['new_status'] not in MYSY_GV.PROCESS_ADMISSION_STATUS):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le statut est invalide ")
return False, " Le statut est invalide "
local_id = str(diction['_id'])
del diction['token']
del diction['_id']
new_data = {}
new_data['update_by'] = str(my_partner['_id'])
new_data['update_date'] = str(datetime.now())
new_data['status'] = str(diction['new_status'])
data_cle = {}
data_cle['partner_owner_recid'] = str(my_partner['recid'])
data_cle['_id'] = ObjectId(local_id)
data_cle['valide'] = "1"
data_cle['locked'] = "0"
result = MYSY_GV.dbname['admission_session_inscrit'].find_one_and_update(
data_cle,
{"$set": new_data},
upsert=False,
return_document=ReturnDocument.AFTER
)
if (not result or "_id" not in result.keys()):
mycommon.myprint(
" Impossible de mettre à jour le candidat (2) ")
return False, " Impossible de mettre à jour le candidat (2) "
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = str(token)
history_event_dict['related_collection'] = "admission_session_inscrit"
history_event_dict['related_collection_recid'] = str(local_id)
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Changement statut pour " + str(result['nom']) + " " + str(
result['prenom']) + " " + str(result['_id'])+" ==> de "+str(old_statut) +" => "+diction['new_status']
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
return True, " Le statut a été correctement mis à 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 candidat "
@ -1193,8 +1323,8 @@ def Update_Stagiaire_To_Admission_Session(diction):
if (is_existe_inscrit != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant de la personne est invalide ")
return False, " L'identifiant de la personne est invalide "
str(inspect.stack()[0][3]) + " L'identifiant du candidat est invalide ")
return False, " L'identifiant du candidat est invalide "
"""
Verififier l'existance et la valididé de la session
@ -1291,8 +1421,8 @@ def Update_Stagiaire_To_Admission_Session(diction):
if (not result or "_id" not in result.keys()):
mycommon.myprint(
" Impossible de mettre à jour la personne (2) ")
return False, " Impossible de mettre à jour la personne (2) "
" Impossible de mettre à jour le candidat (2) ")
return False, " Impossible de mettre à jour le candidat (2) "
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
@ -1300,7 +1430,7 @@ def Update_Stagiaire_To_Admission_Session(diction):
history_event_dict['related_collection'] = "admission_session_inscrit"
history_event_dict['related_collection_recid'] = str(local_id)
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Inscription de la personnes " + str(result['nom']) + " " + str(
history_event_dict['action_description'] = "Inscription du candidat " + str(result['nom']) + " " + str(
result['prenom']) + " " + str(result['_id'])
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
@ -1308,13 +1438,13 @@ def Update_Stagiaire_To_Admission_Session(diction):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
return True, " La personne a été correctement ajoutée"
return True, " Le candidat a été correctement mis à 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 la personne "
return False, "Impossible de mettre à jour le candidat "
@ -2215,3 +2345,146 @@ def Internal_Get_Pourcentage_Candidat_Document(diction=None):
exc_type, exc_obj, exc_tb = sys.exc_info()
print(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de recuperer la liste des documents du candidat "
"""
Cette fonction retourne une synthèse
des candidats à une session d'admission.
Cette synthèse est un outil d'aide à l'acceptation du candidat
"""
def Get_Synthese_Candidat_Process_Admission(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'session_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', 'session_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
"""
Clés de mise à jour
"""
data_cle = {}
data_cle['partner_owner_recid'] = str(my_partner['recid'])
data_cle['session_id'] = str(diction['session_id'])
data_cle['valide'] = "1"
data_cle['locked'] = "0"
RetObject = []
val_tmp = 0
for retval in MYSY_GV.dbname['admission_session_inscrit'].find(data_cle).sort([("_id", pymongo.DESCENDING), ]):
user = retval
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
if ("date_naissance" not in retval.keys() or retval['date_naissance'] == ""):
retval['date_naissance'] = "01/01/1900"
if ("civilite" not in retval.keys() or retval['civilite'] == ""):
retval['civilite'] = "neutre"
age = relativedelta( date.today(), datetime.strptime(str(retval['date_naissance']), '%d/%m/%Y') )
retval['age'] = str(age.years)
session_etape_code = ""
if( "session_etape" in retval.keys() and retval['session_etape'] ):
admiss_session_etape_data = MYSY_GV.dbname['admission_setup_etape'].find_one(({'_id':ObjectId(str(retval['session_etape'])),
'valide':'1',
'partner_owner_recid':str(my_partner['recid'])}))
if( admiss_session_etape_data and "code" in admiss_session_etape_data.keys()):
session_etape_code = admiss_session_etape_data['code']
retval['session_etape_code'] = str(session_etape_code)
local_status, local_retval = Internal_Get_Pourcentage_Candidat_Document({'partner_recid':str(my_partner['recid']), 'inscrit_id':str(retval['_id'])})
if(local_status ):
#retval['document_satatus'] = local_retval
if( "pourcentage_accepted" in local_retval.keys()):
retval['document_pourcentage_accepted'] = str(local_retval['pourcentage_accepted'])
if ("pourcentage_send" in local_retval.keys()):
retval['taux_document_pourcentage_received'] = str(local_retval['pourcentage_send'])
else:
retval['document_pourcentage_accepted'] = "0"
retval['taux_document_pourcentage_received'] = "0"
if( retval['document_pourcentage_accepted'] != "1"):
retval['document_alert_message'] = "Tous les documents ne sont pas validés"
else:
retval['document_alert_message'] = ""
"""
Recuperer les notes et observation pour chacun des jury et examen de session pour ce candidat
"""
tab_jury_exam_note_obser = []
tab_entete_exam_jury = []
for local_jury_examen_data in MYSY_GV.dbname['jury'].find(
{'partner_owner_recid': str(my_partner['recid']), 'valide': '1', 'locked': '0',
'cible': 'admission', 'session_id': str(diction['session_id'])}, ):
for jury_apprenant_data in MYSY_GV.dbname['jury_apprenant'].find({'inscription_id':str(retval['_id']),
'jury_id':str(local_jury_examen_data['_id']),
'partner_owner_recid':str(my_partner['recid'])}):
retval[str(local_jury_examen_data['code'])+"_note"] = jury_apprenant_data['jury_note']
retval[str(local_jury_examen_data['code']) + "_obs."] = jury_apprenant_data['jury_observation']
tab_entete_exam_jury.append(str(local_jury_examen_data['code'])+"_note");
tab_entete_exam_jury.append(str(local_jury_examen_data['code']) + "_obs.")
#retval['tab_jury_exam_note_observation'] = tab_jury_exam_note_obser
user['tab_entete_exam_jury'] = tab_entete_exam_jury
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 inscrits"