29/10/2025 - 22h

Signed-off-by: Cherif <cbalde@mysy-training.com>
master_Elyos_FI
Cherif 2025-10-29 22:11:35 +01:00
parent fe3b8bb7a5
commit ca7cd37e68
8 changed files with 3810 additions and 44 deletions

View File

@ -4,22 +4,15 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="22/10*2025 - 22h">
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="26/10/2025 - 15h">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" 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$/Job_Cron_Common.py" beforeDir="false" afterPath="$PROJECT_DIR$/Job_Cron_Common.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Dashbord_queries/ressources_humaines_tbd_qries.py" beforeDir="false" afterPath="$PROJECT_DIR$/Dashbord_queries/ressources_humaines_tbd_qries.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$/attestation_formation.py" beforeDir="false" afterPath="$PROJECT_DIR$/attestation_formation.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/base_class_calcul_note.py" beforeDir="false" afterPath="$PROJECT_DIR$/base_class_calcul_note.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/class_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/class_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/internal_email_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/internal_email_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lms_chamilo/mysy_lms.py" beforeDir="false" afterPath="$PROJECT_DIR$/lms_chamilo/mysy_lms.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/partner_base_setup.py" beforeDir="false" afterPath="$PROJECT_DIR$/partner_base_setup.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/prj_common.py" beforeDir="false" afterPath="$PROJECT_DIR$/prj_common.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/survey_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/survey_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/wrapper.py" beforeDir="false" afterPath="$PROJECT_DIR$/wrapper.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Session_Formation_Sequence.py" beforeDir="false" afterPath="$PROJECT_DIR$/Session_Formation_Sequence.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ent_student_common.py" beforeDir="false" afterPath="$PROJECT_DIR$/ent_student_common.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/model_planning_sequence_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/model_planning_sequence_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/user_session.py" beforeDir="false" afterPath="$PROJECT_DIR$/user_session.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -462,7 +455,7 @@
<option name="project" value="LOCAL" />
<updated>1747251650255</updated>
</task>
<option name="localTasksCounter" value="507" />
<option name="localTasksCounter" value="508" />
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
@ -504,7 +497,6 @@
</option>
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="09/06/2025 - 21h30" />
<MESSAGE value="11/06/2025 - 16h30" />
<MESSAGE value="19/06/2025 -18h" />
<MESSAGE value="20/06/2025 -18h" />
@ -529,6 +521,7 @@
<MESSAGE value="21/10/2025 - 22h" />
<MESSAGE value="wds" />
<MESSAGE value="22/10*2025 - 22h" />
<option name="LAST_COMMIT_MESSAGE" value="22/10*2025 - 22h" />
<MESSAGE value="26/10/2025 - 15h" />
<option name="LAST_COMMIT_MESSAGE" value="26/10/2025 - 15h" />
</component>
</project>

View File

@ -187,8 +187,6 @@ def Get_Humain_Ressource_With_Planning(diction):
{'$eq': ["$partner_owner_recid", '$$rh_partner_owner_recid']},
{'$gte': [{'$toDate': "$event_start" },filt_session_start_date_ISODATE]},
{'$lte': [{'$toDate': "$event_start"}, filt_session_end_date_ISODATE]}
]
}
}
@ -625,6 +623,8 @@ def Get_Humain_Ressource_With_Planning_And_Cost(diction):
filt_session_start_date = start_current_month_date
filt_session_end_date = end_current_month_date
filt_session_start_date_ISODATE = datetime.strptime(str(filt_session_start_date), '%d/%m/%Y')
filt_session_end_date_ISODATE = datetime.strptime(str(filt_session_end_date), '%d/%m/%Y')
"""
Algorithme :
@ -744,8 +744,8 @@ def Get_Humain_Ressource_With_Planning_And_Cost(diction):
Aller recuperer les taches dans les agendas
"""
filt_session_start_date_ISODATE = datetime.strptime(str(date_debut_contrat), '%d/%m/%Y')
filt_session_end_date_ISODATE = datetime.strptime(str(date_fin_contrat), '%d/%m/%Y')
filt_contrat_start_date_ISODATE = datetime.strptime(str(date_debut_contrat), '%d/%m/%Y')
filt_contrat_end_date_ISODATE = datetime.strptime(str(date_fin_contrat), '%d/%m/%Y')
local_qry_tache_agenda = ([
{"$match": {'_id': rh_id_Object}},
@ -762,8 +762,8 @@ def Get_Humain_Ressource_With_Planning_And_Cost(diction):
{'$eq': ["$valide", "1"]},
{'$eq': ["$related_collection_recid", '$$rh_id']},
{'$eq': ["$partner_owner_recid", '$$rh_partner_owner_recid']},
{'$gte': [{'$toDate': "$event_start"}, filt_session_start_date_ISODATE]},
{'$lte': [{'$toDate': "$event_start"}, filt_session_end_date_ISODATE]}
{'$gte': [{'$toDate': "$event_start"}, filt_contrat_start_date_ISODATE]},
{'$lte': [{'$toDate': "$event_start"}, filt_contrat_end_date_ISODATE]}
]
}
@ -808,16 +808,26 @@ def Get_Humain_Ressource_With_Planning_And_Cost(diction):
#json_agenda_formatted_str = json.dumps(retval_agenda, indent=2)
if ("collection_agenda" in retval_agenda.keys() and "partner_owner_recid" in retval_agenda[
'collection_agenda'].keys()):
new_node = retval_agenda['collection_agenda']
retval['Tab_agenda'].append(new_node)
# print(" ### NODE ADDED = ", new_node)
if ("collection_agenda" in retval_agenda.keys() and "partner_owner_recid" in retval_agenda['collection_agenda'].keys()):
"""print(" ### NODE = ", retval_agenda['collection_agenda'])
print(" ### filt_session_start_date_ISODATE = ", filt_session_start_date_ISODATE)
print(" ### filt_session_end_date_ISODATE = ", filt_session_end_date_ISODATE)"""
aganda_start_date_ISODATE = datetime.strptime(str(retval_agenda['collection_agenda']['event_start'])[0:16],'%Y-%m-%dT%H:%M')
aganda_end_date_ISODATE = datetime.strptime(
str(retval_agenda['collection_agenda']['event_end'])[0:16], '%Y-%m-%dT%H:%M')
"""print(" ### aganda_start_date_ISODATE = ", aganda_start_date_ISODATE)
print(" ### aganda_end_date_ISODATE = ", aganda_end_date_ISODATE)"""
if( aganda_start_date_ISODATE >= filt_session_start_date_ISODATE and aganda_end_date_ISODATE <= filt_session_end_date_ISODATE ):
new_node = retval_agenda['collection_agenda']
retval['Tab_agenda'].append(new_node)
#print(" ### NODE ADDED = ", new_node)
#json_formatted_str = json.dumps(retval, indent=2)
#print(" ### Final Line : ", json_formatted_str)
#print(" ### retval['Tab_agenda'] : ", retval['Tab_agenda'])
tab_lines_employe_by_contract.append(retval)
local_status, local_retval, node_total_duration, node_total_cost = Format_employee_contrat_agenda_events(tab_lines_employe_by_contract)

File diff suppressed because it is too large Load Diff

View File

@ -1751,8 +1751,23 @@ def Get_Session_Sequence_List(diction):
if ("mode_animation" not in user.keys()):
user['mode_animation'] = "0"
ue_titre = ""
ue_code = ""
if ("ue_id" not in user.keys()):
user['ue_id'] = ""
elif ( "ue_id" in user.keys() and user['ue_id']):
eu_id_data = MYSY_GV.dbname['unite_enseignement'].find_one({'_id':ObjectId(str(user['ue_id'])),
'partner_owner_recid':str(my_partner['recid'])})
if(eu_id_data and "titre" in eu_id_data.keys() ):
ue_titre = eu_id_data['titre']
if (eu_id_data and "code" in eu_id_data.keys()):
ue_code = eu_id_data['code']
user['ue_code'] = ue_code
user['ue_titre'] = ue_titre
if ("unite_enseignement_planif_id" not in user.keys()):
user['unite_enseignement_planif_id'] = ""

View File

@ -355,6 +355,152 @@ def Get_Ent_Student_List_Class(diction):
return False, " Impossible de récupérer les formations de l'apprenant "
"""
Recuperation des session / promotion d'un apprenant pour son espace ENT
"""
def Get_Ent_Student_List_Session_Promotion(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'apprenant_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', 'apprenant_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
"""
Verifier la validité de l'apprenant
"""
is_apprenant_valide_count = MYSY_GV.dbname['apprenant'].count_documents(
{'_id': ObjectId(str(diction['apprenant_id'])),
'valide': '1',
'locked': '0'})
if (is_apprenant_valide_count != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de l'apprenant est invalide ")
return False, " L'identifiant de l'apprenant est invalide ",
apprenant_data = MYSY_GV.dbname['apprenant'].find_one(
{'_id': ObjectId(str(diction['apprenant_id'])),
'valide': '1',
'locked': '0'})
qry = {}
qry['partner_owner_recid'] = apprenant_data['partner_owner_recid']
qry['apprenant_id'] = diction['apprenant_id']
qry['valide'] = "1"
qry['locked'] = "0"
query = [{'$match': {'$and': [qry]}},
{'$sort': {'_id': -1}},
{'$lookup':
{
'from': 'myclass',
'localField': 'class_internal_url',
'foreignField': 'internal_url',
'pipeline': [{'$match': {'$and': [{}, {}]}},
{'$project': {'_id': 1, 'title':1 }}],
'as': 'myclass_collection'
}
},
{'$lookup':
{
'from': 'apprenant',
"let": {'apprenant_id': "$apprenant_id", 'partner_owner_recid': '$partner_owner_recid'},
'pipeline': [{'$match':
{'$expr': {'$and': [
{'$eq': ["$valide", "1"]},
{'$eq': ["$_id", {'$convert': {
'input': "$$apprenant_id",
'to': "objectId",
'onError': {'error': 'true'},
'onNull': {'isnull': 'true'}
}}]},
]}}},
], 'as': 'apprenant_collection'}}
]
#print("#### Get_Apprenant_Tab_Class_Inscrip_Session_Id laa 01 : query = ", query)
RetObject = []
cpt = 0
for retVal in MYSY_GV.dbname['inscription'].aggregate(query):
val = {}
if( "session_id" in retVal.keys() ):
is_active_session_count = MYSY_GV.dbname['session_formation'].count_documents({'_id':ObjectId(str(retVal['session_id'])),
'valide':'1',
'partner_owner_recid':str(retVal['partner_owner_recid']),
'session_status':'1'})
if( is_active_session_count == 1):
session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(retVal['session_id'])),
'valide': '1',
'partner_owner_recid': str(retVal['partner_owner_recid']),
'session_status': '1'}, )
local_node = {}
local_node['id'] = str(cpt)
local_node['inscription_id'] = (str(retVal['_id']))
local_node['session_id'] = (str(retVal['session_id']))
local_node['session_code_session'] = (str(session_data['code_session']))
local_node['session_titre'] = (str(session_data['titre']))
local_node['session_date_du'] = (str(session_data['date_debut']))
local_node['session_date_au'] = (str(session_data['date_fin']))
#print('### retVal = ', retVal)
if ('myclass_collection' in retVal.keys() and len(retVal['myclass_collection']) > 0):
local_node['class_id'] = (str(retVal['myclass_collection'][0]['_id']))
local_node['class_title'] = (str(retVal['myclass_collection'][0]['title']))
RetObject.append(mycommon.JSONEncoder().encode(local_node))
cpt = cpt + 1
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de récuperer la liste des promotion et sessions de l'apprenant"
"""
Cette fonction retourne une formation, prenant en argument le l'_id de la formation
@ -442,7 +588,7 @@ def Get_Ent_Student_Session_Sequence_List(diction):
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', 'session_id', 'apprenant_id']
field_list_obligatoire = ['token', 'apprenant_id']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
@ -462,6 +608,12 @@ def Get_Ent_Student_Session_Sequence_List(diction):
if (local_status is not True):
return local_status, my_partner
filt_session = {}
if( 'session_id' in diction.keys() and diction['session_id']):
filt_session = {'session_id':str(diction['session_id'])}
"""
Verifier la validité de l'apprenant
"""
@ -485,8 +637,9 @@ def Get_Ent_Student_Session_Sequence_List(diction):
RetObject = []
val_tmp = 0
nb_sequence = 0
for New_retVal in MYSY_GV.dbname['session_formation_sequence'].find({'session_id':str(diction['session_id']),
'partner_owner_recid':str(apprenant_data['partner_owner_recid']), 'valide':'1', 'locked':'0'}):
for New_retVal in MYSY_GV.dbname['session_formation_sequence'].find({'$and':[
{'partner_owner_recid':str(apprenant_data['partner_owner_recid']), 'valide':'1', 'locked':'0'},
filt_session]}):
user = New_retVal
user['id'] = str(val_tmp)

24
main.py
View File

@ -217,8 +217,8 @@ def Ent_Student_login():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Ent_Student_login payload = ",payload)
status, retval, firstconnexion = us.Ent_Student_login(payload)
return jsonify(status=status, message=retval, firstconnexion=firstconnexion)
status, retval, firstconnexion, apprenant_id = us.Ent_Student_login(payload)
return jsonify(status=status, message=retval, firstconnexion=firstconnexion, apprenant_id=apprenant_id)
@ -12312,7 +12312,7 @@ choisir un planning modele
def Apply_Planning_Model_To_Session():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Apply_Planning_Model_To_Session payload = no display, trop lng",)
print(" ### Apply_Planning_Model_To_Session payload = no display, trop lng")
status, retval = model_planning_sequence_mgt.Apply_Planning_Model_To_Session(payload)
return jsonify(status=status, message=retval)
@ -13845,6 +13845,24 @@ def Get_Apprenant_Tab_Class_Inscrip_Session_Id():
status, retval = ent_student_common.Get_Apprenant_Tab_Class_Inscrip_Session_Id( payload)
return jsonify(status=status, message=retval)
"""
API - Gestion ENT Apprenant : Récuperation de la liste des sessions et promotion d'un apprenant
"""
@app.route('/myclass/api/Get_Ent_Student_List_Session_Promotion/', methods=['POST','GET'])
@crossdomain(origin='*')
def Get_Ent_Student_List_Session_Promotion():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Get_Ent_Student_List_Session_Promotion : payload = ",str(payload))
status, retval = ent_student_common.Get_Ent_Student_List_Session_Promotion( payload)
return jsonify(status=status, message=retval)
"""
API - Gestion ENT Apprenant : Recuperation du detail d'une formation
"""

View File

@ -283,7 +283,7 @@ def Get_List_Sequence_Planning_Model_Header(diction):
RetObject = []
val_tmp = 0
for retval in MYSY_GV.dbname['planning_model_header'].find(data_header_qry):
for retval in MYSY_GV.dbname['planning_model_header'].find(data_header_qry).sort([("_id", pymongo.DESCENDING), ]):
user = retval
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
@ -541,6 +541,26 @@ def Get_Given_Sequence_Planning_Model_With_Option(diction):
new_planning_line_node = {}
new_planning_line_node = planning_line
ue_titre = ""
ue_code = ""
if ("ue_id" not in planning_line.keys()):
new_planning_line_node['ue_id'] = ""
elif ("ue_id" in planning_line.keys() and planning_line['ue_id']):
eu_id_data = MYSY_GV.dbname['unite_enseignement'].find_one({'_id': ObjectId(str(planning_line['ue_id'])),
'partner_owner_recid': str(
my_partner['recid'])})
if (eu_id_data and "titre" in eu_id_data.keys()):
ue_titre = eu_id_data['titre']
if (eu_id_data and "code" in eu_id_data.keys()):
ue_code = eu_id_data['code']
new_planning_line_node['ue_code'] = ue_code
new_planning_line_node['ue_titre'] = ue_titre
planning_line_sequence_start = str(planning_line['sequence_start'])
local_status = mycommon.CheckisDate_Hours(planning_line_sequence_start)
if (local_status is False):
@ -744,7 +764,22 @@ def Apply_Planning_Model_To_Session(diction):
local_node['grp_apprenant_id'] = ""
local_node['ue_id'] = ""
if("local_ue_id" in new_sequence.keys() ):
local_node['ue_id'] = new_sequence['local_ue_id']
else:
local_node['ue_id'] = ""
if ("local_mode_animation" in new_sequence.keys()):
local_node['mode_animation'] = new_sequence['local_mode_animation']
else:
local_node['mode_animation'] = ""
if ("local_volume_theorique" in new_sequence.keys()):
local_node['volume_theorique'] = new_sequence['local_volume_theorique']
else:
local_node['volume_theorique'] = ""
local_node['ue_planif_line_id'] = ""
MYSY_GV.dbname['session_formation_sequence'].insert_one(local_node)

View File

@ -210,7 +210,7 @@ def Ent_Student_login(diction):
for val in incom_keys:
if str(val).lower() not in str(field_list).lower():
mycommon.myprint(str(inspect.stack()[0][3])+" Le champ '" + val + "' n'existe pas, MAJ annulée")
return False, " Impossible de se connecter, merci de contacter le support technique", False
return False, " Impossible de se connecter, merci de contacter le support technique", False, False
'''
Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
@ -220,7 +220,7 @@ def Ent_Student_login(diction):
for val in field_list_obligatoire:
if str(val).lower() 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 se connecter, merci de contacter le support technique", False
return False, " Impossible de se connecter, merci de contacter le support technique", False, False
query = {}
# recuperation des paramettre
@ -256,7 +256,7 @@ def Ent_Student_login(diction):
if (tmp != 1):
mycommon.myprint(str(inspect.stack()[0][3])+" Login/mot de passe invalide " + str(query)+ " my_user.count() = "+str(tmp))
return False, " Login/mot de passe invalide, merci de verifier votre saisie. ", False
return False, " Login/mot de passe invalide, merci de verifier votre saisie. ", False, False
my_user = coll_name.find(query)
@ -330,13 +330,12 @@ def Ent_Student_login(diction):
if ("_id" not in ret_val.keys()):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Impossible de récupérer les données de l'utilisateur (2)")
return False, " Impossible de récupérer les données de l'utilisateur (2) ", False
return False, " Impossible de récupérer les données de l'utilisateur (2) ", False, False
return True, str(my_token), str(user_firstconnexion)
return True, str(my_token), str(user_firstconnexion), str(ret_val['apprenant_id'])
else:
mycommon.myprint(str(inspect.stack()[0][3])+" Impossible d'enregistrer le token " + my_token)
return False, " Impossible de se connecter, merci de contacter le support technique", False
return False, " Impossible de se connecter, merci de contacter le support technique", False, False
except Exception as e: