From f047239431e3644b749ab4c96bd3d0ebe4de153d Mon Sep 17 00:00:00 2001 From: Cherif Date: Sat, 27 Jun 2026 19:45:17 +0200 Subject: [PATCH] 27/06/26 - 18h Signed-off-by: Cherif --- .idea/workspace.xml | 41 +- Inscription_mgt.py | 728 +- Inscription_mgt_ORIG_2706.py | 20823 +++++++++++++++++++++++++++++++++ Log/log_file.log | 3182 +++++ apprenant_mgt.py | 363 + main.py | 33 + partner_client.py | 16 +- session_admission_fi.py | 80 +- 8 files changed, 25201 insertions(+), 65 deletions(-) create mode 100644 Inscription_mgt_ORIG_2706.py diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 9ff673b..7774c8d 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,20 +4,15 @@ - @@ -528,6 +522,7 @@ - \ No newline at end of file diff --git a/Inscription_mgt.py b/Inscription_mgt.py index ed609f5..4ac86fb 100644 --- a/Inscription_mgt.py +++ b/Inscription_mgt.py @@ -3467,9 +3467,13 @@ def SendPre_InscriptionEmail(diction): if local_session[0]['employeur']: data_mail['employeur'] = local_session[0]['employeur'] + telephone = "" if ("telephone" in local_session[0].keys()): if local_session[0]['telephone']: - data_mail['telephone'] = local_session[0]['telephone'] + telephone = local_session[0]['telephone'] + + data_mail['telephone'] = telephone + # 1 - Recuperation des données de la formation local_class = MYSY_GV.dbname['myclass'].find({'internal_url': str(local_session[0]['class_internal_url']), @@ -3622,6 +3626,7 @@ def SendPre_InscriptionEmail(diction): + # Envoi de l'email de notification au formateur local_status, local_message = email_session.Notification_partner_Pre_incription_mail(data_mail) @@ -7468,6 +7473,186 @@ def CancelAttendeeInscription(diction): +""" +Annuler les inscription_ID_ en mass +""" +def Cancel_Tab_Inscription(diction): + try: + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', 'tab_inscription_ids'] + 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 ne sont pas correctes" + + mytoken = "" + if ("token" in diction.keys()): + if diction['token']: + mytoken = diction['token'] + + + + local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data({'token':str(diction['token'])}) + if (local_status is not True): + return local_status, my_partner + + + partner_recid = str(my_partner['recid']) + + tab_inscription_ids_work = str(diction['tab_inscription_ids']).split(",") + tab_inscription_ids = [] + tab_inscription_ids_ObjectId = [] + + for tmp in tab_inscription_ids_work: + if( tmp ): + tab_inscription_ids.append(str(tmp)) + tab_inscription_ids_ObjectId.append(ObjectId(str(tmp))) + + nb_annulation = 0 + for tab_inscrption_id in tab_inscription_ids : + + # 2 - Recuperation des données de l'inscription + local_inscription = MYSY_GV.dbname['inscription'].find({'_id': ObjectId(str(tab_inscrption_id)), + 'partner_owner_recid': str(my_partner['recid']), + }) + + print(" ### III local_inscription = ", local_inscription) + + if( local_inscription and "_id" in local_inscription[0].keys()): + + nb_annulation = nb_annulation + 1 + data_mail = {} + # 1 - Recuperation des données de la formation + print(" QRY class = ", {'_id': ObjectId(str(local_inscription[0]['class_id'])), + 'partner_owner_recid': str(my_partner['recid']),}) + + local_class = MYSY_GV.dbname['myclass'].find_one({'_id': ObjectId(str(local_inscription[0]['class_id'])), + 'partner_owner_recid': str(my_partner['recid']),}, {'title':1}) + data_mail['title'] = local_class['title'] + class_title = local_class['title'] + + + lms_class_code = "" + if ("lms_class_code" in local_inscription[0].keys()): + if local_inscription[0]['lms_class_code']: + lms_class_code = local_inscription[0]['lms_class_code'] + + lms_user_id = "" + if ("lms_user_id" in local_inscription[0].keys()): + if local_inscription[0]['lms_user_id']: + lms_user_id = local_inscription[0]['lms_user_id'] + + nom = "" + if ("nom" in local_inscription[0].keys()): + if local_inscription[0]['nom']: + nom = local_inscription[0]['nom'] + + prenom = "" + if ("prenom" in local_inscription[0].keys()): + if local_inscription[0]['prenom']: + prenom = local_inscription[0]['prenom'] + + email = "" + if ("email" in local_inscription[0].keys()): + if local_inscription[0]['email']: + email = local_inscription[0]['email'] + + date_du = "" + if ("date_du" in local_inscription[0].keys()): + if local_inscription[0]['date_du']: + date_du = str(local_inscription[0]['date_du'])[0:10] + + date_au = "" + if ("date_au" in local_inscription[0].keys()): + if local_inscription[0]['date_au']: + date_au = str(local_inscription[0]['date_au'])[0:10] + + + # Recuperation des données de la session + local_session = MYSY_GV.dbname['session_formation'].find_one( + {'_id': ObjectId(str(local_inscription[0]['session_id'])), 'partner_owner_recid': str(my_partner['recid']), }) + + if (local_session is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer les données de la session ") + return False, " Impossible de récupérer les données de la session " + + # Annulation de l'inscription + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + + ret_val2 = MYSY_GV.dbname['inscription'].find_one_and_update( + {'_id': ObjectId(str(tab_inscrption_id)), + 'partner_owner_recid': str(my_partner['recid'])}, + {"$set": {'status':'-1', 'inscription_refuse_date':now, 'date_update':now}}, + return_document=ReturnDocument.AFTER, + upsert=False, + ) + + if( ret_val2 is None ): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible d'annuler l'inscription ") + return False, " Impossible d'annuler l'inscription " + + """ + Verification s'il y a une inscription LMS, au quel cas, on l'annule aussi + """ + + return_message = "" + + if( lms_user_id.strip() != ""): + # Il a une inscription à une formation dans le LMS, il faut l'annuler + new_diction = {} + new_diction['token'] = str(diction['token']) + new_diction['user_lms_id'] = str(lms_user_id) + new_diction['course_code'] = str(lms_class_code) + + local_status, local_message = mys_lms.Remove_User_From_LMS_Class(new_diction) + if (local_status is False): + mycommon.myprint(str(inspect.stack()[0][3]) + " - WARNING : Impossible de supprimer l'inscription dans le LMS pour "+str( diction['email']) ) + return_message = "Impossible de supprimer l'inscription dans le LMS pour : "+str( diction['email']) + + """ + 13/12/2025 : + On n'envoit la notification d'annulation que la paramettre 'annulation_inscription_notification_email' est à 1 + """ + local_insc_status, local_insc_retval = mycommon.Is_Partnair_Annulation_Inscription_Notification( {'token': diction['token']}) + if (local_insc_status and local_insc_retval == "1"): + print(" ###OK on doit envoyer l'email d'annulation à l'apprenant = ") + email_data = {} + email_data['token'] = str(diction['token']) + email_data['nom'] = nom + email_data['prenom'] = prenom + email_data['email'] = email + email_data['date_du'] = date_du + email_data['date_au'] = date_au + email_data['title'] = class_title + email_data['partner_owner_recid'] = str(partner_recid) + + + local_status, local_message = email_session.incription_training_cancelled_mail(email_data) + if( local_status is False ): + mycommon.myprint(str( + inspect.stack()[0][3]) + " - WARNING : Impossible d'envoyer le mail de notification pour " + str( + diction['email'])) + return_message = return_message + str(" Impossible d'envoyer le mail de notification pour : " + str(diction['email'])) + + if( return_message.strip() != ""): + return True, return_message + + + + return True, "Annulation de "+str(nb_annulation)+" inscription(s)" + + except Exception as e: + 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 d'annuler les inscriptions" + + + + """ Cette fonction refuse une inscription, met jour le motif de refus et envoie un email au participants @@ -9977,7 +10162,7 @@ def Get_Statgaire_List_Partner_with_filter_OLD(diction): ], 'as': 'apprenant_collection'}} ] - #print("#### Get_Statgaire_List_Partner_with_filter laa 01 : query = ", query) + #print("#### Get_Statgaire_List_Partner_with_filter laa 02 : query = ", query) RetObject = [] cpt = 0 for retVal in MYSY_GV.dbname['inscription'].aggregate(query): @@ -10556,15 +10741,15 @@ def Get_Statgaire_List_Partner_with_filter(diction): {'$sort': {'_id': -1}}, {'$lookup': { - 'from': 'myclass', - 'let': {'class_id': "$class_id", 'partner_owner_recid': '$partner_owner_recid'}, + 'from': 'session_formation', + 'let': {'session_id': "$session_id", 'partner_owner_recid': '$partner_owner_recid'}, 'pipeline': [ {'$match': {'$expr': {'$and': [ {'$eq': ["$_id", {'$convert': { - 'input': "$$class_id", + 'input': "$$session_id", 'to': "objectId", 'onError': {'error': 'true'}, 'onNull': {'isnull': 'true'} @@ -10577,30 +10762,15 @@ def Get_Statgaire_List_Partner_with_filter(diction): } } }, - {'$project': {"_id": 1, "order_header_ref_interne": 1, "external_code": 1, - "title": 1, "partner_owner_recid": 1, "valide": 1} + {'$project': {"_id": 1,'code_session':1, 'date_debut':1, 'date_fin':1, 'code_postal':1, 'prix_session':1, 'presentiel':1, 'distantiel':1, + 'session_ondemande':1, "partner_owner_recid": 1, "valide": 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_Statgaire_List_Partner_with_filter laa 01 : query = ", query) @@ -10947,6 +11117,520 @@ def Get_Statgaire_List_Partner_with_filter(diction): return False, "Impossible de récupérer la liste des stagiaires" +def Get_Statgaire_List_Partner_with_filter_uptimized(diction): + try: + field_list = ['token', 'class_internal_url', 'code_session', 'status', 'email', 'nom', + 'class_title', 'code_session', 'client_nom', 'client_rattachement_id', + 'session_id', 'archive', 'invoiced'] + 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_class_title = {} + if ("class_title" in diction.keys()): + filt_class_title = { + 'title': {'$regex': mycommon.regex_replace_cartere(str(diction['class_title'])), "$options": "i"}} + + filt_class_internal_url = {} + if ("class_internal_url" in diction.keys()): + filt_class_internal_url = { + 'class_internal_url': {'$regex': mycommon.regex_replace_cartere(str(diction['class_internal_url'])), + "$options": "i"}} + + filt_email = {} + if ("email" in diction.keys()): + filt_email = {'email': {'$regex': mycommon.regex_replace_cartere(str(diction['email'])), "$options": "i"}} + + filt_nom = {} + if ("nom" in diction.keys()): + filt_nom = {'nom': {'$regex': mycommon.regex_replace_cartere(str(diction['nom'])), "$options": "i"}} + + """ + Filtre général + """ + if ("nom" in diction.keys()): + qry_gle = {"$or": [ + {'prenom': {'$regex': mycommon.regex_replace_cartere(str(diction['nom'])), "$options": "i"}}, + {'nom': {'$regex': mycommon.regex_replace_cartere(str(diction['nom'])), "$options": "i"}}, + {'email': {'$regex': mycommon.regex_replace_cartere(str(diction['nom'])), "$options": "i"}}, + {'telephone': {'$regex': mycommon.regex_replace_cartere(str(diction['nom'])), "$options": "i"}}, + ]} + else: + qry_gle = {} + + filt_class_partner_recid = {'partner_owner_recid': str(partner_recid)} + + filt_client_rattachement_id = {} + if ("client_rattachement_id" in diction.keys()): + filt_client_rattachement_id = {'client_rattachement_id': str(diction['client_rattachement_id'])} + + filt_session_id = {} + if ("session_id" in diction.keys()): + filt_session_id = {'session_id': str(diction['session_id'])} + + filt_invoiced = {} + if ("invoiced" in diction.keys() and str(diction['invoiced']).strip() == "1"): + filt_invoiced = {'invoiced': str(diction['invoiced'])} + + if ("invoiced" in diction.keys() and str(diction['invoiced']).strip() != "1" ): + filt_invoiced = {'invoiced': {'$ne':'1'} } + + # ----- + + filt_client_nom = {} + sub_filt_client_nom = {} + Lists_partner_client_id = [] + if ("client_nom" in diction.keys()): + + sub_filt_client_nom = {"$or": [ + {'raison_sociale': {'$regex': mycommon.regex_replace_cartere(str(diction['client_nom'])), "$options": "i"}, }, + {'nom': {'$regex': mycommon.regex_replace_cartere(str(diction['client_nom'])), "$options": "i"}, 'partner_owner_recid': str(partner_recid), 'valide': '1', 'locked': '0'}, + {'email': {'$regex': mycommon.regex_replace_cartere(str(diction['client_nom'])), "$options": "i"}, 'partner_owner_recid': str(partner_recid), 'valide': '1', 'locked': '0'}, + {'telephone': {'$regex': mycommon.regex_replace_cartere(str(diction['client_nom'])), "$options": "i"}, 'partner_owner_recid': str(partner_recid), 'valide': '1', 'locked': '0'}, + + ]} + + + # Recuperation des '_id' des clients dont le nom match en regexp + print(" ### sub_filt_client_nom = ", sub_filt_client_nom) + for List_Client_Data in MYSY_GV.dbname['partner_client'].find(sub_filt_client_nom, {'_id': 1}): + Lists_partner_client_id.append(str(List_Client_Data['_id'])) + + filt_client_nom = {'client_rattachement_id': {'$in': Lists_partner_client_id, }} + print(' ### filt_client_nom = ', filt_client_nom) + + # ---- + + query = [{'$match': + { + '$and': [filt_archive, filt_class_internal_url, filt_session_code, qry_gle, filt_client_nom, + filt_client_rattachement_id, + filt_session_id, filt_invoiced, {'partner_owner_recid': str(partner_recid), 'valide': '1', + 'class_id': {'$exists': True, '$ne': ""}, + 'session_id': {'$exists': True, '$ne': ""} + }]}}, + + {'$sort': {'_id': -1}}, + {'$lookup': + { + 'from': 'session_formation', + 'let': {'session_id': "$session_id", 'partner_owner_recid': '$partner_owner_recid'}, + 'pipeline': [ + {'$match': + {'$expr': + {'$and': + [ + {'$eq': ["$_id", {'$convert': { + 'input': "$$session_id", + 'to': "objectId", + 'onError': {'error': 'true'}, + 'onNull': {'isnull': 'true'} + }}]}, + + {'$eq': ["$valide", "1"]}, + {'$eq': ["$partner_owner_recid", '$$partner_owner_recid']}, + + ] + } + } + }, + {'$project': {"_id": 1,'code_session':1, 'date_debut':1, 'date_fin':1, 'code_postal':1, 'prix_session':1, 'presentiel':1, 'distantiel':1, + 'session_ondemande':1, "partner_owner_recid": 1, "valide": 1} + }, + ], + 'as': 'session_formation_collection' + + } + }, + + ] + + #print("#### Get_Statgaire_List_Partner_with_filter_uptimized laa 01 : query = ", query) + RetObject = [] + cpt = 0 + for retVal in MYSY_GV.dbname['inscription'].aggregate(query): + val = {} + + + # 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 (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'] + + + + type_apprenant_code = "" + type_apprenant_id = "" + if ("type_apprenant_id" in retVal.keys() and retVal['type_apprenant_id']): + type_apprenant_data = MYSY_GV.dbname['type_apprenant'].find_one( + {'_id': ObjectId(str(retVal['type_apprenant_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(retVal['partner_owner_recid'])}) + + if (type_apprenant_data and "code" in type_apprenant_data.keys()): + type_apprenant_code = str(type_apprenant_data['code']) + type_apprenant_id = str(type_apprenant_data['_id']) + + val['type_apprenant_code'] = type_apprenant_code + val['type_apprenant_id'] = type_apprenant_id + + ### + + + 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 ("archive" not in retVal.keys()): + val['archive'] = "0" + + if ("opco" in retVal.keys()): + + val['opco'] = retVal['opco'] + else: + val['opco'] = "" + + + + 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 ("ville" in retVal.keys()): + val['ville'] = retVal['ville'] + else: + val['ville'] = "" + + + val['status'] = retVal['status'] + + val['class_id'] = str(retVal['class_id']) + + + + 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 + + + + session_retval = {} + if( "session_formation_collection" in retVal.keys() and len(retVal['session_formation_collection']) > 0 ): + session_retval = retVal['session_formation_collection'][0] + + + if ("titre" in session_retval.keys()): + val['title'] = session_retval['domaine'] + else: + val['title'] = "" + + 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" + + local_class_recyclage = "0" + local_class_recyclage_float = 0 + if ('myclass_collection' in retVal.keys() and len(retVal['myclass_collection']) > 0 + and "recyclage_alert" in retVal['myclass_collection'][0].keys() + and retVal['myclass_collection'][0]['recyclage_alert'] ): + local_class_recyclage = retVal['myclass_collection'][0]['recyclage_alert'] + local_class_recyclage_float = mycommon.tryFloat(str(retVal['myclass_collection'][0]['recyclage_alert'])) + + + if( local_class_recyclage_float > 0 ): + 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" + + """ 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 diff --git a/Inscription_mgt_ORIG_2706.py b/Inscription_mgt_ORIG_2706.py new file mode 100644 index 0000000..09d3efe --- /dev/null +++ b/Inscription_mgt_ORIG_2706.py @@ -0,0 +1,20823 @@ +""" +Ce fichier permets de créer les inscription des stagiaires à une formation +""" +import base64 +import smtplib + +import segno +import xlsxwriter +from email import encoders +from email.mime.base import MIMEBase +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText +import ast +import pymongo +from dateutil.relativedelta import relativedelta +from fontTools.misc.plistlib import end_date +from pymongo import MongoClient +import json +from bson import ObjectId +import re +from datetime import datetime, date, time + +from werkzeug.utils import secure_filename + +import apprenant_mgt +import groupe_inscrit_mgt +import module_editique +import prj_common as mycommon +import secrets +import inspect +import sys, os +import csv +import pandas as pd +from pymongo import ReturnDocument +import GlobalVariable as MYSY_GV +from math import isnan +import GlobalVariable as MYSY_GV +from datetime import timedelta +import email_inscription_mgt as email_session +from flask import send_file +import re +from xhtml2pdf import pisa +import jinja2 +import ftplib +import pysftp +import email_mgt as email_mgt +import lms_chamilo.mysy_lms as mys_lms +from email.message import EmailMessage +import attached_file_mgt as attached_file_mgt +from zipfile import ZipFile +import partner_client as partner_client +import E_Sign_Document as E_Sign_Document +import survey_mgt +import shutil +from werkzeug.utils import secure_filename + + +""" +Enregistrement d'un stagiaire + +Voici les valeurs possibles du statut d'un stagiaire +# 0 ==> Preinscription +# 1 ==> Inscription validée +# 2 ==> Encours d'inscription. Ce statut est surtout utilisé quand on fait de inscription depuis le backoffice par un gestionnaire de formation. +# -1 ==> Inscription annulée + +Important : : Cette foncton est utilisé aussi bien en mode non-connecté qu'en mode connecté +il ne faut donc controler le token que s'il est fourni avec une valeur donnée +Si il n'est pas fourni, on prend le 'partner_owner_recid' de la formation + +Important : 2 : le 'partner_owner_recid' doit etre celui de la session de formation, EN AUCUN CAS CELUI DE LA PERSONNE CONNECTEE + +""" +def AddStagiairetoClass(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 = ['nom', 'prenom', 'email', 'telephone', 'modefinancement', 'opco', + 'class_internal_url', 'session_id', 'employeur', 'status', 'price', + 'inscription_validation_date', 'token', 'client_rattachement_id', + 'adresse', 'code_postal', 'ville', 'pays', 'type_apprenant', 'apprenant_id', 'civilite', + 'tuteur1_nom', 'tuteur1_prenom', 'tuteur1_email', 'tuteur1_telephone', 'tuteur1_adresse', + 'tuteur1_cp', 'tuteur1_ville', 'tuteur1_pays', 'tuteur1_include_com', + 'tuteur2_nom', 'tuteur2_prenom', 'tuteur2_email', 'tuteur2_telephone', 'tuteur2_adresse', + 'tuteur2_cp', 'tuteur2_ville', 'tuteur2_pays', 'tuteur2_include_com','date_naissance', + 'financeur_rattachement_id', 'tuteur1_civilite', 'tuteur2_civilite', 'quotation_id', + 'facture_client_rattachement_id', 'tab_ue_ids','memo', 'comment', + 'is_handicap', 'is_droit_image', 'is_rgpd', 'nationalite', 'situation_famille', 'naissance_lieu', + 'naissance_departement', + 'naissance_pays', 'num_secu', 'identite_type', 'piece_identite_num', 'type_mobilite', + 'telephone_bis', 'frequence_facturation', 'ine', 'matricule', 'modefinancement_id', 'type_apprenant_id', + 'nom_fille', 'num_cvec', 'handicap_detail', 'employeur_id', 'categorie_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, "Toutes les informations fournies ne sont pas valables" + + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['nom', 'prenom', 'email', 'telephone', + 'class_internal_url', '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, "Impossible de créer le stagiaire. La valeur '" + val + "' n'est pas presente dans la liste des arguments" + + my_partner = None + connected_user_id = "None" + if( "token" in diction.keys() and 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 + + connected_user_id = my_partner['recid'] + + """ + Verifier qu'il n'y pas un étudiant avec le meme INE (Identifiant National Étudiant) + """ + if ("ine" in diction.keys() and diction['ine']): + is_exist_ine_count = MYSY_GV.dbname['inscription'].count_documents( + {'ine': str(diction['ine']), + 'session_id': str(diction['session_id']), + 'partner_owner_recid': str(my_partner['recid']) + }) + + if (is_exist_ine_count > 0): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " Il y a déjà un candidat avec le même numéro Identifiant National Étudiant (INE) ") + return False, " Il y a déjà un candidat avec le même numéro Identifiant National Étudiant (INE) " + + + if( "email" in diction.keys() and diction['email']): + diction['email'] = str(diction['email']).strip().lower() + + + #print(" #### my_partner = ", my_partner) + + """ + Verifier que la formation est valide + """ + is_myclass_valide_count = MYSY_GV.dbname['myclass'].count_documents({'internal_url':str(diction['class_internal_url']), + 'valide':'1', + 'locked':'0', + }) + + + if( is_myclass_valide_count <= 0 ): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " L'identifiant de la formation est invalide ") + return False, " L'identifiant de la formation est invalide " + + if (is_myclass_valide_count > 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + str(is_myclass_valide_count)+" formations ont le même internal_url. Or un 'internal_url' correspond à une et une seule formation. internal_url est "+str(diction['class_internal_url'])) + return False, str(is_myclass_valide_count)+" formations ont le même internal_url." + + is_myclass_valide_data = MYSY_GV.dbname['myclass'].find_one({'internal_url':str(diction['class_internal_url']), + 'valide':'1', + 'locked':'0', + }) + + + + """ + Important : : 01/08/2024 + Si 'my_partner' est NONE, on va recuperer les données coorespondant au compte admin du partnenaire . + On ajoute aussi le token au dictionnaire + """ + if(my_partner is None ): + local_status, my_partner = mycommon.Get_Connected_User_Partner_Data_From_RecID( + str(is_myclass_valide_data['partner_owner_recid'])) + if (local_status is not True): + return local_status, my_partner + + diction['token'] = my_partner['token'] + + + if( "modefinancement_id" in diction.keys() and diction['modefinancement_id']): + is_valide_modefinancement_id = MYSY_GV.dbname['financement_mode'].count_documents({'_id':ObjectId(str(diction['modefinancement_id'])), + 'valide':'1', + 'locked':'0', + 'partner_owner_recid':str(my_partner['recid'])}) + + if( is_valide_modefinancement_id != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " Le mode de financement est invalide ") + return False, " Le mode de financement est invalide " + + + if ("type_apprenant_id" in diction.keys() and diction['type_apprenant_id']): + is_valide_type_apprenant_id = MYSY_GV.dbname['type_apprenant'].count_documents( + {'_id': ObjectId(str(diction['type_apprenant_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_valide_type_apprenant_id != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " Le type d'apprenant est invalide ") + return False, " Le type d'apprenant est invalide " + + if ("employeur_id" in diction.keys() and diction['employeur_id']): + is_valide_employeur_id = MYSY_GV.dbname['partner_client'].count_documents( + {'_id': ObjectId(str(diction['employeur_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_valide_employeur_id != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " L'employeur est invalide ") + return False, " L'employeur est invalide " + + if ("categorie_id" in diction.keys() and diction['categorie_id']): + is_valide_categorie_id = MYSY_GV.dbname['categorie_apprenant'].count_documents( + {'_id': ObjectId(str(diction['categorie_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_valide_categorie_id != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " La catégorie de l'apprenant est invalide ") + return False, " La catégorie de l'apprenant est invalide " + + #print(" #### my_partner V2 = ", my_partner) + + mydata = {} + + # Initialisation des champs non envoyés à vide + for val in field_list: + if val not in diction.keys(): + mydata[str(val)] = "" + + # Initialisation des champs non envoyés à vide + for val in field_list: + if val not in diction.keys(): + mydata[str(val)] = "" + + session_id = "" + if ("session_id" in diction.keys()): + if diction['session_id']: + session_id = str(diction['session_id']).strip() + mydata['session_id'] = session_id + + memo = "" + if ("memo" in diction.keys()): + if diction['memo']: + memo = str(diction['memo']).strip() + mydata['memo'] = memo + + comment = "" + if ("comment" in diction.keys()): + if diction['comment']: + comment = str(diction['comment']).strip() + mydata['comment'] = comment + + nom_fille = "" + if ("nom_fille" in diction.keys()): + if diction['nom_fille']: + nom_fille = str(diction['nom_fille']).strip() + mydata['nom_fille'] = nom_fille + + num_cvec = "" + if ("num_cvec" in diction.keys()): + if diction['num_cvec']: + comment = str(diction['num_cvec']).strip() + mydata['num_cvec'] = num_cvec + + handicap_detail = "" + if ("handicap_detail" in diction.keys()): + if diction['handicap_detail']: + handicap_detail = str(diction['handicap_detail']).strip() + mydata['handicap_detail'] = handicap_detail + + type_apprenant_id = "" + if ("type_apprenant_id" in diction.keys()): + type_apprenant_id = str(diction['type_apprenant_id']) + mydata['type_apprenant_id'] = type_apprenant_id + + + modefinancement_id = "" + if ("modefinancement_id" in diction.keys()): + modefinancement_id = str(diction['modefinancement_id']) + mydata['modefinancement_id'] = modefinancement_id + + employeur_id = "" + if ("employeur_id" in diction.keys()): + employeur_id = str(diction['employeur_id']) + mydata['employeur_id'] = employeur_id + + categorie_id = "" + if ("categorie_id" in diction.keys()): + categorie_id = str(diction['categorie_id']) + mydata['categorie_id'] = categorie_id + + + + ine = "" + if ("ine" in diction.keys()): + if diction['ine']: + ine = str(diction['ine']).strip() + mydata['ine'] = ine + + matricule = "" + if ("matricule" in diction.keys()): + if diction['matricule']: + matricule = str(diction['matricule']).strip() + mydata['matricule'] = matricule + + + + if ("is_handicap" in diction.keys() and str(diction['is_handicap']) not in ['0', '1', '']): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'is_handicap' est invalide ") + return False, " Le champ 'is_handicap' est invalide " + + is_handicap = "" + if ("is_handicap" in diction.keys()): + if diction['is_handicap']: + is_handicap = str(diction['is_handicap']).strip() + mydata['is_handicap'] = is_handicap + + + + if ("is_droit_image" in diction.keys() and str(diction['is_droit_image']) not in ['0', '1', '']): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'is_droit_image' est invalide ") + return False, " Le champ 'is_droit_image' est invalide " + + is_droit_image = "" + if ("is_droit_image" in diction.keys()): + if diction['is_droit_image']: + is_droit_image = str(diction['is_droit_image']).strip() + mydata['is_droit_image'] = is_droit_image + + + if ("situation_famille" in diction.keys() and str(diction['situation_famille']) not in MYSY_GV.SITUATION_FAMILLE): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'situation_famille' est invalide ") + return False, " Le champ 'situation_famille' est invalide " + + situation_famille = "" + if ("situation_famille" in diction.keys()): + if diction['situation_famille']: + situation_famille = str(diction['situation_famille']).strip() + mydata['situation_famille'] = situation_famille + + + if ("identite_type" in diction.keys() and str(diction['identite_type']) not in MYSY_GV.PICE_IDENTITE_TYPE): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'identite_type' est invalide ") + return False, " Le champ 'identite_type' est invalide " + + identite_type = "" + if ("identite_type" in diction.keys()): + if diction['identite_type']: + identite_type = str(diction['identite_type']).strip() + mydata['identite_type'] = identite_type + + + if ("type_mobilite" in diction.keys() and str(diction['type_mobilite']) not in MYSY_GV.APPRENANT_MOBILITE): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'type_mobilite' est invalide ") + return False, " Le champ 'type_mobilite' est invalide " + + type_mobilite = "" + if ("type_mobilite" in diction.keys()): + if diction['type_mobilite']: + type_mobilite = str(diction['type_mobilite']).strip() + mydata['type_mobilite'] = type_mobilite + + + + nationalite = "" + if ("nationalite" in diction.keys()): + if diction['nationalite']: + nationalite = str(diction['nationalite']).strip() + mydata['nationalite'] = nationalite + + naissance_lieu = "" + if ("naissance_lieu" in diction.keys()): + if diction['naissance_lieu']: + naissance_lieu = str(diction['naissance_lieu']).strip() + mydata['naissance_lieu'] = naissance_lieu + + naissance_departement = "" + if ("naissance_departement" in diction.keys()): + if diction['naissance_departement']: + naissance_departement = str(diction['naissance_departement']).strip() + mydata['naissance_departement'] = naissance_departement + + naissance_pays = "" + if ("naissance_pays" in diction.keys()): + if diction['naissance_pays']: + naissance_pays = str(diction['naissance_pays']).strip() + mydata['naissance_pays'] = naissance_pays + + num_secu = "" + if ("num_secu" in diction.keys()): + if diction['num_secu']: + num_secu = str(diction['num_secu']).strip() + mydata['num_secu'] = num_secu + + piece_identite_num = "" + if ("piece_identite_num" in diction.keys()): + if diction['piece_identite_num']: + piece_identite_num = str(diction['piece_identite_num']).strip() + mydata['piece_identite_num'] = piece_identite_num + + telephone_bis = "" + if ("telephone_bis" in diction.keys()): + if diction['telephone_bis']: + telephone_bis = str(diction['telephone_bis']).strip() + mydata['telephone_bis'] = telephone_bis + + + frequence_facturation = "" + if ("frequence_facturation" in diction.keys() and diction['frequence_facturation'] not in MYSY_GV.INSCRIT_FREQUENCE_FACTURE ): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La fréquence de facturation doit être "+str(MYSY_GV.INSCRIT_FREQUENCE_FACTURE)) + return False, " La fréquence de facturation doit être "+str(MYSY_GV.INSCRIT_FREQUENCE_FACTURE) + frequence_facturation = diction['frequence_facturation'] + + mydata['frequence_facturation'] = frequence_facturation + + + + if ("is_rgpd" in diction.keys() and str(diction['is_rgpd']) not in ['0', '1', '']): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'is_rgpd' est invalide ") + return False, " Le champ 'is_rgpd' est invalide " + + is_rgpd = "" + if ("is_rgpd" in diction.keys()): + if diction['is_rgpd']: + is_rgpd = str(diction['is_rgpd']).strip() + mydata['is_rgpd'] = is_rgpd + + """ + Verififier l'existance et la valididé de la session + """ + my_session_data_qry = {"_id":ObjectId(str(session_id)), 'valide':'1' } + #print(" AddStagiairetoClass my_session_data_qry = ", my_session_data_qry) + + my_session_data = MYSY_GV.dbname['session_formation'].find_one(my_session_data_qry) + if( my_session_data is None ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de la session est invalide session_id = "+ str(session_id)) + return False, " L'identifiant de la session est invalide" + + mytoken = "" + if ("token" in diction.keys()): + if diction['token']: + mytoken = str(diction['token']).strip() + + apprenant_id = "" + if ("apprenant_id" in diction.keys()): + if diction['apprenant_id']: + apprenant_id = str(diction['apprenant_id']).strip() + mydata['apprenant_id'] = str(apprenant_id) + + date_naissance = "" + if ("date_naissance" in diction.keys()): + if diction['date_naissance']: + date_naissance = str(diction['date_naissance']).strip() + + local_status = mycommon.CheckisDate(date_naissance) + if (local_status is False): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La date de naissance n'est pas au format 'jj/mm/aaaa' ") + return False, " La date de naissance n'est pas au format 'jj/mm/aaaa' " + + mydata['date_naissance'] = str(date_naissance) + + + + """ + Recuperation des info de la session de formation + """ + + """ + update : 13/07/23 : gestion des prix + + - par defaut si Le champ diction['price'] est rempli, alors on prend cette valeur. + - si cette valeur est vide ou inexistante, on va chercher le prix sur la session. + - Si aucun prix n'est mis sur la session, on va aller cherche le prix sur la formation. + + + """ + + # Verifier que le type d'apprenant est bien valide + type_apprenant = "0" + + if ("type_apprenant" in diction.keys() and diction['type_apprenant'] ): + type_apprenant = str(mycommon.tryInt(diction['type_apprenant'])) + if( type_apprenant not in MYSY_GV.INSCRIPTION_TYPE_APPRENANT): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le type d'apprenant est invalide ") + return False, " Le type d'apprenant est invalide. Valeurs autorisées"+str(MYSY_GV.INSCRIPTION_TYPE_APPRENANT) + + + + new_price = "-1" # 0 ==> par defaut + session_partner_owner_recid = "" + for tmp_val in MYSY_GV.dbname['session_formation'].find({"_id":ObjectId(str(session_id)), 'valide':'1' }): + mydata['date_du'] = str(tmp_val['date_debut'])[0:10] + mydata['date_au'] = str(tmp_val['date_fin'])[0:10] + mydata['partner_owner_recid'] = tmp_val['partner_owner_recid'] + + if ("prix_session" in tmp_val.keys()): + if tmp_val['prix_session']: + new_price = tmp_val['prix_session'] + mydata['price'] = str(new_price) + + + if( "partner_owner_recid" in tmp_val.keys() ): + session_partner_owner_recid = tmp_val['partner_owner_recid'] + + ## Update du 11/12/2023 : On doit prendre le class_internal_url sur la session et non sur la valeur du ditionnaire d'entré. + ## car realité ces deux doivent etre les meme. + if ("class_internal_url" in tmp_val.keys()): + mydata['class_internal_url'] = str(tmp_val['class_internal_url']).strip() + + + civilite = "neutre" + if ("civilite" in diction.keys()): + if diction['civilite']: + civilite = str(diction['civilite']).strip().lower() + + if (str(civilite) not in MYSY_GV.CIVILITE): + civilite = "neutre" + + if( str(civilite).strip() == ""): + civilite = "neutre" + + mydata['civilite'] = civilite + + + nom = "" + if ("nom" in diction.keys()): + if diction['nom']: + nom = str(diction['nom']).strip() + mydata['nom'] = nom + + quotation_id = "" + if ("quotation_id" in diction.keys()): + if diction['quotation_id']: + quotation_id = str(diction['quotation_id']).strip() + + + is_valide_qotation = MYSY_GV.dbname['partner_order_header'].count_documents( + {'_id': ObjectId(str(diction['quotation_id'])), + 'partner_owner_recid': str(my_partner['recid']), + 'order_header_type': 'devis', + 'valide': '1', + 'locked': '0'}) + + if (is_valide_qotation != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant du devis n'est pas valide ") + return False, " L'identifiant du devis n'est pas valide " + + mydata['quotation_id'] = quotation_id + + + prenom = "" + if ("prenom" in diction.keys() and diction['prenom']): + prenom = str(diction['prenom']).strip() + mydata['prenom'] = prenom + + employeur = "" + if ("employeur" in diction.keys() and diction['employeur']): + employeur = str(diction['employeur']).strip() + mydata['employeur'] = employeur + + telephone = "" + if ("telephone" in diction.keys() and diction['telephone']): + telephone = str(diction['telephone']).strip() + mydata['telephone'] = telephone + + if ("client_rattachement_id" in diction.keys() and diction['client_rattachement_id']): + mydata['client_rattachement_id'] = diction['client_rattachement_id'] + + ## Verifier l'existance du client de rattachement + local_client_retval_count = MYSY_GV.dbname['partner_client'].count_documents( {'_id': ObjectId(diction['client_rattachement_id']), + 'valide': '1','locked': '0', 'partner_owner_recid': str(my_session_data['partner_owner_recid'])}) + + if( local_client_retval_count != 1 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " - Le client de rattachement est invalide : local_client_retval_count = "+ str(local_client_retval_count)) + return False, " Le client de rattachement est invalide " + + else: + mydata['client_rattachement_id'] = "" + + + + if ("facture_client_rattachement_id" in diction.keys() and diction['facture_client_rattachement_id']): + mydata['facture_client_rattachement_id'] = diction['facture_client_rattachement_id'] + + ## Verifier l'existance du client de rattachement + local_client_retval_count = MYSY_GV.dbname['partner_client'].count_documents( {'_id': ObjectId(diction['facture_client_rattachement_id']), + 'valide': '1','locked': '0', 'partner_owner_recid': str(my_session_data['partner_owner_recid'])}) + + if( local_client_retval_count != 1 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " - L'entité à facturer est invalide : local_client_retval_count = "+ str(local_client_retval_count)) + return False, " L'entité à facturer est invalide " + + else: + mydata['facture_client_rattachement_id'] = "" + + + """ + 11/07/2024 - si j'ai un client_client, mais pas de client facturé, alors on fait : client_facturé = client_client + """ + + if ("facture_client_rattachement_id" in mydata.keys() and len(str(mydata['facture_client_rattachement_id']).strip()) <= 1 and "client_rattachement_id" in mydata.keys() and + len(str(mydata['client_rattachement_id']).strip()) > 3): + mydata['facture_client_rattachement_id'] = str(mydata['client_rattachement_id']) + + """ + 11/07/2024 - si j'ai un client facture , mais pas de client_client, alors on fait : client_client = client_facturé + """ + if ("client_rattachement_id" in mydata.keys() and len(str(mydata['client_rattachement_id']).strip()) <= 1 and len( + str(mydata['facture_client_rattachement_id']).strip()) > 3): + mydata['client_rattachement_id'] = str(mydata['facture_client_rattachement_id']) + + + + if ("financeur_rattachement_id" in diction.keys() and diction['financeur_rattachement_id']): + mydata['financeur_rattachement_id'] = diction['financeur_rattachement_id'] + + ## Verifier l'existance du client de rattachement + local_client_retval_count = MYSY_GV.dbname['partner_client'].count_documents( + {'_id': ObjectId(diction['financeur_rattachement_id']), + 'valide': '1', 'locked': '0', 'partner_owner_recid': str(my_session_data['partner_owner_recid'])}) + + if (local_client_retval_count != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " - Le client de rattachement est invalide : local_client_retval_count = " + str( + local_client_retval_count)) + return False, " Le financeur est invalide " + + else: + mydata['financeur_rattachement_id'] = "" + + if ("tuteur1_civilite" not in diction.keys()): + mydata['tuteur1_civilite'] = "neutre" + + elif (diction['tuteur1_civilite'] not in MYSY_GV.CIVILITE): + # la civilité n'est pas une de celle autorisée, alors je renvoie vide + mydata['tuteur1_civilite'] = "neutre" + + if ("tuteur2_civilite" not in diction.keys()): + mydata['tuteur2_civilite'] = "neutre" + elif (diction['tuteur2_civilite'] not in MYSY_GV.CIVILITE): + # la civilité n'est pas une de celle autorisée, alors je renvoie vide + mydata['tuteur2_civilite'] = "neutre" + + + if ("ville" in diction.keys() and diction['ville']): + mydata['ville'] = diction['ville'] + else: + mydata['ville'] = "" + + if ("code_postal" in diction.keys() and diction['code_postal']): + mydata['code_postal'] = diction['code_postal'] + else: + mydata['code_postal'] = "" + + if ("adresse" in diction.keys() and diction['adresse']): + mydata['adresse'] = diction['adresse'] + else: + mydata['adresse'] = "" + + + if ("pays" in diction.keys() and diction['pays']): + mydata['pays'] = diction['pays'] + else: + mydata['pays'] = "" + + + if ("inscription_validation_date" in diction.keys() and diction['inscription_validation_date']): + mydata['inscription_validation_date'] = str(diction['inscription_validation_date']).strip() + else: + mydata['inscription_validation_date'] = "" + + if ("email" in diction.keys()): + if diction['email']: + mydata['email'] = str(diction['email']).strip().lower() + regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b' + if (not re.fullmatch(regex, str(diction['email']).strip() ) ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " l'adresse email "+str(diction['email']).strip() +" est invalide") + return False, " l'adresse email -"+str(diction['email']).strip() +"- est invalide" + + + + + if ("modefinancement" in diction.keys() and diction['modefinancement']): + mydata['modefinancement'] = str(diction['modefinancement']).strip() + else: + mydata['modefinancement'] = "" + + if ("opco" in diction.keys() and diction['opco']): + mydata['opco'] = str(diction['opco']).strip() + else: + mydata['opco'] = "" + + mydata['class_id'] = str(is_myclass_valide_data['_id']) + mydata['update_date'] = datetime.now().strftime("%d/%m/%Y %H:%M:%S") + mydata['date_creation'] = datetime.now().strftime("%d/%m/%Y %H:%M:%S") + mydata['update_by'] = str(connected_user_id) + mydata['creation_by'] = str(connected_user_id) + mydata['valide'] = "1" + mydata['locked'] = "0" + + new_status = "2" # 0 ==> par defaut Encours (Inscription en cours de creation, ici, on ne declenche aucun email) + if ("status" in diction.keys()): + if diction['status']: + new_status = str(diction['status']).strip() + if( new_status not in MYSY_GV.INSCRIPTION_STATUS): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le statut d'inscription : " + str(diction['status']) + " est invalide ") + return False, " Le statut d'inscription : " + str(diction['status']) + " est invalide " + + + mydata['status'] = str(new_status) + mydata['type_apprenant'] = str(type_apprenant) + + + # Si un prix est fourni dans le diction, j'ecrase le prise qui est venu de la session + if ("price" in diction.keys() and diction['price']): + new_price = str(diction['price']).strip() + mydata['price'] = str(diction['price']).strip() + + + + # Verification des prix. si new_price = "-1" cela veut dire qu'il n'a pas de prix dans le diction ni sur la session + # Alors on va chercher le prix (prix public sans reduction) sur la formation + if( new_price == "-1"): + print(" aucun prix trouvé sur la session ") + local_class = MYSY_GV.dbname['myclass'].find_one({'internal_url':str(diction['class_internal_url']).strip(), + 'valide':'1', 'locked':'0'}) + + if( 'price' in local_class.keys()): + mydata['price'] = str(local_class['price']).strip() + else: + mydata['price'] = '0' + + + """ + Update du 22/10/2023 - Gestion des champs spécifiques ajoutés par le partenaire + """ + + # Recuperation des champs spécifiques se trouvant dans le dictionnaire. ils commencent tous par 'my_' + for val in diction.keys(): + if (val.startswith('my_')): + if (MYSY_GV.dbname['base_specific_fields'].count_documents( + {'partner_owner_recid': str(session_partner_owner_recid), + 'related_collection': 'inscription', + 'field_name': str(val), + 'valide': '1', + 'locked': '0'}) != 1): + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ") + return False, " Les informations fournies sont incorrectes" + + mydata[str(val)] = diction[str(val)] + + + #print(" #### mydata for inscription = " + str(mydata)) + + coll_inscription = MYSY_GV.dbname['inscription'] + + ## Verification si cette adresse n'est pas deja inscrite à cette session + # print(" myquery pr demo_account = " + str(myquery)) + qry_count = {'email':str(mydata['email']).lower(), 'session_id':str( mydata['session_id']), } + + #print(" ### qry_count = ", qry_count) + tmp = coll_inscription.count_documents({'email':str(mydata['email']).lower(), + 'session_id':str( mydata['session_id']), + }) + + if( tmp > 0 ) : + mycommon.myprint( + str(inspect.stack()[0][3]) + " - L'adresse email "+str(mydata['email'])+" est deja inscrite à la session du " + " "+str( mydata['session_id'])+ " ") + + return False, " L'adresse email "+str(mydata['email'])\ + +" est deja inscrite à cette formation " + + + """ + Un email ne pouvant s'inscrire qu'a une seule session_id; on fait un upsert + """ + #print(" #### mydata before inscr = ", mydata) + ret_val = MYSY_GV.dbname['inscription'].find_one_and_update( + {'session_id': str(mydata['session_id']), 'email': str(mydata['email']).lower(),}, + {"$set": mydata}, + return_document=ReturnDocument.AFTER, + upsert=True, + ) + + if (ret_val is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible d'ajouter la participant ") + return False, " Impossible d'ajouter la participant " + + #ret_val = coll_inscription.insert_one(mydata) + + Warning_message = "" + + inserted_id = ret_val['_id'] + + """ + 26/05/2024 : S'il s'agit d'une formation initiale, alors on lance la fonction 'xxxx' + qui permet de créer les contenus des collection 'inscription_liste_ue' et peut etre 'inscription_liste_ue_type_eval' + + Il s'agit du remplissage par defaut ou tout est actif + + """ + + if ("tab_ue_ids" not in diction.keys() and "formation_initiale" in my_partner.keys() and my_partner['formation_initiale'] == "1" ): + local_diction = {} + local_diction['token'] = diction['token'] + local_diction['inscription_id'] = str(inserted_id) + local_diction['class_id'] = str(is_myclass_valide_data['_id']) + + if("tab_ue_ids" in diction.keys()): + local_diction['tab_ue_ids'] = diction['tab_ue_ids'] + else: + local_diction['tab_ue_ids'] = "" + + #print(" ### Init_AcceptAttendeeInscription_For_Initial_Formation 11 local_diction = ",local_diction ) + + local_inscription_liste_ue_status, local_inscription_liste_ue_retval = Init_AcceptAttendeeInscription_For_Initial_Formation( + local_diction) + + """print(" local_inscription_liste_ue_status, local_inscription_liste_ue_retval = ", + local_inscription_liste_ue_status, local_inscription_liste_ue_retval)""" + + + elif ("tab_ue_ids" in diction.keys() and "formation_initiale" in my_partner.keys() and my_partner['formation_initiale'] == "1" ): + # Ici l'utilisateur a fourni un list d'UE ou il faut inscrire l'apprenant. + # Ceci s'applique lorsque par exemple un apprenant d'inscrit à 1 ou 2 UE sur une formation + local_diction = {} + local_diction['token'] = diction['token'] + local_diction['inscription_id'] = str(inserted_id) + local_diction['class_id'] = str(is_myclass_valide_data['_id']) + if ("tab_ue_ids" in diction.keys()): + local_diction['tab_ue_ids'] = diction['tab_ue_ids'] + else: + local_diction['tab_ue_ids'] = "" + + print(" ### Init_AcceptAttendeeInscription_For_Initial_Formation 22 local_diction = ",local_diction ) + + local_inscription_liste_ue_status, local_inscription_liste_ue_retval = Init_AcceptAttendeeInscription_For_Initial_Formation( + local_diction) + + print(" local_inscription_liste_ue_status, local_inscription_liste_ue_retval = ", + local_inscription_liste_ue_status, local_inscription_liste_ue_retval) + + + + """ + update du 25/08/23 + On ne declenche l'envoie d'un email que l'inscription est soit : + - Preinscrit (hors reservation automatique - validation devis) soit + - inscrit soit + - annulé. + + Donc pas d'email si le statut est (2 => 'encours de creation' + On doit donner la possibilité a l'utilisateur de saisir une inscription avec un statut en cours de creation : 'creation' + """ + + + if( inserted_id ): + # On verifie que le statut de l'inscription n'est pas (2 : en cours) avant de declencher des envoies d'email + + """ + update 21/04/2024 - + si le champs devis est remplis, alors il s'agit d'une inscription qui vient de la validation automatique d'un devis + pour le moment, dans ce cas figure, vu que les email ne sont pas bon car il s'agit d'un resa, alors on ne declenche + pas d'envoie d'email + """ + if( new_status == "0" and quotation_id == ""): + # Le stagaire a bien ete inseré, on declenche l'envoi des emails + + ## Envoie de l'email de preinscription + mail_data = {} + mail_data['token'] = diction['token'] + mail_data['email'] = diction['email'] + mail_data['class_internal_url'] = diction['class_internal_url'] + mail_data['session_id'] = diction['session_id'] + mail_data['inscription_id'] = ret_val['_id'] + + if ("modefinancement" in diction.keys()): + mail_data['modefinancement'] = diction['modefinancement'] + else: + mail_data['modefinancement'] = "" + + if ("opco" in diction.keys()): + mail_data['opco'] = diction['opco'] + else: + mail_data['opco'] = "" + + #print(" ### l'inscription est ok, il faut declencher l'envoi des email a "+str(mail_data)) + """ + 26/02/2025 : + Si le paramettre, 'inscription_notification_email' de la collection 'base_partner_setup' est à 1, + alors on envoie un email de notification à l'apprenant + """ + local_insc_status, local_insc_retval = mycommon.Is_Partnair_Prenscription_Notification( + {'token': diction['token']}) + if (local_insc_status and local_insc_retval == "1"): + local_status, message = SendPre_InscriptionEmail(mail_data) + if( local_status is False): + mycommon.myprint(" WARNING : Impossible d'envoyer le mail de preinscriton à "+ + str(inspect.stack()[0][3]) + " - l'adresse email " + str( + mydata['email']) + " pour la session " + str(mydata['session_id']) + " ") + + Warning_message = " WARNING : Impossible d'envoyer le mail de preinscriton à "+ str(inspect.stack()[0][3]) + " - l'adresse email " + str( mydata['email']) + " pour la session " + str(mydata['session_id']) + " " + + + """ + 05/07/2025 : Aller regarder dans la configuration des traitements automatique de la session si des opérations + doivent etre doclenchés à la preinscription + ex : les client qui souhaite envoyer le questionnaire de positionnement à la préinscription + pour rechercher les actions à declencer à la préinscrition, il faut regarder ici : + session_formation['automatic_traitement'][num_line]['action_target_date'] = 'preinscription' + (my_session_data) + """ + if( "automatic_traitement" in my_session_data and len(my_session_data['automatic_traitement']) > 0 ): + for local_automatic_traitement in my_session_data['automatic_traitement'] : + if( "action_target_date" in local_automatic_traitement.keys() and local_automatic_traitement['action_target_date'] == 'preinscription' + and 'courrier_template_type_document_ref_interne' in local_automatic_traitement.keys() + and local_automatic_traitement['actif'] == '1' and local_automatic_traitement['valide'] == '1' + and local_automatic_traitement['statut'] == '0' and local_automatic_traitement['locked'] == '0' + ): + # Il y a une action a declencher + if( local_automatic_traitement["courrier_template_type_document_ref_interne"] == "QUESTION_POSITIONNEMENT" ): + + # Recuperer le formulaire de positionnement par defaut + formulaire_q_pos_data = MYSY_GV.dbname['formulaire'].find_one({'partner_owner_recid':str(my_partner['recid']), + 'valide':'1', + 'locked':'0', + 'type':'pos', + 'default':'1', + }) + if( formulaire_q_pos_data ): + Init_Survey_data = {} + Init_Survey_data['token'] = diction['token'] + Init_Survey_data['session_id'] = str(my_session_data['_id']) + Init_Survey_data['formulaire_id'] = str(formulaire_q_pos_data['_id']) + Init_Survey_data['survey_type'] = "pos" + Init_Survey_data['tab_inscrit_ids'] = str(inserted_id) + Init_Survey_data['sending_date'] = "" + + qpo_status, qpo_retval = survey_mgt.Init_Survey_Tab_For_All_Session_Inscrit(Init_Survey_data) + + if( qpo_status is True): + #il faut envoyer le questionnaire + survey_data = MYSY_GV.dbname['survey'].find_one({'inscription_id':str(inserted_id), + 'session_id':str(my_session_data['_id']), + 'survey_type':"pos", + 'statut':'0'}) + + + + if( survey_data): + Init_Survey_send_data = {} + Init_Survey_send_data['token'] = diction['token'] + Init_Survey_send_data['tab_ids'] = str(survey_data['_id']) + + + qpo_send_status, qpo_send_retval = survey_mgt.Send_Survey_TabIds(Init_Survey_send_data) + + if (qpo_send_status is False): + mycommon.myprint( + " WARNING : Impossible d'envoyer le questionnaire de positionnement pour l'inscription" + + str(inserted_id) + ", Raison " + qpo_send_retval+ " ") + + + + else: + mycommon.myprint( + str(inspect.stack()[0][3]) + " - ret_val.inserted_id is null ") + return False, "Impossible de créer le stagiaire" + + + + """ + 29/12/2023 : La creation s'est bien passée, si c'est une inscription definitive du premier cout, + c'est a dire que str(new_status) = 1 => Inscription (validée) alors on fait la creation ou une mise à jour + du dossier apprenant en meme tps + """ + if (new_status == "1"): + local_apprenant_id = "" + is_apprenant_existe_count = MYSY_GV.dbname['apprenant'].count_documents( + {'email': str(diction['email']), + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked': '0'}) + + if (is_apprenant_existe_count > 0): + # Il faut mettre à jour un dossier apprenant + is_apprenant_existe = MYSY_GV.dbname['apprenant'].find_one( + {'email': str(diction['email']), + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked': '0'}, {'_id': 1}) + + local_apprenant_matricule = "" + if ("matricule" in is_apprenant_existe.keys()): + local_apprenant_matricule = is_apprenant_existe['matricule'] + + local_apprenant_ine = "" + if ("ine" in is_apprenant_existe.keys()): + local_apprenant_ine = is_apprenant_existe['ine'] + + + new_apprenant_diction = diction + champ_to_delete = ['class_internal_url', 'session_id', 'inscription_validation_date', 'apprenant_id', + 'status', 'modefinancement', 'type_apprenant', 'financeur_rattachement_id', + 'quotation_id', 'facture_client_rattachement_id', 'price', 'modefinancement_id'] + + for val in champ_to_delete: + if (val in new_apprenant_diction.keys()): + del new_apprenant_diction[str(val)] + + new_apprenant_diction['_id'] = str(is_apprenant_existe['_id']) + + local_apprenant_id = str(is_apprenant_existe['_id']) + if( "tab_ue_ids" in new_apprenant_diction.keys()): + del new_apprenant_diction['tab_ue_ids'] + + if ("price" in new_apprenant_diction.keys()): + del new_apprenant_diction['price'] + + local_status, local_retval = apprenant_mgt.Update_Apprenant(new_apprenant_diction) + if (local_status is False): + return local_status, local_retval + + else: + + new_apprenant_diction = diction + champ_to_delete = [ 'class_internal_url', 'session_id', 'inscription_validation_date', 'apprenant_id', 'status', + 'modefinancement', 'type_apprenant', 'financeur_rattachement_id', + 'quotation_id', 'facture_client_rattachement_id', 'tab_ue_ids', 'price', 'modefinancement_id', 'type_apprenant_id'] + for val in champ_to_delete: + if( val in new_apprenant_diction.keys()): + del new_apprenant_diction[str(val)] + + + + local_status, local_retval = apprenant_mgt.Add_Apprenant(new_apprenant_diction) + if (local_status is False): + return local_status, local_retval + """ + recuperation de l'id du dossier qui vient d'etre créer + """ + apprenant_data = MYSY_GV.dbname['apprenant'].find_one({'email': str(diction['email']), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}, + {'_id': 1}) + + if (apprenant_data is None): + mycommon.myprint(str( + inspect.stack()[0][3]) + " Impossible de récuperer l'identifiant du dossier créé ") + return False, " Impossible de récuperer l'identifiant du dossier créé " + + local_apprenant_id = str(apprenant_data['_id']) + + + local_apprenant_matricule = "" + if( "matricule" in apprenant_data.keys() ): + local_apprenant_matricule = apprenant_data['matricule'] + + local_apprenant_ine = "" + if ("ine" in apprenant_data.keys()): + local_apprenant_ine = apprenant_data['ine'] + + + """ + Apres la creation du dossier on met à jour l'inscription en rajoutant l'apprenant_id + """ + ret_val2 = MYSY_GV.dbname['inscription'].find_one_and_update( + {'_id': ObjectId(str(inserted_id)), 'email': str(diction['email']), + 'partner_owner_recid': str(my_partner['recid'])}, + {"$set": {'apprenant_id': str(local_apprenant_id), + 'matricule':str(local_apprenant_matricule), + 'ine': str(local_apprenant_ine), + 'date_update': str(datetime.now()), + 'update_by': str(my_partner['_id'])}}, + return_document=ReturnDocument.AFTER, + upsert=False, + ) + + + + """ + Update du 08/10/2024 : + Vu que c'est une inscription validée du premier cout, alors on va lancer les opération de validation + """ + + local_diction = {} + local_diction['token'] = str(mytoken) + local_diction['email'] = str(diction['email']) + local_diction['inscription_id'] = str(inserted_id) + + #print(" ### -- local_diction = ", local_diction) + + local_status, local_retval = AcceptAttendeeInscription(local_diction) + if (local_status is False): + return local_status, local_retval + + + """ + # Ajout de l'evenement dans l'historique + seulement dans le cas de la preinscription, car le log de la validation de l'inscription + est porté par la fonction 'acceptinscription..." + """ + if( new_status == "0"): + + # pour la collection 'inscription' + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + #print(" ####### laaaa diction = ", diction) + + history_event_dict = {} + history_event_dict['token'] = mytoken + history_event_dict['related_collection'] = "inscription" + history_event_dict['related_collection_recid'] = str(inserted_id) + history_event_dict['action_date'] = str(now) + + local_session_info = "Id Session : "+str(my_session_data['_id']) + if( "code_session" in my_session_data.keys() ): + local_session_info = local_session_info + ", Code Session : " + my_session_data["code_session"] + + history_event_dict['action_description'] = "Preinscription à "+str(local_session_info) + 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)) + + + # Pour la collection session_formation + history_event_dict = {} + history_event_dict['token'] = mytoken + history_event_dict['related_collection'] = "session_formation" + history_event_dict['related_collection_recid'] = str(my_session_data['_id']) + history_event_dict['action_date'] = str(now) + + local_inscrit_info = " : " + str(inserted_id) + if ("email" in diction.keys()): + local_inscrit_info = local_inscrit_info + ", " + diction["email"] + + if ("nom" in diction.keys()): + local_inscrit_info = local_inscrit_info + ", " + diction["nom"] + + if ("prenom" in diction.keys()): + local_inscrit_info = local_inscrit_info + ", " + diction["prenom"] + + history_event_dict['action_description'] = "Preinscription de " + str(local_inscrit_info) + 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 stagiaire à bien été créé. "+str(Warning_message) + + + 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 le stagiaire" + + +""" +Cette fonction juste pour distinguer une inscription +depuis la marketplace de l'inscription interne depuis back_office""" +def AddStagiairetoClass_from_marketplace(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 = ['nom', 'prenom', 'email', 'telephone', 'modefinancement', 'opco', + 'class_internal_url', 'session_id', 'employeur', 'status', 'price', + 'inscription_validation_date', 'token', 'client_rattachement_id', + 'adresse', 'code_postal', 'ville', 'pays', 'type_apprenant', 'apprenant_id', 'civilite', + 'tuteur1_nom', 'tuteur1_prenom', 'tuteur1_email', 'tuteur1_telephone', 'tuteur1_adresse', + 'tuteur1_cp', 'tuteur1_ville', 'tuteur1_pays', 'tuteur1_include_com', + 'tuteur2_nom', 'tuteur2_prenom', 'tuteur2_email', 'tuteur2_telephone', 'tuteur2_adresse', + 'tuteur2_cp', 'tuteur2_ville', 'tuteur2_pays', 'tuteur2_include_com', 'date_naissance', + 'financeur_rattachement_id', 'tuteur1_civilite', 'tuteur2_civilite', 'quotation_id', + 'facture_client_rattachement_id', 'tab_ue_ids', 'memo', 'comment', 'modefinancement_id', + 'type_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'est pas autorisé") + return False, "Toutes les informations fournies ne sont pas valables" + + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['nom', 'prenom', 'email', 'telephone', + 'class_internal_url', '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, "Impossible de créer le stagiaire. La valeur '" + val + "' n'est pas presente dans la liste des arguments" + + my_partner = None + connected_user_id = "None" + if ("token" in diction.keys() and 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 + + connected_user_id = my_partner['recid'] + + # print(" #### my_partner = ", my_partner) + + + if( "email" in diction.keys() and diction['email']): + diction['email'] = str(diction['email']).strip().lower() + + """ + Verifier que la formation est valide + """ + is_myclass_valide_count = MYSY_GV.dbname['myclass'].count_documents( + {'internal_url': str(diction['class_internal_url']), + 'valide': '1', + 'locked': '0', + }) + + if (is_myclass_valide_count <= 0): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " L'identifiant de la formation est invalide ") + return False, " L'identifiant de la formation est invalide " + + if (is_myclass_valide_count > 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + str( + is_myclass_valide_count) + " formations ont le même internal_url. Or un 'internal_url' correspond à une et une seule formation. internal_url est " + str( + diction['class_internal_url'])) + return False, str(is_myclass_valide_count) + " formations ont le même internal_url." + + is_myclass_valide_data = MYSY_GV.dbname['myclass'].find_one({'internal_url': str(diction['class_internal_url']), + 'valide': '1', + 'locked': '0', + }) + + """ + Important : : 01/08/2024 + Si 'my_partner' est NONE, on va recuperer les données coorespondant au compte admin du partnenaire . + On ajoute aussi le token au dictionnaire + """ + if (my_partner is None): + local_status, my_partner = mycommon.Get_Connected_User_Partner_Data_From_RecID( + str(is_myclass_valide_data['partner_owner_recid'])) + if (local_status is not True): + return local_status, my_partner + + diction['token'] = my_partner['token'] + + if ("modefinancement_id" in diction.keys() and diction['modefinancement_id']): + is_valide_modefinancement_id = MYSY_GV.dbname['financement_mode'].count_documents( + {'_id': ObjectId(str(diction['modefinancement_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_valide_modefinancement_id != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " Le mode de financement est invalide ") + return False, " Le mode de financement est invalide " + + if ("type_apprenant_id" in diction.keys() and diction['type_apprenant_id']): + is_valide_type_apprenant_id = MYSY_GV.dbname['type_apprenant'].count_documents( + {'_id': ObjectId(str(diction['type_apprenant_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_valide_type_apprenant_id != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " Le type d'apprenant est invalide ") + return False, " Le type d'apprenant est invalide " + + + # print(" #### my_partner V2 = ", my_partner) + + mydata = {} + + # Initialisation des champs non envoyés à vide + for val in field_list: + if val not in diction.keys(): + mydata[str(val)] = "" + + # Initialisation des champs non envoyés à vide + for val in field_list: + if val not in diction.keys(): + mydata[str(val)] = "" + + session_id = "" + if ("session_id" in diction.keys()): + if diction['session_id']: + session_id = str(diction['session_id']).strip() + mydata['session_id'] = session_id + + memo = "" + if ("memo" in diction.keys()): + if diction['memo']: + memo = str(diction['memo']).strip() + mydata['memo'] = memo + + comment = "" + if ("comment" in diction.keys()): + if diction['comment']: + comment = str(diction['comment']).strip() + mydata['comment'] = comment + + """ + Verififier l'existance et la valididé de la session + """ + my_session_data_qry = {"_id": ObjectId(str(session_id)), 'valide': '1'} + # print(" AddStagiairetoClass my_session_data_qry = ", my_session_data_qry) + + my_session_data = MYSY_GV.dbname['session_formation'].find_one(my_session_data_qry) + if (my_session_data is None): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de la session est invalide session_id = " + str( + session_id)) + return False, " L'identifiant de la session est invalide" + + mytoken = "" + if ("token" in diction.keys()): + if diction['token']: + mytoken = str(diction['token']).strip() + + apprenant_id = "" + if ("apprenant_id" in diction.keys()): + if diction['apprenant_id']: + apprenant_id = str(diction['apprenant_id']).strip() + mydata['apprenant_id'] = str(apprenant_id) + + date_naissance = "" + if ("date_naissance" in diction.keys()): + if diction['date_naissance']: + date_naissance = str(diction['date_naissance']).strip() + + local_status = mycommon.CheckisDate(date_naissance) + if (local_status is False): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La date de naissance n'est pas au format 'jj/mm/aaaa' ") + return False, " La date de naissance n'est pas au format 'jj/mm/aaaa' " + + mydata['date_naissance'] = str(date_naissance) + + """ + Recuperation des info de la session de formation + """ + + """ + update : 13/07/23 : gestion des prix + + - par defaut si Le champ diction['price'] est rempli, alors on prend cette valeur. + - si cette valeur est vide ou inexistante, on va chercher le prix sur la session. + - Si aucun prix n'est mis sur la session, on va aller cherche le prix sur la formation. + + + """ + + # Verifier que le type d'apprenant est bien valide + type_apprenant = "0" + + if ("type_apprenant" in diction.keys() and diction['type_apprenant']): + type_apprenant = str(mycommon.tryInt(diction['type_apprenant'])) + if (type_apprenant not in MYSY_GV.INSCRIPTION_TYPE_APPRENANT): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le type d'apprenant est invalide ") + return False, " Le type d'apprenant est invalide. Valeurs autorisées" + str( + MYSY_GV.INSCRIPTION_TYPE_APPRENANT) + + new_price = "-1" # 0 ==> par defaut + session_partner_owner_recid = "" + for tmp_val in MYSY_GV.dbname['session_formation'].find({"_id": ObjectId(str(session_id)), 'valide': '1'}): + mydata['date_du'] = str(tmp_val['date_debut'])[0:10] + mydata['date_au'] = str(tmp_val['date_fin'])[0:10] + mydata['partner_owner_recid'] = tmp_val['partner_owner_recid'] + + if ("prix_session" in tmp_val.keys()): + if tmp_val['prix_session']: + new_price = tmp_val['prix_session'] + mydata['price'] = str(new_price) + + if ("partner_owner_recid" in tmp_val.keys()): + session_partner_owner_recid = tmp_val['partner_owner_recid'] + + ## Update du 11/12/2023 : On doit prendre le class_internal_url sur la session et non sur la valeur du ditionnaire d'entré. + ## car realité ces deux doivent etre les meme. + if ("class_internal_url" in tmp_val.keys()): + mydata['class_internal_url'] = str(tmp_val['class_internal_url']).strip() + + civilite = "neutre" + if ("civilite" in diction.keys()): + if diction['civilite']: + civilite = str(diction['civilite']).strip().lower() + + if (str(civilite) not in MYSY_GV.CIVILITE): + civilite = "neutre" + + if (str(civilite).strip() == ""): + civilite = "neutre" + + mydata['civilite'] = civilite + + nom = "" + if ("nom" in diction.keys()): + if diction['nom']: + nom = str(diction['nom']).strip() + mydata['nom'] = nom + + quotation_id = "" + if ("quotation_id" in diction.keys()): + if diction['quotation_id']: + quotation_id = str(diction['quotation_id']).strip() + + is_valide_qotation = MYSY_GV.dbname['partner_order_header'].count_documents( + {'_id': ObjectId(str(diction['quotation_id'])), + 'partner_owner_recid': str(my_partner['recid']), + 'order_header_type': 'devis', + 'valide': '1', + 'locked': '0'}) + + if (is_valide_qotation != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant du devis n'est pas valide ") + return False, " L'identifiant du devis n'est pas valide " + + mydata['quotation_id'] = quotation_id + + prenom = "" + if ("prenom" in diction.keys() and diction['prenom']): + prenom = str(diction['prenom']).strip() + mydata['prenom'] = prenom + + employeur = "" + if ("employeur" in diction.keys() and diction['employeur']): + employeur = str(diction['employeur']).strip() + mydata['employeur'] = employeur + + type_apprenant_id = "" + if ("type_apprenant_id" in diction.keys()): + type_apprenant_id = str(diction['type_apprenant_id']).strip() + mydata['type_apprenant_id'] = type_apprenant_id + + modefinancement_id = "" + if ("modefinancement_id" in diction.keys()): + modefinancement_id = str(diction['modefinancement_id']).strip() + mydata['modefinancement_id'] = modefinancement_id + + + telephone = "" + if ("telephone" in diction.keys() and diction['telephone']): + telephone = str(diction['telephone']).strip() + mydata['telephone'] = telephone + + if ("client_rattachement_id" in diction.keys() and diction['client_rattachement_id']): + mydata['client_rattachement_id'] = diction['client_rattachement_id'] + + ## Verifier l'existance du client de rattachement + local_client_retval_count = MYSY_GV.dbname['partner_client'].count_documents( + {'_id': ObjectId(diction['client_rattachement_id']), + 'valide': '1', 'locked': '0', 'partner_owner_recid': str(my_session_data['partner_owner_recid'])}) + + if (local_client_retval_count != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " - Le client de rattachement est invalide : local_client_retval_count = " + str( + local_client_retval_count)) + return False, " Le client de rattachement est invalide " + + else: + mydata['client_rattachement_id'] = "" + + if ("facture_client_rattachement_id" in diction.keys() and diction['facture_client_rattachement_id']): + mydata['facture_client_rattachement_id'] = diction['facture_client_rattachement_id'] + + ## Verifier l'existance du client de rattachement + local_client_retval_count = MYSY_GV.dbname['partner_client'].count_documents( + {'_id': ObjectId(diction['facture_client_rattachement_id']), + 'valide': '1', 'locked': '0', 'partner_owner_recid': str(my_session_data['partner_owner_recid'])}) + + if (local_client_retval_count != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " - L'entité à facturer est invalide : local_client_retval_count = " + str( + local_client_retval_count)) + return False, " L'entité à facturer est invalide " + + else: + mydata['facture_client_rattachement_id'] = "" + + """ + 11/07/2024 - si j'ai un client_client, mais pas de client facturé, alors on fait : client_facturé = client_client + """ + + if ("facture_client_rattachement_id" in mydata.keys() and len(str(mydata[ + 'facture_client_rattachement_id']).strip()) <= 1 and "client_rattachement_id" in mydata.keys() and + len(str(mydata['client_rattachement_id']).strip()) > 3): + mydata['facture_client_rattachement_id'] = str(mydata['client_rattachement_id']) + + """ + 11/07/2024 - si j'ai un client facture , mais pas de client_client, alors on fait : client_client = client_facturé + """ + if ("client_rattachement_id" in mydata.keys() and len( + str(mydata['client_rattachement_id']).strip()) <= 1 and len( + str(mydata['facture_client_rattachement_id']).strip()) > 3): + mydata['client_rattachement_id'] = str(mydata['facture_client_rattachement_id']) + + if ("financeur_rattachement_id" in diction.keys() and diction['financeur_rattachement_id']): + mydata['financeur_rattachement_id'] = diction['financeur_rattachement_id'] + + ## Verifier l'existance du client de rattachement + local_client_retval_count = MYSY_GV.dbname['partner_client'].count_documents( + {'_id': ObjectId(diction['financeur_rattachement_id']), + 'valide': '1', 'locked': '0', 'partner_owner_recid': str(my_session_data['partner_owner_recid'])}) + + if (local_client_retval_count != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " - Le client de rattachement est invalide : local_client_retval_count = " + str( + local_client_retval_count)) + return False, " Le financeur est invalide " + + else: + mydata['financeur_rattachement_id'] = "" + + if ("tuteur1_civilite" not in diction.keys()): + mydata['tuteur1_civilite'] = "neutre" + + elif (diction['tuteur1_civilite'] not in MYSY_GV.CIVILITE): + # la civilité n'est pas une de celle autorisée, alors je renvoie vide + mydata['tuteur1_civilite'] = "neutre" + + if ("tuteur2_civilite" not in diction.keys()): + mydata['tuteur2_civilite'] = "neutre" + elif (diction['tuteur2_civilite'] not in MYSY_GV.CIVILITE): + # la civilité n'est pas une de celle autorisée, alors je renvoie vide + mydata['tuteur2_civilite'] = "neutre" + + if ("ville" in diction.keys() and diction['ville']): + mydata['ville'] = diction['ville'] + else: + mydata['ville'] = "" + + if ("code_postal" in diction.keys() and diction['code_postal']): + mydata['code_postal'] = diction['code_postal'] + else: + mydata['code_postal'] = "" + + if ("adresse" in diction.keys() and diction['adresse']): + mydata['adresse'] = diction['adresse'] + else: + mydata['adresse'] = "" + + if ("pays" in diction.keys() and diction['pays']): + mydata['pays'] = diction['pays'] + else: + mydata['pays'] = "" + + if ("inscription_validation_date" in diction.keys() and diction['inscription_validation_date']): + mydata['inscription_validation_date'] = str(diction['inscription_validation_date']).strip() + else: + mydata['inscription_validation_date'] = "" + + if ("email" in diction.keys()): + if diction['email']: + mydata['email'] = str(diction['email']).strip().lower() + regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b' + if (not re.fullmatch(regex, str(diction['email']).strip())): + mycommon.myprint( + str(inspect.stack()[0][3]) + " l'adresse email " + str( + diction['email']).strip() + " est invalide") + return False, " l'adresse email -" + str(diction['email']).strip() + "- est invalide" + + if ("modefinancement" in diction.keys() and diction['modefinancement']): + mydata['modefinancement'] = str(diction['modefinancement']).strip() + else: + mydata['modefinancement'] = "" + + if ("opco" in diction.keys() and diction['opco']): + mydata['opco'] = str(diction['opco']).strip() + else: + mydata['opco'] = "" + + mydata['class_id'] = str(is_myclass_valide_data['_id']) + mydata['update_date'] = datetime.now().strftime("%d/%m/%Y %H:%M:%S") + mydata['date_creation'] = datetime.now().strftime("%d/%m/%Y %H:%M:%S") + mydata['update_by'] = str(connected_user_id) + mydata['creation_by'] = str(connected_user_id) + mydata['valide'] = "1" + mydata['locked'] = "0" + + new_status = "2" # 0 ==> par defaut Encours (Inscription en cours de creation, ici, on ne declenche aucun email) + if ("status" in diction.keys()): + if diction['status']: + new_status = str(diction['status']).strip() + if (new_status not in MYSY_GV.INSCRIPTION_STATUS): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le statut d'inscription : " + str( + diction['status']) + " est invalide ") + return False, " Le statut d'inscription : " + str(diction['status']) + " est invalide " + + """ + 03/04/2026 : s'il s'agit d'une formation avec inscription directe, + """ + if( "inscription_direct" in is_myclass_valide_data.keys() and is_myclass_valide_data['inscription_direct'] == "1"): + new_status = "1" + + + mydata['status'] = str(new_status) + mydata['type_apprenant'] = str(type_apprenant) + + # Si un prix est fourni dans le diction, j'ecrase le prise qui est venu de la session + if ("price" in diction.keys() and diction['price']): + new_price = str(diction['price']).strip() + mydata['price'] = str(diction['price']).strip() + + # Verification des prix. si new_price = "-1" cela veut dire qu'il n'a pas de prix dans le diction ni sur la session + # Alors on va chercher le prix (prix public sans reduction) sur la formation + if (new_price == "-1"): + print(" aucun prix trouvé sur la session ") + local_class = MYSY_GV.dbname['myclass'].find_one( + {'internal_url': str(diction['class_internal_url']).strip(), + 'valide': '1', 'locked': '0'}) + + if ('price' in local_class.keys()): + mydata['price'] = str(local_class['price']).strip() + else: + mydata['price'] = '0' + + """ + Update du 22/10/2023 - Gestion des champs spécifiques ajoutés par le partenaire + """ + + # Recuperation des champs spécifiques se trouvant dans le dictionnaire. ils commencent tous par 'my_' + for val in diction.keys(): + if (val.startswith('my_')): + if (MYSY_GV.dbname['base_specific_fields'].count_documents( + {'partner_owner_recid': str(session_partner_owner_recid), + 'related_collection': 'inscription', + 'field_name': str(val), + 'valide': '1', + 'locked': '0'}) != 1): + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ") + return False, " Les informations fournies sont incorrectes" + + mydata[str(val)] = diction[str(val)] + + #print(" #### mydata for inscription = " + str(mydata)) + + coll_inscription = MYSY_GV.dbname['inscription'] + + ## Verification si cette adresse n'est pas deja inscrite à cette session + # print(" myquery pr demo_account = " + str(myquery)) + qry_count = {'email': str(mydata['email']).lower(), 'session_id': str(mydata['session_id']), } + + # print(" ### qry_count = ", qry_count) + tmp = coll_inscription.count_documents({'email': str(mydata['email']).lower(), + 'session_id': str(mydata['session_id']), + }) + + if (tmp > 0): + mycommon.myprint( + str(inspect.stack()[0][3]) + " - L'adresse email " + str( + mydata['email']) + " est deja inscrite à la session du " + " " + str(mydata['session_id']) + " ") + + return False, "Impossible de créer le stagiaire. l'adresse email " + str(mydata['email']) \ + + " est deja inscrite à cette session de formation " + + """ + Un email ne pouvant s'inscrire qu'a une seule session_id; on fait un upsert + """ + # print(" #### mydata before inscr = ", mydata) + ret_val = MYSY_GV.dbname['inscription'].find_one_and_update( + {'session_id': str(mydata['session_id']), 'email': str(mydata['email']).lower(), }, + {"$set": mydata}, + return_document=ReturnDocument.AFTER, + upsert=True, + ) + + if (ret_val is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible d'ajouter la participant ") + return False, " Impossible d'ajouter la participant " + + # ret_val = coll_inscription.insert_one(mydata) + + Warning_message = "" + + inserted_id = ret_val['_id'] + + """ + 26/05/2024 : S'il s'agit d'une formation initiale, alors on lance la fonction 'xxxx' + qui permet de créer les contenus des collection 'inscription_liste_ue' et peut etre 'inscription_liste_ue_type_eval' + + Il s'agit du remplissage par defaut ou tout est actif + + """ + + if ("tab_ue_ids" not in diction.keys() and "formation_initiale" in my_partner.keys() and my_partner[ + 'formation_initiale'] == "1"): + local_diction = {} + local_diction['token'] = diction['token'] + local_diction['inscription_id'] = str(inserted_id) + local_diction['class_id'] = str(is_myclass_valide_data['_id']) + + if ("tab_ue_ids" in diction.keys()): + local_diction['tab_ue_ids'] = diction['tab_ue_ids'] + else: + local_diction['tab_ue_ids'] = "" + + #print(" ### Init_AcceptAttendeeInscription_For_Initial_Formation 11 local_diction = ", local_diction) + + local_inscription_liste_ue_status, local_inscription_liste_ue_retval = Init_AcceptAttendeeInscription_For_Initial_Formation( + local_diction) + + """print(" local_inscription_liste_ue_status, local_inscription_liste_ue_retval = ", + local_inscription_liste_ue_status, local_inscription_liste_ue_retval)""" + + + elif ("tab_ue_ids" in diction.keys() and "formation_initiale" in my_partner.keys() and my_partner[ + 'formation_initiale'] == "1"): + # Ici l'utilisateur a fourni un list d'UE ou il faut inscrire l'apprenant. + # Ceci s'applique lorsque par exemple un apprenant d'inscrit à 1 ou 2 UE sur une formation + local_diction = {} + local_diction['token'] = diction['token'] + local_diction['inscription_id'] = str(inserted_id) + local_diction['class_id'] = str(is_myclass_valide_data['_id']) + if ("tab_ue_ids" in diction.keys()): + local_diction['tab_ue_ids'] = diction['tab_ue_ids'] + else: + local_diction['tab_ue_ids'] = "" + + print(" ### Init_AcceptAttendeeInscription_For_Initial_Formation 22 local_diction = ", local_diction) + + local_inscription_liste_ue_status, local_inscription_liste_ue_retval = Init_AcceptAttendeeInscription_For_Initial_Formation( + local_diction) + + print(" local_inscription_liste_ue_status, local_inscription_liste_ue_retval = ", + local_inscription_liste_ue_status, local_inscription_liste_ue_retval) + + """ + update du 25/08/23 + On ne declenche l'envoie d'un email que l'inscription est soit : + - Preinscrit (hors reservation automatique - validation devis) soit + - inscrit soit + - annulé. + + Donc pas d'email si le statut est (2 => 'encours de creation' + On doit donner la possibilité a l'utilisateur de saisir une inscription avec un statut en cours de creation : 'creation' + """ + + if (inserted_id): + # On verifie que le statut de l'inscription n'est pas (2 : en cours) avant de declencher des envoies d'email + + """ + update 21/04/2024 - + si le champs devis est remplis, alors il s'agit d'une inscription qui vient de la validation automatique d'un devis + pour le moment, dans ce cas figure, vu que les email ne sont pas bon car il s'agit d'un resa, alors on ne declenche + pas d'envoie d'email + """ + if (new_status == "0" and quotation_id == ""): + # Le stagaire a bien ete inseré, on declenche l'envoi des emails + + ## Envoie de l'email de preinscription + mail_data = {} + mail_data['token'] = diction['token'] + mail_data['email'] = diction['email'] + mail_data['class_internal_url'] = diction['class_internal_url'] + mail_data['session_id'] = diction['session_id'] + mail_data['inscription_id'] = ret_val['_id'] + mail_data['inscription_from_marketplace'] = "1" + + if( "modefinancement" in diction.keys()): + mail_data['modefinancement'] = diction['modefinancement'] + else: + mail_data['modefinancement'] = "" + + if ("opco" in diction.keys()): + mail_data['opco'] = diction['opco'] + else: + mail_data['opco'] = "" + + # print(" ### l'inscription est ok, il faut declencher l'envoi des email a "+str(mail_data)) + + """ + 07/01/26 - Vu qu'il s'agit d'une inscription depuis le front (marketplace), on doit obligatoirement envoyer + une notification par email + """ + + local_status, message = SendPre_InscriptionEmail(mail_data) + if (local_status is False): + mycommon.myprint(" WARNING : Impossible d'envoyer le mail de preinscriton à " + + str(inspect.stack()[0][3]) + " - l'adresse email " + str( + mydata['email']) + " pour la session " + str(mydata['session_id']) + " ") + + Warning_message = " WARNING : Impossible d'envoyer le mail de preinscriton à " + str( + inspect.stack()[0][3]) + " - l'adresse email " + str( + mydata['email']) + " pour la session " + str(mydata['session_id']) + " " + + """ + 05/07/2025 : Aller regarder dans la configuration des traitements automatique de la session si des opérations + doivent etre doclenchés à la preinscription + ex : les client qui souhaite envoyer le questionnaire de positionnement à la préinscription + pour rechercher les actions à declencer à la préinscrition, il faut regarder ici : + session_formation['automatic_traitement'][num_line]['action_target_date'] = 'preinscription' + (my_session_data) + """ + if ("automatic_traitement" in my_session_data and len(my_session_data['automatic_traitement']) > 0): + for local_automatic_traitement in my_session_data['automatic_traitement']: + if ("action_target_date" in local_automatic_traitement.keys() and local_automatic_traitement[ + 'action_target_date'] == 'preinscription' + and 'courrier_template_type_document_ref_interne' in local_automatic_traitement.keys() + and local_automatic_traitement['actif'] == '1' and local_automatic_traitement[ + 'valide'] == '1' + and local_automatic_traitement['statut'] == '0' and local_automatic_traitement[ + 'locked'] == '0' + ): + # Il y a une action a declencher + if (local_automatic_traitement[ + "courrier_template_type_document_ref_interne"] == "QUESTION_POSITIONNEMENT"): + + # Recuperer le formulaire de positionnement par defaut + formulaire_q_pos_data = MYSY_GV.dbname['formulaire'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked': '0', + 'type': 'pos', + 'default': '1', + }) + if (formulaire_q_pos_data): + Init_Survey_data = {} + Init_Survey_data['token'] = diction['token'] + Init_Survey_data['session_id'] = str(my_session_data['_id']) + Init_Survey_data['formulaire_id'] = str(formulaire_q_pos_data['_id']) + Init_Survey_data['survey_type'] = "pos" + Init_Survey_data['tab_inscrit_ids'] = str(inserted_id) + Init_Survey_data['sending_date'] = "" + + qpo_status, qpo_retval = survey_mgt.Init_Survey_Tab_For_All_Session_Inscrit( + Init_Survey_data) + + if (qpo_status is True): + # il faut envoyer le questionnaire + survey_data = MYSY_GV.dbname['survey'].find_one( + {'inscription_id': str(inserted_id), + 'session_id': str(my_session_data['_id']), + 'survey_type': "pos", + 'statut': '0'}) + + if (survey_data): + Init_Survey_send_data = {} + Init_Survey_send_data['token'] = diction['token'] + Init_Survey_send_data['tab_ids'] = str(survey_data['_id']) + + qpo_send_status, qpo_send_retval = survey_mgt.Send_Survey_TabIds( + Init_Survey_send_data) + + if (qpo_send_status is False): + mycommon.myprint( + " WARNING : Impossible d'envoyer le questionnaire de positionnement pour l'inscription" + + str(inserted_id) + ", Raison " + qpo_send_retval + " ") + + + + else: + mycommon.myprint( + str(inspect.stack()[0][3]) + " - ret_val.inserted_id is null ") + return False, "Impossible de créer le stagiaire" + + """ + 29/12/2023 : La creation s'est bien passée, si c'est une inscription definitive du premier cout, + c'est a dire que str(new_status) = 1 => Inscription (validée) alors on fait la creation ou une mise à jour + du dossier apprenant en meme tps + """ + if (new_status == "1"): + """ + 28/03/26 + Pour les formation en inscription directe : myclass.inscription_direct == '1' + Il faudra envoyer l'email de notification d'inscription d'une personne + courrier_template.ref_interne = 'PARTNER_PRE_INSCRIPTION_NOTIF' + au gestionnaire de la formation + """ + + local_inscription_direct = "" + if( "inscription_direct" in is_myclass_valide_data.keys()): + local_inscription_direct = is_myclass_valide_data['inscription_direct'] + + if( local_inscription_direct == "1"): + """ + field_list_obligatoire = ['nom', 'prenom', 'email', 'date_du', 'date_au', 'title', + 'partner_mail', 'telephone', 'token', 'partner_owner_recid', + 'session_id', 'formateur_email', ] + """ + + notif_mail_dic = {} + + notif_mail_dic['session_id'] = diction['session_id'] + notif_mail_dic['token'] = my_partner['token'] + notif_mail_dic['partner_owner_recid'] = my_partner['recid'] + notif_mail_dic['nom'] = diction['nom'] + notif_mail_dic['prenom'] = diction['prenom'] + notif_mail_dic['email'] = diction['email'] + notif_mail_dic['telephone'] = diction['telephone'] + notif_mail_dic['partner_mail'] = my_partner['email'] + + local_distanciel = "0" + local_presentiel = "0" + if( "mode_animation" in my_session_data.keys()): + if( my_session_data['mode_animation'] == "0"): + local_presentiel = "1" + local_distanciel = "0" + elif ( my_session_data['mode_animation'] == "1"): + local_distanciel = "1" + local_presentiel = "0" + + notif_mail_dic['presentiel'] = local_presentiel + notif_mail_dic['distantiel'] = local_distanciel + + + if( my_session_data and 'date_debut' in my_session_data.keys()): + notif_mail_dic['date_du'] = my_session_data['date_debut'] + else: + notif_mail_dic['date_du'] = '' + + if (my_session_data and 'date_fin' in my_session_data.keys()): + notif_mail_dic['date_au'] = my_session_data['date_fin'] + else: + notif_mail_dic['date_au'] = '' + + if (is_myclass_valide_data and 'title' in is_myclass_valide_data.keys()): + notif_mail_dic['title'] = is_myclass_valide_data['title'] + else: + notif_mail_dic['title'] = '' + + formateur = "" + formateur_email = "" + if ("formateur_id" in my_session_data.keys()): + if my_session_data['formateur_id']: + formateur_data = MYSY_GV.dbname['ressource_humaine'].find_one( + {'_id': ObjectId(str(my_session_data['formateur_id'])), + 'valide': '1', + 'locked': '0', + 'partner_recid': my_partner['recid']}) + + if (formateur_data and "nom" in formateur_data.keys() and "prenom" in formateur_data.keys()): + formateur = str(formateur_data['nom']) + " " + str(formateur_data['prenom']) + + if (formateur_data and "email" in formateur_data.keys()): + formateur_email = str(formateur_data['email']) + + notif_mail_dic['formateur_email'] = formateur_email + + if( "modefinancement" in diction.keys()): + notif_mail_dic['modefinancement'] = diction['modefinancement'] + else: + notif_mail_dic['modefinancement'] = "" + + if ("opco" in diction.keys()): + notif_mail_dic['opco'] = diction['opco'] + else: + notif_mail_dic['opco'] = "" + + # Envoi de l'email de notification au formateur + local_status, local_message = email_session.Notification_partner_Pre_incription_mail(notif_mail_dic) + + + + local_apprenant_id = "" + is_apprenant_existe_count = MYSY_GV.dbname['apprenant'].count_documents( + {'email': str(diction['email']), + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked': '0'}) + + if (is_apprenant_existe_count > 0): + # Il faut mettre à jour un dossier apprenant + is_apprenant_existe = MYSY_GV.dbname['apprenant'].find_one( + {'email': str(diction['email']), + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked': '0'}, {'_id': 1}) + + new_apprenant_diction = diction + champ_to_delete = ['class_internal_url', 'session_id', 'inscription_validation_date', 'apprenant_id', + 'status', 'modefinancement', 'type_apprenant', 'financeur_rattachement_id', + 'quotation_id', 'facture_client_rattachement_id', 'price'] + + for val in champ_to_delete: + if (val in new_apprenant_diction.keys()): + del new_apprenant_diction[str(val)] + + new_apprenant_diction['_id'] = str(is_apprenant_existe['_id']) + + local_apprenant_id = str(is_apprenant_existe['_id']) + if ("tab_ue_ids" in new_apprenant_diction.keys()): + del new_apprenant_diction['tab_ue_ids'] + + if ("price" in new_apprenant_diction.keys()): + del new_apprenant_diction['price'] + + local_status, local_retval = apprenant_mgt.Update_Apprenant(new_apprenant_diction) + if (local_status is False): + return local_status, local_retval + + else: + + new_apprenant_diction = diction + champ_to_delete = ['class_internal_url', 'session_id', 'inscription_validation_date', 'apprenant_id', + 'status', + 'modefinancement', 'type_apprenant', 'financeur_rattachement_id', + 'quotation_id', 'facture_client_rattachement_id', 'tab_ue_ids', 'price', 'modefinancement_id', 'type_apprenant_id'] + for val in champ_to_delete: + if (val in new_apprenant_diction.keys()): + del new_apprenant_diction[str(val)] + + local_status, local_retval = apprenant_mgt.Add_Apprenant(new_apprenant_diction) + if (local_status is False): + return local_status, local_retval + """ + recuperation de l'id du dossier qui vient d'etre créer + """ + apprenant_data = MYSY_GV.dbname['apprenant'].find_one({'email': str(diction['email']), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}, + {'_id': 1}) + + if (apprenant_data is None): + mycommon.myprint(str( + inspect.stack()[0][3]) + " Impossible de récuperer l'identifiant du dossier créé ") + return False, " Impossible de récuperer l'identifiant du dossier créé " + + local_apprenant_id = str(apprenant_data['_id']) + + """ + Apres la creation du dossier on met à jour l'inscription en rajoutant l'apprenant_id + """ + ret_val2 = MYSY_GV.dbname['inscription'].find_one_and_update( + {'_id': ObjectId(str(inserted_id)), 'email': str(diction['email']), + 'partner_owner_recid': str(my_partner['recid'])}, + {"$set": {'apprenant_id': str(local_apprenant_id), 'date_update': str(datetime.now()), + 'update_by': str(my_partner['_id'])}}, + return_document=ReturnDocument.AFTER, + upsert=False, + ) + + """ + Update du 08/10/2024 : + Vu que c'est une inscription validée du premier cout, alors on va lancer les opération de validation + """ + + local_diction = {} + local_diction['token'] = str(mytoken) + local_diction['email'] = str(diction['email']) + local_diction['inscription_id'] = str(inserted_id) + + #print(" ### -- eeeeeeeeeeeeeeeeeeeee local_diction = ", local_diction) + + local_status, local_retval = AcceptAttendeeInscription(local_diction) + if (local_status is False): + return local_status, local_retval + + """ + # Ajout de l'evenement dans l'historique + seulement dans le cas de la preinscription, car le log de la validation de l'inscription + est porté par la fonction 'acceptinscription..." + """ + if (new_status == "0"): + + # pour la collection 'inscription' + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + # print(" ####### laaaa diction = ", diction) + + history_event_dict = {} + history_event_dict['token'] = mytoken + history_event_dict['related_collection'] = "inscription" + history_event_dict['related_collection_recid'] = str(inserted_id) + history_event_dict['action_date'] = str(now) + + local_session_info = "Id Session : " + str(my_session_data['_id']) + if ("code_session" in my_session_data.keys()): + local_session_info = local_session_info + ", Code Session : " + my_session_data["code_session"] + + history_event_dict['action_description'] = "Preinscription à " + str(local_session_info) + 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)) + + # Pour la collection session_formation + history_event_dict = {} + history_event_dict['token'] = mytoken + history_event_dict['related_collection'] = "session_formation" + history_event_dict['related_collection_recid'] = str(my_session_data['_id']) + history_event_dict['action_date'] = str(now) + + local_inscrit_info = " : " + str(inserted_id) + if ("email" in diction.keys()): + local_inscrit_info = local_inscrit_info + ", " + diction["email"] + + if ("nom" in diction.keys()): + local_inscrit_info = local_inscrit_info + ", " + diction["nom"] + + if ("prenom" in diction.keys()): + local_inscrit_info = local_inscrit_info + ", " + diction["prenom"] + + history_event_dict['action_description'] = "Preinscription de " + str(local_inscrit_info) + 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 stagiaire à bien été créé. " + str(Warning_message) + + + 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 le stagiaire" + + +""" +Mettre à jour les infomration d'un stgiaire + +Important : : on NE mets PAS à jour la session, juste les info du stagiaire + + # status : 0 ==> Preinscription + # status : 1 ==> Inscription validée + # status : -1 ==> Inscription annulée + # status : 2 ==> Inscription encours de creation + +Important : Inscription sur le LMS : +Si la session de formation possede un code de formation lms 'lms_class_code' + +Alors cela veut dire que c'est une formation qui est gérée avec le LMS de MYSY. +Donc l'inscription va generer : + 1 - La creation du compte LMS participant + 2 - L'inscription de l'utilisateur à la formation. + +""" +def UpdateStagiairetoClass(diction): + try: + + return_message = "" + field_list = ['token', 'email', 'nom', 'prenom', 'telephone', 'modefinancement', 'opco', + 'status', 'class_internal_url', 'session_id', 'price', 'employeur', 'comment', + '_id', 'client_rattachement_id', 'adresse', 'code_postal', 'ville', 'pays', + 'tuteur1_nom', 'tuteur1_prenom', 'tuteur1_email', 'tuteur1_telephone', 'tuteur1_adresse', + 'tuteur1_cp', 'tuteur1_ville', 'tuteur1_pays', 'tuteur1_include_com', + 'tuteur2_nom', 'tuteur2_prenom', 'tuteur2_email', 'tuteur2_telephone', 'tuteur2_adresse', + 'tuteur2_cp', 'tuteur2_ville', 'tuteur2_pays', 'tuteur2_include_com', 'type_apprenant', 'civilite', + 'date_naissance', 'financeur_rattachement_id', 'facture_client_rattachement_id', 'memo', + 'is_handicap', 'is_droit_image', 'is_rgpd', 'nationalite', 'situation_famille', 'naissance_lieu', + 'naissance_departement', + 'naissance_pays', 'num_secu', 'identite_type', 'piece_identite_num', 'type_mobilite', + 'telephone_bis', 'frequence_facturation', 'update_dossier_apprenant', 'ine', 'matricule', + 'modefinancement_id', 'type_apprenant_id', 'nom_fille', 'num_cvec', 'handicap_detail', + 'employeur_id', 'categorie_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é, Creation partenaire annulée") + return False, "Impossible de mettre à jour stagiaire. Toutes les informations fournies ne sont pas valables" + + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', 'email', 'class_internal_url', 'session_id', '_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, "Impossible de mettre à jour stagiaire, Toutes les informations necessaires n'ont pas été fournies" + + query_key = {} + mytoken = "" + if ("token" in diction.keys()): + if diction['token']: + mytoken = str(diction['token']).strip() + #query_key['token'] = diction['token'] + + if( "email" in diction.keys() and diction['email']): + diction['email'] = str(diction['email']).strip().lower() + + # Verifier la validité du token + retval = mycommon.check_partner_token_validity("", mytoken) + if retval is False: + return "Err_Connexion", " La session de connexion n'est pas valide" + + mydata = {} + user_nom = "" + + local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data({'token':mytoken}) + if (local_status is not True): + return local_status, my_partner + + partner_recid = my_partner['recid'] + + if ("modefinancement_id" in diction.keys() and diction['modefinancement_id']): + is_valide_modefinancement_id = MYSY_GV.dbname['financement_mode'].count_documents( + {'_id': ObjectId(str(diction['modefinancement_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_valide_modefinancement_id != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " Le mode de financement est invalide ") + return False, " Le mode de financement est invalide " + + if ("type_apprenant_id" in diction.keys() and diction['type_apprenant_id']): + is_valide_type_apprenant_id = MYSY_GV.dbname['type_apprenant'].count_documents( + {'_id': ObjectId(str(diction['type_apprenant_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_valide_type_apprenant_id != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " Le type d'apprenant est invalide ") + return False, " Le type d'apprenant est invalide " + + + if ("employeur_id" in diction.keys() and diction['employeur_id']): + is_valide_employeur_id = MYSY_GV.dbname['partner_client'].count_documents( + {'_id': ObjectId(str(diction['employeur_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_valide_employeur_id != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " L'employeur est invalide ") + return False, " L'employeur est invalide " + + if ("categorie_id" in diction.keys() and diction['categorie_id']): + is_valide_categorie_id = MYSY_GV.dbname['categorie_apprenant'].count_documents( + {'_id': ObjectId(str(diction['categorie_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_valide_categorie_id != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " La catégorie de l'apprenant est invalide ") + return False, " La catégorie de l'apprenant est invalide " + + + """ + Verifier qu'il n'y pas un étudiant avec le meme INE (Identifiant National Étudiant) + """ + if ("ine" in diction.keys() and diction['ine']): + is_exist_ine_count = MYSY_GV.dbname['inscription'].count_documents( + {'_id': {'$ne': ObjectId(str(diction['_id']))}, + 'ine': str(diction['ine']), + 'session_id': str(diction[ + 'session_id']), + 'partner_owner_recid': str( + my_partner['recid']) + }) + + if (is_exist_ine_count > 0): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " Il y a déjà un candidat avec le même numéro Identifiant National Étudiant (INE) ") + return False, " Il y a déjà un candidat avec le même numéro Identifiant National Étudiant (INE) " + + myemail = "" + if ("email" in diction.keys()): + if diction['email']: + myemail = str(diction['email']).strip().lower() + if( mycommon.isEmailValide(myemail)) : + mydata['email'] = str(diction['email']).strip().lower() + else: + mycommon.myprint(str(inspect.stack()[0][3]) + " - l'adresse email "+str(diction['email'])+" n'est pas valide") + return False, " L'adresse email "+str(diction['email'])+" n'est pas valide " + + + """ + Verifier que cet email n'est pas déjà utilisé par un autre inscrit de la meme session + """ + print(" quryy nb_mail_inscrit_session = ", {'email':str(myemail), + 'session_id':str(diction['session_id']), + '_id':{'$ne':ObjectId(diction['_id'])}, + 'partner_owner_recid':my_partner['recid']}) + + nb_mail_inscrit_session = MYSY_GV.dbname['inscription'].count_documents({'email':str(myemail), + 'session_id':str(diction['session_id']), + '_id':{'$ne':ObjectId(diction['_id'])}, + 'partner_owner_recid':my_partner['recid']}) + + if( nb_mail_inscrit_session > 0 ): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Un utilisateur avec cette adresse e-mail est déjà inscrit à cette formation.") + return False, " Un utilisateur avec cette adresse e-mail est déjà inscrit à cette formation. " + + else: + mycommon.myprint( + str(inspect.stack()[0][3]) + " - l'adresse email " + str(diction['email']) + " n'est pas valide") + return False, " L'adresse email " + str(diction['email']) + " n'est pas valide " + + + object_id = "" + if ("_id" in diction.keys()): + if diction['_id']: + object_id = str(diction['_id']).strip() + query_key['_id'] = ObjectId (str(diction['_id']).strip()) + else: + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de l'inscrit est invalide ") + return False, " L'identifiant de l'inscrit est invalide " + + myinternal_url = "" + if ("class_internal_url" in diction.keys()): + if diction['class_internal_url']: + myinternal_url = str(diction['class_internal_url']).strip() + #query_key['class_internal_url'] = str(diction['class_internal_url']).strip() + + mysession_id = "" + if ("session_id" in diction.keys()): + if diction['session_id']: + mysession_id = str(diction['session_id']).strip() + #query_key['session_id'] = str(diction['session_id']).strip() + + + """" + Important : : update du 18/08/2023 : On va autoriser le changement le session de formation. + en effet il peut arriver qu'on souhaite deplacer la formation d'une personne à une autre session. + """ + if ("session_id" in diction.keys()): + if diction['session_id']: + mysession_id = str(diction['session_id']).strip() + mydata['session_id'] = str(diction['session_id']).strip() + + if ("nom" in diction.keys()): + mydata['nom'] = str(diction['nom']).strip() + user_nom = str(diction['nom']).strip() + + if ("ine" in diction.keys()): + mydata['ine'] = str(diction['ine']).strip() + + + if ("matricule" in diction.keys()): + mydata['matricule'] = str(diction['matricule']).strip() + + if ("nom_fille" in diction.keys()): + mydata['nom_fille'] = str(diction['nom_fille']).strip() + + if ("num_cvec" in diction.keys()): + mydata['num_cvec'] = str(diction['num_cvec']).strip() + + if ("handicap_detail" in diction.keys()): + mydata['handicap_detail'] = str(diction['handicap_detail']).strip() + + + if ("type_apprenant_id" in diction.keys()): + mydata['type_apprenant_id'] = str(diction['type_apprenant_id']) + + if ("categorie_id" in diction.keys()): + mydata['categorie_id'] = str(diction['categorie_id']) + + + if ("employeur_id" in diction.keys()): + mydata['employeur_id'] = str(diction['employeur_id']) + + + if ("modefinancement_id" in diction.keys()): + mydata['modefinancement_id'] = str(diction['modefinancement_id']).strip() + + + + if ("civilite" in diction.keys()): + mydata['civilite'] = str(diction['civilite']).strip().lower() + + if (str(mydata['civilite']) not in MYSY_GV.CIVILITE): + mydata['civilite'] = "neutre" + + if( str(mydata['civilite']).strip() == ""): + mydata['civilite'] = "neutre" + + if ("date_naissance" in diction.keys()): + if diction['date_naissance']: + date_naissance = str(diction['date_naissance']).strip() + + local_status = mycommon.CheckisDate(date_naissance) + if (local_status is False): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La date de naissance n'est pas au format 'jj/mm/aaaa' ") + return False, " La date de naissance n'est pas au format 'jj/mm/aaaa' " + + mydata['date_naissance'] = str(date_naissance) + + frequence_facturation = "" + if ("frequence_facturation" in diction.keys() and diction[ + 'frequence_facturation'] not in MYSY_GV.INSCRIT_FREQUENCE_FACTURE): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La fréquence de facturation doit être " + str(MYSY_GV.INSCRIT_FREQUENCE_FACTURE)) + return False, " La fréquence de facturation doit être " + str(MYSY_GV.INSCRIT_FREQUENCE_FACTURE) + + elif( "frequence_facturation" in diction.keys() and diction[ + 'frequence_facturation'] in MYSY_GV.INSCRIT_FREQUENCE_FACTURE ): + + frequence_facturation = diction['frequence_facturation'] + mydata['frequence_facturation'] = frequence_facturation + + if ("price" in diction.keys()): + mydata['price'] = str(diction['price']).strip() + + if ("employeur" in diction.keys()): + mydata['employeur'] = str(diction['employeur']).strip() + + if ("tuteur1_nom" in diction.keys()): + mydata['tuteur1_nom'] = str(diction['tuteur1_nom']).strip() + + if ("tuteur1_email" in diction.keys()): + mydata['tuteur1_email'] = str(diction['tuteur1_email']).strip() + + if ("tuteur1_email" in diction.keys()): + mydata['tuteur1_email'] = str(diction['tuteur1_email']).strip() + + if ("tuteur1_telephone" in diction.keys()): + mydata['tuteur1_telephone'] = str(diction['tuteur1_telephone']).strip() + + if ("tuteur1_adresse" in diction.keys()): + mydata['tuteur1_adresse'] = str(diction['tuteur1_adresse']).strip() + + if ("tuteur1_cp" in diction.keys()): + mydata['tuteur1_cp'] = str(diction['tuteur1_cp']).strip() + + if ("tuteur1_ville" in diction.keys()): + mydata['tuteur1_ville'] = str(diction['tuteur1_ville']).strip() + + if ("tuteur1_pays" in diction.keys()): + mydata['tuteur1_pays'] = str(diction['tuteur1_pays']).strip() + + if ("tuteur1_include_com" in diction.keys()): + mydata['tuteur1_include_com'] = str(diction['tuteur1_include_com']).strip() + + if ("tuteur2_nom" in diction.keys()): + mydata['tuteur2_nom'] = str(diction['tuteur2_nom']).strip() + + if("tuteur2_email" in diction.keys()): + mydata['tuteur2_email'] = str(diction['tuteur2_email']).strip() + + if ("tuteur2_email" in diction.keys()): + mydata['tuteur2_email'] = str(diction['tuteur2_email']).strip() + + if ("tuteur2_telephone" in diction.keys()): + mydata['tuteur2_telephone'] = str(diction['tuteur2_telephone']).strip() + + if ("tuteur2_adresse" in diction.keys()): + mydata['tuteur2_adresse'] = str(diction['tuteur2_adresse']).strip() + + if ("tuteur2_cp" in diction.keys()): + mydata['tuteur2_cp'] = str(diction['tuteur2_cp']).strip() + + if ("tuteur2_ville" in diction.keys()): + mydata['tuteur2_ville'] = str(diction['tuteur2_ville']).strip() + + if ("tuteur2_pays" in diction.keys()): + mydata['tuteur2_pays'] = str(diction['tuteur2_pays']).strip() + + if ("tuteur2_include_com" in diction.keys()): + mydata['tuteur2_include_com'] = str(diction['tuteur2_include_com']).strip() + + # Verifier que le type d'apprenant est bien valide + if ("type_apprenant" in diction.keys() and diction['type_apprenant']): + type_apprenant = str(mycommon.tryInt(diction['type_apprenant'])) + if (type_apprenant not in MYSY_GV.INSCRIPTION_TYPE_APPRENANT): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le type d'apprenant est invalide ") + return False, " Le type d'apprenant est invalide. Valeurs autorisées" + str( + MYSY_GV.INSCRIPTION_TYPE_APPRENANT) + mydata['type_apprenant'] = str(type_apprenant) + + + + user_prenom = "" + if ("prenom" in diction.keys()): + mydata['prenom'] = str(diction['prenom']).strip() + user_prenom = str(diction['prenom']).strip() + + if ("telephone" in diction.keys()): + mydata['telephone'] = str(diction['telephone']).strip() + + if ("modefinancement" in diction.keys()): + mydata['modefinancement'] = str(diction['modefinancement']).strip() + + if ("opco" in diction.keys()): + mydata['opco'] = str(diction['opco']).strip() + + if ("price" in diction.keys()): + mydata['price'] = str(diction['price']).strip() + + if ("adresse" in diction.keys()): + mydata['adresse'] = str(diction['adresse']).strip() + + if ("code_postal" in diction.keys()): + mydata['code_postal'] = str(diction['code_postal']).strip() + + if ("ville" in diction.keys()): + mydata['ville'] = str(diction['ville']).strip() + + if ("pays" in diction.keys()): + mydata['pays'] = str(diction['pays']).strip() + + new_status = "" + old_status = "" + if ("status" in diction.keys()): + if diction['status']: + mydata['status'] = str(diction['status']).strip() + new_status = str(diction['status']).strip() + + # On stock le old_status avec la valeur de new_status. + # Cela permettra de comparer apres pour voir s'il y a un changement de statut. + old_status = str(diction['status']).strip() + + if (new_status not in MYSY_GV.INSCRIPTION_STATUS): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le statut d'inscription : " + str( + diction['status']) + " est invalide ") + return False, " Le statut d'inscription : " + str(diction['status']) + " est invalide " + + + if ("comment" in diction.keys()): + mydata['comment'] = str(diction['comment']).strip() + + if ("memo" in diction.keys()): + mydata['memo'] = str(diction['memo']).strip() + + + if ("client_rattachement_id" in diction.keys()): + mydata['client_rattachement_id'] = str(diction['client_rattachement_id']).strip() + + + + if(len(str(diction['client_rattachement_id']).strip()) > 0 ): + ## Verifier l'existance du client de rattachement + local_client_retval_count = MYSY_GV.dbname['partner_client'].count_documents({'_id': ObjectId(diction['client_rattachement_id']), + 'valide': '1', 'locked': '0', 'partner_owner_recid': str(partner_recid)}) + + if (local_client_retval_count != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " - Le client de rattachement est invalide : local_client_retval_count = "+str(local_client_retval_count)) + return False, " Le client de rattachement est invalide " + + mydata['entreprise'] = "1" + else: + # 06/01/2025 - Mettre le champs "entreprise" à "0" sir 'client_rattachement_id' est vide + mydata['entreprise'] = "" + + if ("facture_client_rattachement_id" in diction.keys()): + mydata['facture_client_rattachement_id'] = str(diction['facture_client_rattachement_id']).strip() + if(len(str(diction['facture_client_rattachement_id']).strip()) > 0 ): + ## Verifier l'existance du client de rattachement + local_client_retval_count = MYSY_GV.dbname['partner_client'].count_documents({'_id': ObjectId(diction['facture_client_rattachement_id']), + 'valide': '1', 'locked': '0', 'partner_owner_recid': str(partner_recid)}) + + if (local_client_retval_count != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'entité à facturer est invalide : local_client_retval_count = "+str(local_client_retval_count)) + return False, "L'entité à facturer est invalide " + + + + if ("financeur_rattachement_id" in diction.keys()): + mydata['financeur_rattachement_id'] = str(diction['financeur_rattachement_id']).strip() + if (len(str(diction['financeur_rattachement_id']).strip()) > 0): + ## Verifier l'existance du client de rattachement + local_client_retval_count = MYSY_GV.dbname['partner_client'].count_documents( + {'_id': ObjectId(diction['financeur_rattachement_id']), + 'valide': '1', 'locked': '0', 'partner_owner_recid': str(partner_recid)}) + + if (local_client_retval_count != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " - Le financeur de rattachement est invalide : local_client_retval_count = " + str( + local_client_retval_count)) + return False, " Le financeur de rattachement est invalide " + + + + + if ("is_handicap" in diction.keys() and str(diction['is_handicap']) not in ['0', '1', '']): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'is_handicap' est invalide ") + return False, " Le champ 'is_handicap' est invalide " + + if ("is_handicap" in diction.keys()): + mydata['is_handicap'] = str(diction['is_handicap']).strip() + + + + + if ("is_droit_image" in diction.keys() and str(diction['is_droit_image']) not in ['0', '1', '']): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'is_droit_image' est invalide ") + return False, " Le champ 'is_droit_image' est invalide " + + + if ("is_droit_image" in diction.keys()): + mydata['is_droit_image'] = str(diction['is_droit_image']).strip() + + + if ("situation_famille" in diction.keys() and str(diction['situation_famille']) not in MYSY_GV.SITUATION_FAMILLE): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'situation_famille' est invalide ") + return False, " Le champ 'situation_famille' est invalide " + + + if ("situation_famille" in diction.keys()): + mydata['situation_famille'] = str(diction['situation_famille']).strip() + + + if ("identite_type" in diction.keys() and str(diction['identite_type']) not in MYSY_GV.PICE_IDENTITE_TYPE): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'identite_type' est invalide ") + return False, " Le champ 'identite_type' est invalide " + + + if ("identite_type" in diction.keys()): + mydata['identite_type'] = str(diction['identite_type']).strip() + + + if ("type_mobilite" in diction.keys() and str(diction['type_mobilite']) not in MYSY_GV.APPRENANT_MOBILITE): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'type_mobilite' est invalide ") + return False, " Le champ 'type_mobilite' est invalide " + + + if ("type_mobilite" in diction.keys()): + mydata['type_mobilite'] = str(diction['type_mobilite']).strip() + + + if ("nationalite" in diction.keys()): + mydata['nationalite'] = str(diction['nationalite']).strip() + + + if ("naissance_lieu" in diction.keys()): + mydata['naissance_lieu'] = str(diction['naissance_lieu']).strip() + + naissance_departement = "" + if ("naissance_departement" in diction.keys()): + mydata['naissance_departement'] = str(diction['naissance_departement']).strip() + + + if ("naissance_pays" in diction.keys()): + mydata['naissance_pays'] = str(diction['naissance_pays']).strip() + + + if ("num_secu" in diction.keys()): + mydata['num_secu'] = str(diction['num_secu']).strip() + + + if ("piece_identite_num" in diction.keys()): + mydata['piece_identite_num'] = str(diction['piece_identite_num']).strip() + + + if ("telephone_bis" in diction.keys()): + mydata['telephone_bis'] = str(diction['telephone_bis']).strip() + + + + if ("is_rgpd" in diction.keys() and str(diction['is_rgpd']) not in ['0', '1', '']): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'is_rgpd' est invalide ") + return False, " Le champ 'is_rgpd' est invalide " + + if ("is_rgpd" in diction.keys()): + mydata['is_rgpd'] = str(diction['is_rgpd']).strip() + + + + + # ici recup des infos de la session + local_query = {'_id': ObjectId(str(mysession_id)), 'valide': '1'} + print("### local_query = " + str(local_query)) + + local_tmp_session_count = MYSY_GV.dbname['session_formation'].count_documents(local_query) + if (local_tmp_session_count <= 0): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Aucune session de formation pour " + str(local_query)) + return False, "Impossible de mettre à jour le stagiaire, Cette session de formation n'est pas valide " + + if (local_tmp_session_count > 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " - Plusieurs sessions existent pour ce code sessions " + str( + local_query)) + return False, "Impossible de mettre à jour le stagiaire, Cette session de formation n'est pas valide (2) " + + local_tmp_session_data = MYSY_GV.dbname['session_formation'].find_one(local_query) + + """ + update de 20/08/23 : + Vu qu'on autorise maintenant le changement de session, alors pour parer à une eventuellement changement de sessio + pour une affectation a une session appartenant à une autre formation, + on va ecraser le 'class_internal_url' de la collection 'inscription' avec celui de la collection 'session_formation' + + """ + mydata['class_internal_url'] = str(local_tmp_session_data['class_internal_url']).strip() + + # Recuperation des champs spécifiques se trouvant dans le dictionnaire. ils commencent tous par 'my_' + for val in diction.keys(): + if (val.startswith('my_')): + if (MYSY_GV.dbname['base_specific_fields'].count_documents( + {'partner_owner_recid': str(partner_recid), + 'related_collection': 'inscription', + 'field_name': str(val), + 'valide': '1', + 'locked': '0'}) != 1): + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ") + return False, " Les informations fournies sont incorrectes" + + mydata[str(val)] = diction[str(val)] + + """ + Pour gerer la date de validation, différemment d'une simple mise à jour, + on récupérer le status actuellement en base, on verifie si le nouveau status != de status en base. + + Si il y a changement de status alors c'est une date de changement de status. + """ + coll_inscription = MYSY_GV.dbname['inscription'] + + #print(" #### query_key = ", query_key) + local_retval = coll_inscription.find_one(query_key) + + message_for_historic = "" + + if( local_retval is not None ): + if( "status" in local_retval.keys()): + + # On recupere le statut stock en base dans 'old_status' + old_status = local_retval['status'] + inscription_line_id = local_retval['_id'] + + + if( new_status != old_status ): + # Il y a eu un changement de status + if( new_status == "1"): + mydata['inscription_validation_date'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + message_for_historic = "Validation Inscription" + + if (new_status == "-1"): + mydata['inscription_refuse_date'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + message_for_historic = "Refus Inscription" + + if (new_status == "2"): + mydata['inscription_preinscription_date'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + message_for_historic = "Préinscription " + + mydata['update_date'] = str(datetime.now()) + mydata['update_by'] = str(my_partner['_id']) + + ret_val2 = coll_inscription.find_one_and_update(query_key, + {"$set": mydata}, + return_document=ReturnDocument.AFTER + ) + + if (ret_val2 and ret_val2['_id']): + + """ + - Si le status == 1; alors il s'agit d'une validation d'une inscription. + - Si le status == -1; alors il s'agit d'une refus d'une inscription. + - Si le status == 0; alors il s'agit d'une preinscription. + + Du coup, il faut envoyer le mail de confirmation de l'inscription: + 1 - recuperation des infos de la session + 1 BIS - recuperation du title + 2 - Envoie de l'email + """ + email_data = {} + email_data['nom'] = user_nom + email_data['prenom'] = user_prenom + email_data['email'] = myemail + + if ("comment" in diction.keys()): + if diction['comment']: + email_data['comment'] = diction['comment'] + + if ("memo" in diction.keys()): + if diction['memo']: + email_data['memo'] = diction['memo'] + + + if ("code_session" in local_tmp_session_data.keys()): + if local_tmp_session_data['code_session']: + email_data['code_session'] = local_tmp_session_data['code_session'] + + if ("date_debut" in local_tmp_session_data.keys()): + if local_tmp_session_data['date_debut']: + email_data['date_debut'] = str(local_tmp_session_data['date_debut'])[0:10] + + if ("date_fin" in local_tmp_session_data.keys()): + if local_tmp_session_data['date_fin']: + email_data['date_fin'] = str(local_tmp_session_data['date_fin'])[0:10] + + if ("adresse" in local_tmp_session_data.keys()): + if local_tmp_session_data['adresse']: + email_data['adresse'] = local_tmp_session_data['adresse'] + + if ("code_postal" in local_tmp_session_data.keys()): + if local_tmp_session_data['code_postal']: + email_data['code_postal'] = local_tmp_session_data['code_postal'] + + if ("ville" in local_tmp_session_data.keys()): + if local_tmp_session_data['ville']: + email_data['ville'] = local_tmp_session_data['ville'] + + if ("session_ondemande" in local_tmp_session_data.keys()): + if local_tmp_session_data['session_ondemande']: + email_data['session_ondemande'] = local_tmp_session_data['session_ondemande'] + + + + # ici recup du titre + lms_class_code = "" + for local_tmp_myclass in MYSY_GV.dbname['myclass'].find( + {'internal_url': str(myinternal_url)}): + + local_title = "" + if ("title" in local_tmp_myclass.keys() and local_tmp_myclass['title']): + local_title = local_tmp_myclass['title'] + email_data['title'] = local_title + + + if ("lms_class_code" in local_tmp_myclass.keys() ): + lms_class_code = local_tmp_myclass['lms_class_code'] + + print(" #### new_status / old_status / diction['status'] = ",new_status, old_status, str(diction['status']) ) + if ( new_status != old_status and diction['status'] == "0" ): + mail_data = {} + mail_data['email'] = diction['email'] + mail_data['class_internal_url'] = diction['class_internal_url'] + mail_data['session_id'] = diction['session_id'] + mail_data['inscription_id'] = diction['_id'] + + mail_data['token'] = diction['token'] + + # Il s'agit d'envoyer le message de presinscription + + local_status, local_message = SendPre_InscriptionEmail(mail_data) + if (local_status is False): + mycommon.myprint(" WARNING : Impossible d'envoyer le mail de preinscriton à " + + str(inspect.stack()[0][3]) + " - l'adresse email " + str( + mydata['email']) + " pour la session " + str(mydata['session_id']) + " ") + + Warning_message = " WARNING : Impossible d'envoyer le mail de preinscriton à " + str( + inspect.stack()[0][3]) + " - l'adresse email " + str( + mydata['email']) + " pour la session " + str(mydata['session_id']) + " " + + message_for_historic = message_for_historic + " : Email Préinscription " + + + if (new_status != old_status and diction['status'] == "1" ): + + # Il s'agit d'envoyer le message de confirmation d'une inscription + email_data['partner_owner_recid'] = str(partner_recid) + + """ + 26/02/2025 : + Si le paramettre, 'inscription_notification_email' de la collection 'base_partner_setup' est à 1, + alors on envoie un email de notification à l'apprenant + """ + local_insc_status, local_insc_retval = mycommon.Is_Partnair_Inscription_Notification( + {'token': diction['token']}) + if (local_insc_status and local_insc_retval == "1"): + print(" ### 1er envoie emailll email_data = ", email_data) + #local_status, local_message = email_session.incription_training_confirmation_mail(email_data) + message_for_historic = message_for_historic + " : Email Inscription " + + """ + Update du 28/12/2023 + """ + local_diction = {} + local_diction['token'] = str(diction['token']) + local_diction['email'] = str(diction['email']) + local_diction['inscription_id'] = str(diction['_id']) + + #print(" ### -- local_diction = ", local_diction) + + + local_status, local_retval = AcceptAttendeeInscription(local_diction) + if( local_status is False ): + return local_status, local_retval + + + + elif ( new_status != old_status and diction['status'] == "-1" ): + # Il s'agit d'envoyer le message de refus d'une inscription + if( "date_debut" not in email_data.keys() ): + email_data['date_du'] = "--" + else: + email_data['date_du'] = str(email_data['date_debut']) + + if ("date_fin" not in email_data.keys()): + email_data['date_au'] = "--" + else: + email_data['date_au'] = str(email_data['date_fin']) + + email_data['partner_recid'] = str(partner_recid) + email_data['token'] = str(diction['token']) + + print(" ### avant refus : email_data = ", email_data) + + local_insc_status, local_insc_retval = mycommon.Is_Partnair_Annulation_Inscription_Notification({'token': diction['token']}) + if (local_insc_status and local_insc_retval == "1"): + print(" ## OKKK ENVOIE MAIL REFUSSS") + local_status, local_message = email_session.incription_training_refused_mail(email_data) + else: + print(" ## NOOOOO ENVOIE MAIL REFUSSS") + + message_for_historic = message_for_historic + " : Email Refus Inscription " + + + + """ + # Ajout de l'evenement dans l'historique pour l'inscrit + """ + + message_for_historic = message_for_historic+", pour la session : "+str(local_tmp_session_data['_id']) + if( "code_session" in local_tmp_session_data.keys() ): + message_for_historic = message_for_historic + ", code session " + str(local_tmp_session_data['code_session']) + + + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + history_event_dict = {} + history_event_dict['token'] = diction['token'] + history_event_dict['related_collection'] = "inscription" + history_event_dict['related_collection_recid'] = str(diction['_id']) + history_event_dict['action_date'] = str(now) + history_event_dict['action_description'] = str(message_for_historic) + 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)) + + + inscrit_data = MYSY_GV.dbname['inscription'].find_one({'_id':ObjectId(str(diction['_id']).strip()), + 'partner_owner_recid': str(partner_recid),}) + """ + # Ajout de l'evenement dans l'historique pour la session + """ + session_info_message = "Annulation de l'inscription : "+str(inscrit_data['_id']) + if ("email" in local_tmp_session_data.keys()): + session_info_message = session_info_message + ", " + str(local_tmp_session_data['email']) + if ("nom" in local_tmp_session_data.keys()): + session_info_message = session_info_message + ", " + str(local_tmp_session_data['nom']) + if ("prenom" in local_tmp_session_data.keys()): + session_info_message = session_info_message + ", " + str(local_tmp_session_data['prenom']) + + + history_event_dict = {} + history_event_dict['token'] = diction['token'] + history_event_dict['related_collection'] = "session_formation" + history_event_dict['related_collection_recid'] = str(local_tmp_session_data['_id']) + history_event_dict['action_date'] = str(now) + history_event_dict['action_description'] = str(session_info_message) + 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)) + + """ + 31/03/2026 : Mise à jour du dossier apprenant si update_dossier_apprenant == "1" + """ + + #print(" ### mise à jour de l'apprenant 000 : ", ret_val2['apprenant_id']) + if ("update_dossier_apprenant" in diction.keys() and diction['update_dossier_apprenant'] == "1" + and "apprenant_id" in ret_val2.keys() and ret_val2['apprenant_id']): + + #print(" ### mise à jour de l'apprenant : ", ret_val2['apprenant_id']) + local_apprenant_id = ret_val2['apprenant_id'] + new_apprenant_data = {} + tab_champ = ['civilite', 'nom', 'prenom', 'employeur', 'email', 'adresse', 'code_postal', 'ville', + 'pays', 'ine', 'matricule', 'nom_fille', 'num_cvec', 'handicap_detail', 'num_secu', + 'is_handicap', 'nationalite', 'situation_famille', 'date_naissance', 'naissance_lieu', + 'naissance_departement', 'naissance_pays', 'identite_type', 'piece_identite_num', + 'is_rgpd', 'is_droit_image'] + + for field in tab_champ: + if( str(field) in ret_val2.keys()): + new_apprenant_data[str(field)] = ret_val2[str(field)] + + + new_apprenant_data['update_date'] = str(datetime.now()) + new_apprenant_data['update_by'] = str(my_partner['_id']) + + ret_val = MYSY_GV.dbname['apprenant'].find_one_and_update( + {'_id': ObjectId(str(ret_val2['apprenant_id'])), }, + {"$set": new_apprenant_data}, + upsert=False, + return_document=ReturnDocument.AFTER + ) + + + return True, "Les données du stagiaire ont été correctement mise à jour" + + + else: + mycommon.myprint(" Impossible de mettre à jour les données du stagiaire 1") + return False, "Impossible de mettre à jour les données du stagiaire " + + + + + 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 les informations du stagiaire" + + + +""" +Recuperation d'un stagiaire +""" +def GetStagiaire(diction): + try: + field_list = ['nom', 'adr_street', 'adr_city'] + 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, "Impossible de récupérer le stagiaire. Toutes les informations fournies ne sont pas valables" + + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['nom', 'email', 'pwd', ] + 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 récupérer le stagiaire, Toutes les informations necessaires n'ont pas été fournies" + + + return True + + 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 le stagiaire" + + +""" +Recuperation de liste des stagiaire d'une formation +# status : 0 ==> Preinscription +# status : 1 ==> Inscription validée +# status : -1 ==> Inscription annulée +""" +def GetAllClassStagiaire(diction): + try: + field_list = ['token', 'class_internal_url', 'session_id', '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é, Creation partenaire annulée") + return False, "de récupérer la liste des stagiaires . Toutes les informations fournies ne sont pas valables" + + """ + Verification de la liste 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, "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'] + + # Verifier la validité du token + retval = mycommon.check_partner_token_validity("", mytoken) + if retval is False: + return "Err_Connexion", " La session de connexion n'est pas valide" + + + partner_recid = mycommon.get_parnter_recid_from_token(mytoken) + if (partner_recid is False): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer la liste des stagiaires, ") + return False, "Impossible de récupérer la liste des stagiaires, Les informations d'identification sont incorrectes " + + """ + class_internal_url = "" + if ("class_internal_url" in diction.keys()): + if diction['class_internal_url']: + class_internal_url = diction['class_internal_url'] + """ + + session_id = "" + if ("session_id" in diction.keys()): + if diction['session_id']: + session_id = diction['session_id'] + + status = "" + if ("status" in diction.keys()): + if diction['status']: + status = diction['status'] + + + ## Recuperation de toutes les stagiaire rattaché à cette session + coll_session = MYSY_GV.dbname['inscription'] + myquery = {} + myquery['session_id'] = session_id + #myquery['class_internal_url'] = class_internal_url + + if(len(status) > 0 ): + myquery['status'] = status + + + RetObject = [] + val_tmp = 0 + + #print(" #### myquery 01111 = "+str(myquery)) + + + for retval in coll_session.find(myquery): + val_tmp = val_tmp + 1 + user = retval + user['id'] = str(val_tmp) + + 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'] + + user['client_rattachement_id'] = client_rattachement_id + user['client_rattachement_nom'] = client_rattachement_nom + + if ("facture_client_rattachement_id" in retval.keys()): + user['facture_client_rattachement_id'] = retval['facture_client_rattachement_id'] + else: + user['facture_client_rattachement_id'] = "" + + + if( "invoice_split" in retval.keys() ): + user['has_invoice_split'] = "1" + else: + user['has_invoice_split'] = "0" + + + #----- + 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'] + + user['financeur_rattachement_id'] = financeur_rattachement_id + user['financeur_rattachement_nom'] = financeur_rattachement_nom + + invoiced = "" + if( "invoiced" in retval.keys() ): + invoiced = retval['invoiced'] + user['invoiced'] = invoiced + + invoiced_ref = "" + if ("invoiced_ref" in retval.keys()): + invoiced_ref = retval['invoiced_ref'] + user['invoiced_ref'] = invoiced_ref + + invoiced_date = "" + if ("invoiced_date" in retval.keys()): + invoiced_date = str(retval['invoiced_date'])[0:10] + user['invoiced_date'] = invoiced_date + + + if ("civilite" in retval.keys()): + user['civilite'] = str(retval['civilite']).strip().lower() + else: + user['civilite'] = "neutre" + + if( str( user['civilite']) not in MYSY_GV.CIVILITE): + user['civilite'] = "neutre" + + if( str(user['civilite']).strip() == ""): + user['civilite'] = "neutre" + + if ( 'telephone' not in user.keys()): + user['telephone'] = "" + + lms_account_expiration_date = "" + if ("lms_account_expiration_date" in retval.keys()): + lms_account_expiration_date = retval['lms_account_expiration_date'] + user['lms_account_expiration_date'] = lms_account_expiration_date + + lms_class_code = "" + if ("lms_class_code" in retval.keys()): + lms_class_code = retval['lms_class_code'] + user['lms_class_code'] = lms_class_code + + lms_user_id = "" + if ("lms_user_id" in retval.keys()): + lms_user_id = retval['lms_user_id'] + user['lms_user_id'] = lms_user_id + + if ("rang" not in retval.keys()): + user['rang'] = "-" + else: + user['rang'] = retval['rang'] + + if ("rang_calculation_date" not in retval.keys()): + user['rang_calculation_date'] = "-" + else: + user['rang_calculation_date'] = retval['rang_calculation_date'] + + 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) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno)) + return False, "Impossible de récupérer la liste des stagiaires de la formation" + + + + +""" +Cette fonction envoie l'email de confirmation d'une inscription a une formation. + +Ceci est mis en "mode function" pour permettre aux utilisateur de renvoyer +autant de fois que souhaité la confirmation d'inscription +""" +def SendInscriptionConfirmation(diction): + try: + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', 'email', 'class_internal_url', '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, "Impossible d'envoyer la confirmation d'inscription" + + mytoken = "" + if ("token" in diction.keys()): + if diction['token']: + mytoken = diction['token'] + + # Verifier la validité du token + retval = mycommon.check_partner_token_validity("", mytoken) + if retval is False: + return "Err_Connexion", " La session de connexion n'est pas valide" + + partner_recid = mycommon.get_parnter_recid_from_token(mytoken) + if (partner_recid is False): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer le recid du partenaire") + return False, " Impossible d'envoyer le mail de confirmation" + + + + data_mail = {} + # 1 - Recuperation des données de la formation + local_class = MYSY_GV.dbname['myclass'].find({'internal_url':str(diction['class_internal_url'])}) + data_mail['title'] = local_class[0]['title'] + + + # 2 - Recuperation des données de l'inscription + local_inscription = MYSY_GV.dbname['inscription'].find({'session_id':str(diction['session_id']), + 'email':str(diction['email'])}) + local_nom = "" + if ("nom" in local_inscription[0].keys()): + if local_inscription[0]['nom']: + local_nom = local_inscription[0]['nom'] + data_mail['nom'] = local_nom + + local_prenom = "" + if ("prenom" in local_inscription[0].keys()): + if local_inscription[0]['prenom']: + local_prenom = local_inscription[0]['prenom'] + data_mail['prenom'] = local_prenom + + data_mail['email'] = local_inscription[0]['email'] + + # 3 - Recuperations des info de la session (a distance, formateur, etc) + local_info_session = MYSY_GV.dbname['session_formation'].find({'_id': ObjectId(str(diction['session_id'])), + 'class_internal_url': str( + diction['class_internal_url']), + 'valide': '1'}) + + if (local_info_session is None): + mycommon.myprint( + str(inspect.stack()[0][3]) + " - impossible d'envoyer le mail d'inscription. la session " + str( + diction['session_id']) + " est introuvable ") + return False, " impossible d'envoyer le mail d'inscription. la session " + str( + diction['session_id']) + " est introuvable " + + + date_du = "" + if ("date_debut" in local_info_session[0].keys()): + if local_info_session[0]['date_debut']: + date_du = local_info_session[0]['date_debut'] + data_mail['date_du'] = str(date_du)[0:10] + + date_au = "" + if ("date_fin" in local_info_session[0].keys()): + if local_info_session[0]['date_fin']: + date_au = local_info_session[0]['date_fin'] + data_mail['date_au'] = str(date_au)[0:10] + + adresse = "" + if ("adresse" in local_info_session[0].keys()): + if local_info_session[0]['adresse']: + adresse = local_info_session[0]['adresse'] + data_mail['adresse'] = adresse + + session_ondemande = "" + if ("session_ondemande" in local_info_session[0].keys()): + if local_info_session[0]['session_ondemande']: + session_ondemande = local_info_session[0]['session_ondemande'] + data_mail['session_ondemande'] = session_ondemande + + code_session = "" + if ("code_session" in local_info_session[0].keys()): + if local_info_session[0]['code_session']: + code_session = local_info_session[0]['code_session'] + data_mail['code_session'] = code_session + + session_id = "" + if ("session_id" in local_info_session[0].keys()): + if local_info_session[0]['_id']: + session_id = str(local_info_session[0]['session_id']) + data_mail['session_id'] = session_id + + data_mail['partner_owner_recid'] = str(partner_recid) + + data_mail['token'] = str(diction['token']) + + """ + 26/02/2025 : + Si le paramettre, 'inscription_notification_email' de la collection 'base_partner_setup' est à 1, + alors on envoie un email de notification à l'apprenant + """ + local_insc_status, local_insc_retval = mycommon.Is_Partnair_Inscription_Notification( + {'token': diction['token']}) + if (local_insc_status and local_insc_retval == "1"): + local_status, local_message = email_session.incription_training_confirmation_mail(data_mail) + return local_status, "La confirmation d'inscription a bien ete envoyée" + else: + return True, "La notification par email des inscriptions n'est pas activée." + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno)) + return False, "Impossible d'envoyer la confirmation d'inscription" + + +""" +Cette fonction envoie les pre-inscriptions +""" +def SendPre_InscriptionEmail(diction): + try: + """ + Verification de la liste des champs obligatoires + """ + + field_list_obligatoire = [ 'email', 'session_id', 'inscription_id', '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, "Impossible d'envoyer la pre-inscription " + + + data_mail = {} + + + # 2 - Recuperation des données de l'inscription + local_session = MYSY_GV.dbname['inscription'].find({'session_id':str(diction['session_id']), + 'email':str(diction['email']), + '_id':ObjectId(str(diction['inscription_id']))}) + + if (local_session is None): + mycommon.myprint( + str(inspect.stack()[0][3]) + " - Impossible de récupérer les information de la session de formation") + return False, "Impossible de récupérer les information de la session de formation " + + data_mail['token'] = str(diction['token']) + data_mail['nom'] = local_session[0]['nom'] + data_mail['prenom'] = local_session[0]['prenom'] + data_mail['email'] = local_session[0]['email'] + data_mail['partner_owner_recid'] = local_session[0]['partner_owner_recid'] + + + if ("employeur" in local_session[0].keys()): + if local_session[0]['employeur']: + data_mail['employeur'] = local_session[0]['employeur'] + + if ("telephone" in local_session[0].keys()): + if local_session[0]['telephone']: + data_mail['telephone'] = local_session[0]['telephone'] + + # 1 - Recuperation des données de la formation + local_class = MYSY_GV.dbname['myclass'].find({'internal_url': str(local_session[0]['class_internal_url']), + 'partner_owner_recid':str(local_session[0]['partner_owner_recid']), + 'valide':'1', 'locked':'0'}) + + if( local_class is None): + mycommon.myprint( + str(inspect.stack()[0][3]) + " - Impossible de récupérer les information de la formation") + return False, "Impossible de récupérer les information de la formation " + + + data_mail['title'] = local_class[0]['title'] + partner_recid = local_class[0]['partner_owner_recid'] + + # 1-BIS : Recuperation des donnees de l'editeur de la formation + local_partner = MYSY_GV.dbname['partnair_account'].find_one({'recid': str(partner_recid)}) + if( local_partner is None): + mycommon.myprint( + str(inspect.stack()[0][3]) + " - Impossible de récupérer les information du partenaire") + return False, "Impossible de récupérer les information du partenaire " + + + data_mail['partner_mail'] = local_partner['email'] + + + #3 - Recuperations des info de la session (a distance, formateur, etc) + local_info_session = MYSY_GV.dbname['session_formation'].find_one({'_id': ObjectId(str(diction['session_id'])), 'valide':'1'}) + + + + if( local_info_session is None): + mycommon.myprint( + str(inspect.stack()[0][3]) + " - impossible d'envoyer le mail de presinscription. la session "+str(diction['session_id'])+" est introuvable ") + return False, " impossible d'envoyer le mail de presinscription. la session "+str(diction['session_id'])+" est introuvable " + + code_postal = "" + if ("code_postal" in local_info_session.keys()): + if local_info_session['code_postal']: + code_postal = local_info_session['code_postal'] + data_mail['code_postal'] = code_postal + + code_session = "" + if ("code_session" in local_info_session.keys()): + if local_info_session['code_session']: + code_session = local_info_session['code_session'] + data_mail['code_session'] = code_session + + session_id = "" + if ("_id" in local_info_session.keys()): + session_id = str(local_info_session['_id']) + data_mail['session_id'] = session_id + + + date_debut = "" + if ("date_debut" in local_info_session.keys()): + if local_info_session['date_debut']: + date_debut = str(local_info_session['date_debut'])[0:10] + data_mail['date_du'] = date_debut + + date_fin = "" + if ("date_fin" in local_info_session.keys()): + if local_info_session['date_fin']: + date_fin = str(local_info_session['date_fin'])[0:10] + data_mail['date_au'] = date_fin + + formateur = "" + formateur_email = "" + if ("formateur_id" in local_info_session.keys()): + if local_info_session['formateur_id']: + formateur_data = MYSY_GV.dbname['ressource_humaine'].find_one({'_id':ObjectId(str(local_info_session['formateur_id'])), + 'valide':'1', + 'locked':'0', + 'partner_recid':str(local_session[0]['partner_owner_recid'])}) + + if (formateur_data and "nom" in formateur_data.keys() and "prenom" in formateur_data.keys()): + formateur = str(formateur_data['nom']) + " " + str(formateur_data['prenom']) + + if (formateur_data and "email" in formateur_data.keys()): + formateur_email = str(formateur_data['email']) + + data_mail['formateur'] = formateur + data_mail['formateur_email'] = formateur_email + + distantiel = "" + if ("distantiel" in local_info_session.keys()): + if local_info_session['distantiel']: + distantiel = local_info_session['distantiel'] + data_mail['distantiel'] = distantiel + + presentiel = "" + if ("presentiel" in local_info_session.keys()): + if local_info_session['presentiel']: + presentiel = local_info_session['presentiel'] + data_mail['presentiel'] = presentiel + + ville = "" + if ("ville" in local_info_session.keys()): + if local_info_session['ville']: + ville = local_info_session['ville'] + data_mail['ville'] = ville + + + adresse = "" + if ("adresse" in local_info_session.keys()): + if local_info_session['adresse']: + adresse = local_info_session['adresse'] + data_mail['adresse'] = adresse + + session_ondemande = "" + if ("session_ondemande" in local_info_session.keys()): + if local_info_session['session_ondemande']: + session_ondemande = local_info_session['session_ondemande'] + data_mail['session_ondemande'] = session_ondemande + + + #print(" Pre_incription_training_confirmation_mail DATA = ",data_mail ) + + # Envoi de l'email de confirmation au demandeur de la formation + """ + 26/02/2025 : + Si le paramettre, 'inscription_notification_email' de la collection 'base_partner_setup' est à 1, + alors on envoie un email de notification à l'apprenant uuuuuuuuuu + """ + + """ + 07/01/2026 - Si l'inscription est faite depuis la marketplace, alors on declenche + obligatoirement l'envoie de l'email de notification. + """ + local_insc_status, local_insc_retval = mycommon.Is_Partnair_Prenscription_Notification( + {'token': diction['token']}) + + inscription_from_marketplace = "" + if( "inscription_from_marketplace" in diction.keys() and diction['inscription_from_marketplace'] == "1"): + inscription_from_marketplace = "1" + + if ((local_insc_status and local_insc_retval == "1") or inscription_from_marketplace == "1"): + local_status, local_message = email_session.Pre_incription_training_confirmation_mail(data_mail) + + + if( "modefinancement" in diction.keys() ): + data_mail['modefinancement'] = diction['modefinancement'] + else: + data_mail['modefinancement'] = "" + + if ("opco" in diction.keys()): + data_mail['opco'] = diction['opco'] + else: + data_mail['opco'] = "" + + + + # Envoi de l'email de notification au formateur + local_status, local_message = email_session.Notification_partner_Pre_incription_mail(data_mail) + + return local_status, "La confirmation de la pre-inscription a bien ete envoyée" + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno)) + return False, "Impossible d'envoyer la confirmation d'inscription" + + +""" +Cette fonction retour en CSV la liste +des personnes inscrites à une session de formation +""" +def DownloadParticipantsList(diction): + try: + + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = field_list = ['token', 'session_id', 'internal_url'] + 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 generer la liste des participants. les informations sont incompletes" + + # Recuperation du recid du partner + mydata = {} + mytoken = "" + if ("token" in diction.keys()): + if diction['token']: + mytoken = diction['token'] + + partner_recid = mycommon.get_parnter_recid_from_token(mytoken) + if (partner_recid is False): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer la liste des stagiaires, ") + return False, " Impossible de generer la liste des participants. les informations sont incompletes" + + + session_id = "" + if ("session_id" in diction.keys()): + if diction['session_id']: + session_id = diction['session_id'] + + internal_url = "" + if ("internal_url" in diction.keys()): + if diction['internal_url']: + internal_url = diction['internal_url'] + + + # Recuperation des données de la session + + local_session = MYSY_GV.dbname['session_formation'].find_one({'_id':ObjectId(str(session_id)), 'class_internal_url':internal_url}) + + + if (local_session is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Cette de formation n'a pas d'informations detaillées ") + return False, " Cette session de formation n'a pas d'informations detaillées " + + # Recuperation des données de la formation + local_formation = MYSY_GV.dbname['myclass'].find_one({'internal_url':str(internal_url)}) + if (local_formation is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Cette de formation n'a pas d'informations detaillées (2) ") + return False, " Cette de formation n'a pas d'informations detaillées (2) " + + ## Recuperation de toutes les stagiaire rattaché à cette session + coll_session = MYSY_GV.dbname['inscription'] + myquery = {} + myquery['session_id'] = session_id + myquery['class_internal_url'] = internal_url + + + RetObject = [] + + for retval in coll_session.find(myquery, { 'session_id':0}): + + local_data = {} + local_data['titre'] = local_formation['title'] + local_data['debut_session'] = local_session ['date_debut'] + local_data['fin_session'] = local_session['date_fin'] + + local_formateur = "" + if ("formateur" in local_session.keys()): + if local_session['formateur']: + local_formateur = local_session['formateur'] + local_data['formateur'] = local_formateur + + presentiel = "" + if ("presentiel" in local_session.keys()): + if local_session['presentiel']: + presentiel = local_session['presentiel'] + local_data['presentiel'] = presentiel + + distantiel = "" + if ("distantiel" in local_session.keys()): + if local_session['distantiel']: + distantiel = local_session['distantiel'] + local_data['distantiel'] = distantiel + + adresse = "" + if ("adresse" in local_session.keys()): + if local_session['adresse']: + adresse = local_session['adresse'] + local_data['adresse'] = adresse + + ville = "" + if ("ville" in local_session.keys()): + if local_session['ville']: + ville = local_session['ville'] + local_data['ville'] = ville + + code_postal = "" + if ("code_postal" in local_session.keys()): + if local_session['code_postal']: + code_postal = local_session['code_postal'] + local_data['code_postal'] = code_postal + + prix_session = "" + if ("prix_session" in local_session.keys()): + if local_session['prix_session']: + prix_session = local_session['prix_session'] + local_data['prix_session'] = prix_session + + nb_participant = "" + if ("nb_participant" in local_session.keys()): + if local_session['nb_participant']: + nb_participant = local_session['nb_participant'] + local_data['nb_participants'] = nb_participant + + + + local_data['prenom'] = retval['prenom'] + local_data['nom'] = retval['nom'] + local_data['email'] = retval['email'] + local_data['telephone'] = retval['telephone'] + local_data['date_inscription'] = str(retval['_id'].generation_time.strftime("%m/%d/%Y, %H:%M")) + + + employeur = "" + if ("employeur" in retval.keys()): + if (retval['employeur']): + employeur = retval['employeur'] + local_data['employeur'] = employeur + + financement = "" + if ("modefinancement" in retval.keys()): + if (retval['modefinancement']): + financement = retval['modefinancement'] + local_data['financement'] = financement + + opco = "" + if ("opco" in retval.keys()): + if (retval['opco']): + opco = retval['opco'] + local_data['opco'] = opco + + if '_id' in local_data: + del local_data['_id'] + + if( retval['status'] == "1"): + local_data['status'] = "inscrit" + + elif (retval['status'] == "0"): + local_data['status'] = "en attente" + + elif (retval['status'] == "-1"): + local_data['status'] = "refusé" + + if ("inscription_validation_date" in retval.keys()): + if( retval['inscription_validation_date']): + local_data['inscription_validation_date'] = str(retval['inscription_validation_date'])[0:10] + + if ("inscription_refuse_date" in retval.keys()): + if (retval['inscription_refuse_date']): + local_data['inscription_refuse_date'] = str(retval['inscription_refuse_date'])[0:10] + + RetObject.append(local_data) + + + """ + Important : : Quand il n'y a pas encore de stagaire, alors le grid : RetObject : est vide car la boucle precedent est vide + Donc on retourne juste les infos de la session + """ + + print(" ### len(RetObject) = ", len(RetObject) , " RetObject = ", RetObject ) + if(len(RetObject) <= 0 ): + local_data = {} + local_data['titre_formation'] = local_formation['title'] + local_data['debut_session'] = local_session['date_debut'] + local_data['fin_session'] = local_session['date_fin'] + + local_formateur = "" + if ("formateur" in local_session.keys()): + if local_session['formateur']: + local_formateur = local_session['formateur'] + local_data['formateur'] = local_formateur + + presentiel = "" + if ("presentiel" in local_session.keys()): + if local_session['presentiel']: + local_formateur = local_session['presentiel'] + local_data['presentiel'] = presentiel + + distantiel = "" + if ("distantiel" in local_session.keys()): + if local_session['distantiel']: + distantiel = local_session['distantiel'] + local_data['distantiel'] = distantiel + + adresse = "" + if ("adresse" in local_session.keys()): + if local_session['adresse']: + adresse = local_session['adresse'] + local_data['adresse'] = adresse + + ville = "" + if ("ville" in local_session.keys()): + if local_session['ville']: + ville = local_session['ville'] + local_data['ville'] = ville + + code_postal = "" + if ("code_postal" in local_session.keys()): + if local_session['code_postal']: + code_postal = local_session['code_postal'] + local_data['code_postal'] = code_postal + + prix_session = "" + if ("prix_session" in local_session.keys()): + if local_session['prix_session']: + prix_session = local_session['prix_session'] + local_data['prix_session'] = prix_session + + nb_participant = "" + if ("nb_participant" in local_session.keys()): + if local_session['nb_participant']: + nb_participant = local_session['nb_participant'] + local_data['nb_participants'] = nb_participant + + local_data['nb_inscrit'] = "0" + + RetObject.append(local_data) + + # Expand the cursor and construct the DataFrame + df = pd.DataFrame(list(RetObject)) + + file_name_tmp = mycommon.create_token_urlsafe() + file_name = ''.join(char for char in file_name_tmp if char.isalnum()) + + #print("#### filename = "+str(file_name)) + + df.to_excel(MYSY_GV.TEMPORARY_DIRECTORY+"/"+str(file_name)+".xlsx", index=False) + if os.path.exists(MYSY_GV.TEMPORARY_DIRECTORY+"/"+str(file_name)+".xlsx"): + path = MYSY_GV.TEMPORARY_DIRECTORY+"/"+str(file_name)+".xlsx" + return True, send_file(path, as_attachment=True) + else: + return False, False + + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno)) + return False, "Impossible d'envoyer la confirmation d'inscription" + + +""" +Cette fonction imprime au formation csv la liste des evaluations d'une formation +""" +def DownloadEvaluationList(diction): + try: + + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', 'session_id', 'internal_url'] + 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 generer la liste des participants. les informations sont incompletes" + + # Recuperation du recid du partner + mydata = {} + mytoken = "" + if ("token" in diction.keys()): + if diction['token']: + mytoken = diction['token'] + + partner_recid = mycommon.get_parnter_recid_from_token(mytoken) + if (partner_recid is False): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer la liste des stagiaires, ") + return False, " Impossible de generer la liste des participants. les informations sont incompletes" + + + session_id = "" + if ("session_id" in diction.keys()): + if diction['session_id']: + session_id = diction['session_id'] + + internal_url = "" + if ("internal_url" in diction.keys()): + if diction['internal_url']: + internal_url = diction['internal_url'] + + + # Recuperation des données de la session + local_session = MYSY_GV.dbname['session_formation'].find_one({'_id':ObjectId(str(session_id)), 'class_internal_url':internal_url}) + + + if (local_session is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " L'identifiant de la session est invalide ") + return False, " L'identifiant de la session est invalide " + + # Recuperation des données de la formation + local_formation = MYSY_GV.dbname['myclass'].find_one({'internal_url':str(internal_url)}) + if (local_formation is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Cette de formation n'a pas d'informations detaillées (2) ") + return False, " Cette de formation n'a pas d'informations detaillées (2) " + + ## Recuperation de toutes les stagiaire rattaché à cette session + coll_session = MYSY_GV.dbname['inscription'] + myquery = {} + myquery['session_id'] = session_id + myquery['class_internal_url'] = internal_url + myquery['status'] = "1" + + + RetObject = [] + + for retval in coll_session.find(myquery, { 'session_id':0}): + + local_data = {} + local_data['titre'] = local_formation['title'] + local_data['code_session'] = local_session['code_session'] + titre_session = "" + if( "titre" in local_session.keys() ): + titre_session = local_session['titre'] + local_data['titre_session'] = titre_session + + nb_participants = "" + if ("nb_participant" in local_session.keys()): + nb_participants = local_session['nb_participant'] + local_data['nb_participant'] = nb_participants + + + local_data['debut_session'] = local_session ['date_debut'] + local_data['fin_session'] = local_session['date_fin'] + + + + formateur_nom_prenom = "" + # Si il y a un code formateur_id, alors on va recuperer les nom et prenom du formation + if ("formateur_id" in local_session.keys() and local_session['formateur_id']): + + formateur_data = MYSY_GV.dbname['ressource_humaine'].find_one( + {'_id': ObjectId(str(local_session['formateur_id'])), + 'valide': '1', + 'locked': '0', + 'partner_recid': str(partner_recid) + }) + + if (formateur_data and "nom" in formateur_data.keys() and "prenom" in formateur_data.keys()): + formateur_nom_prenom = str(formateur_data['nom']) + " " + str(formateur_data['prenom']) + + local_data['formateur'] = formateur_nom_prenom + + presentiel = "" + if ("presentiel" in local_session.keys()): + if local_session['presentiel']: + presentiel = local_session['presentiel'] + local_data['presentiel'] = presentiel + + distantiel = "" + if ("distantiel" in local_session.keys()): + if local_session['distantiel']: + distantiel = local_session['distantiel'] + local_data['distantiel'] = distantiel + + adresse = "" + if ("adresse" in local_session.keys()): + if local_session['adresse']: + adresse = local_session['adresse'] + local_data['adresse'] = adresse + + ville = "" + if ("ville" in local_session.keys()): + if local_session['ville']: + ville = local_session['ville'] + local_data['ville'] = ville + + code_postal = "" + if ("code_postal" in local_session.keys()): + if local_session['code_postal']: + code_postal = local_session['code_postal'] + local_data['code_postal'] = code_postal + + + + local_data['prenom'] = retval['prenom'] + local_data['nom'] = retval['nom'] + local_data['email'] = retval['email'] + local_data['telephone'] = retval['telephone'] + local_data['date_inscription'] = str(retval['_id'].generation_time.strftime("%m/%d/%Y, %H:%M")) + + eval_date = "" + if ("eval_date" in retval.keys()): + eval_date = retval['eval_date'] + local_data['evaluation_date'] = str(eval_date)[0:10] + + date_demande_eval = "" + if ("date_demande_eval" in retval.keys()): + date_demande_eval = retval['date_demande_eval'] + local_data['date_demande_eval'] = str(date_demande_eval)[0:10] + + + + eval_note = "" + if ("eval_note" in retval.keys()): + eval_note = retval['eval_note'] + local_data['evaluation_globale'] = eval_note + + eval_pedagogie = "" + if ("eval_pedagogie" in retval.keys()): + eval_pedagogie = retval['eval_pedagogie'] + local_data['evaluation_pedagogie'] = eval_pedagogie + + eval_eval = "" + if ("eval_eval" in retval.keys()): + eval_eval = retval['eval_eval'] + local_data['evaluation_commentaire'] = mycommon.cleanhtml(str(eval_eval)) + + + if ("inscription_validation_date" in retval.keys()): + if( retval['inscription_validation_date']): + local_data['inscription_validation_date'] = str(retval['inscription_validation_date'])[0:10] + + + RetObject.append(local_data) + + + """ + Important : : Quand il n'y a pas encore de stagaire, alors le grid : RetObject : est vide car la boucle precedent est vide + Donc on retourne juste les infos de la session + """ + + print(" ### len(RetObject) = ", len(RetObject) , " RetObject = ", RetObject ) + if(len(RetObject) <= 0 ): + local_data = {} + local_data['titre_formation'] = local_formation['title'] + local_data['debut_session'] = local_session['date_debut'] + local_data['fin_session'] = local_session['date_fin'] + + local_formateur = "" + if ("formateur" in local_session.keys()): + if local_session['formateur']: + local_formateur = local_session['formateur'] + local_data['formateur'] = local_formateur + + presentiel = "" + if ("presentiel" in local_session.keys()): + if local_session['presentiel']: + local_formateur = local_session['presentiel'] + local_data['presentiel'] = presentiel + + distantiel = "" + if ("distantiel" in local_session.keys()): + if local_session['distantiel']: + distantiel = local_session['distantiel'] + local_data['distantiel'] = distantiel + + adresse = "" + if ("adresse" in local_session.keys()): + if local_session['adresse']: + adresse = local_session['adresse'] + local_data['adresse'] = adresse + + ville = "" + if ("ville" in local_session.keys()): + if local_session['ville']: + ville = local_session['ville'] + local_data['ville'] = ville + + code_postal = "" + if ("code_postal" in local_session.keys()): + if local_session['code_postal']: + code_postal = local_session['code_postal'] + local_data['code_postal'] = code_postal + + prix_session = "" + if ("prix_session" in local_session.keys()): + if local_session['prix_session']: + prix_session = local_session['prix_session'] + local_data['prix_session'] = prix_session + + nb_participant = "" + if ("nb_participant" in local_session.keys()): + if local_session['nb_participant']: + nb_participant = local_session['nb_participant'] + local_data['nb_participants'] = nb_participant + + local_data['nb_inscrit'] = "0" + + RetObject.append(local_data) + + # Expand the cursor and construct the DataFrame + df = pd.DataFrame(list(RetObject)) + + file_name_tmp = mycommon.create_token_urlsafe() + file_name = ''.join(char for char in file_name_tmp if char.isalnum()) + + #print("#### filename = "+str(file_name)) + + df.to_excel(MYSY_GV.TEMPORARY_DIRECTORY+"/"+str(file_name)+".xlsx", index=False) + if os.path.exists(MYSY_GV.TEMPORARY_DIRECTORY+"/"+str(file_name)+".xlsx"): + path = MYSY_GV.TEMPORARY_DIRECTORY+"/"+str(file_name)+".xlsx" + return True, send_file(path, as_attachment=True) + else: + return False, False + + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno)) + return False, "Impossible d'envoyer la confirmation d'inscription" + + + +""" Import des inscriptions en masse +Avec l'import d'un fichier csv +""" +def AddStagiairetoClass_mass(file=None, Folder=None, diction=None): + try: + diction = mycommon.strip_dictionary(diction) + + ''' + # 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', 'session_id', 'class_internal_url'] + 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, Creation participants annulée") + return False, " Verifier votre API, Toutes les informations techniques ne sont pas fournies" + + ''' + 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', 'session_id', 'class_internal_url'] + + 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, " Verifier votre API, Toutes les informations techniques ne sont pas fournies" + + 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({'token': str(diction['token'])}) + if (local_status is not True): + return local_status, my_partner + + partner_recid = my_partner['recid'] + + + session_id = "" + if ("session_id" in diction.keys()): + if diction['session_id']: + session_id = diction['session_id'] + + class_internal_url = "" + if ("class_internal_url" in diction.keys()): + if diction['class_internal_url']: + class_internal_url = diction['class_internal_url'] + + + ## Verification de l'existance de session et recuperation du "code_session" + session_count = MYSY_GV.dbname['session_formation'].count_documents( + {'class_internal_url': str(class_internal_url), 'valide': '1', + '_id': ObjectId(str(session_id)), 'partner_owner_recid': str(partner_recid)}) + + if (session_count <= 0): + mycommon.myprint( + str(inspect.stack()[0][3]) + " -" + str(session_id) + " : ' Cette session n'est pas valide ") + return False, " Code de la session de formation n'est pas valide " + + if (session_count > 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " -" + str(session_id) + " : ' Cette session existe en double ") + return False, " Les données de la session de formation sont incohérentes " + + session_data = MYSY_GV.dbname['session_formation'].find_one( + {'class_internal_url': str(class_internal_url), 'valide': '1', + '_id': ObjectId(str(session_id)), 'partner_owner_recid': str(partner_recid)}) + + if( "code_session" not in session_data.keys() ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " - Cette session de formation n'a pas de code_session ") + return False, " Cette session de formation n'a pas de code_session " + + + code_session = session_data['code_session'] + + # Verification de l'existance de la formation (class_internal_url) + tmp_count = MYSY_GV.dbname['myclass'].count_documents({'internal_url': str(class_internal_url), 'valide': '1', + 'locked':'0', 'partner_owner_recid':str(partner_recid)}) + + # logging.info(" TMP = "+str(tmp)) + if (tmp_count <= 0): + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(class_internal_url) + " : ' Cette formation n'est pas valide ") + return False, " Cette formation n'est pas valide " + + MyClass_Data = MYSY_GV.dbname['myclass'].find_one({'internal_url': str(class_internal_url), 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(partner_recid)}) + + if( "external_code" not in MyClass_Data.keys()): + mycommon.myprint( + str(inspect.stack()[0][3]) + " -" + str(class_internal_url) + " : ' Cette formation n'est pas valide (2)") + return False, " Cette formation n'est pas valide (2)" + + MyClass_external_code = MyClass_Data['external_code'] + + + status, saved_file = mycommon.Upload_Save_CSV_File(file, Folder) + if (status == False): + mycommon.myprint("Impossible de récupérer correctement le fichier à importer") + return False, "Impossible d'importer la liste des participants, le nom du fichier est incorrect " + + #" Lecture du fichier " + #print(" Lecture du fichier : "+saved_file) + nb_line = 0 + + """" + update du 31/08/23 : Controle de l'integrité du fichier avant import + """ + local_controle_status, local_controle_message = Controle_AddStagiairetoClass_mass(saved_file, Folder,diction) + + if (local_controle_status is False): + return local_controle_status, local_controle_message + + #print(" #### local_controle_message = ", local_controle_message) + + df = pd.read_csv(saved_file, encoding='utf8', on_bad_lines='skip', sep=';', encoding_errors='ignore', skipinitialspace=True) + df = df.fillna('') + df = df.applymap(lambda x: x.strip() if isinstance(x, str) else x) + # Dictionnaire des champs utilisables + ''' + # Verification que les noms des colonne sont bien corrects" + ''' + field_list = ['formation_code_externe', 'code_session', 'prenom', 'nom', 'employeur', + 'telephone', 'email', 'modefinancement','opco', 'status', 'prix', 'adresse', 'code_postal', 'ville', + 'pays', 'client_rattachement_email', 'client_rattachement_nom', 'type_apprenant', 'civilite', 'date_naissance', + 'mode_financement_code', 'type_apprenant_code'] + + + # Controle du nombre de lignes dans le fichier. + total_rows = len(df) + if( total_rows > MYSY_GV.MAX_PARTICIPANT_BY_CSV ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le fichier comporte plus de "+str(MYSY_GV.MAX_PARTICIPANT_BY_CSV)+" lignes.") + return False, " Le fichier comporte plus de "+str(MYSY_GV.MAX_PARTICIPANT_BY_CSV)+" lignes." + + + #print(df.columns) + for val in df.columns: + if str(val).lower() not in field_list: + mycommon.myprint( + str(inspect.stack()[0][3])+" : entete du fichier csv. '" + val + "' n'est pas acceptée") + return False, " Entete du fichier csv. La Colonne '" + val + "' n'est pas acceptée" + + # Verification des champs obligatoires dans le fichier + field_list_obligatoire_file = ['prenom', 'nom', 'email', 'status', 'prix'] + + for val in field_list_obligatoire_file: + if val not in df.columns: + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " : Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire") + return False, " Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire " + + + + """ + # Recuperation des info de la session. + session_data = MYSY_GV.dbname['session_formation'].find_one({'formation_session_id':str(session_id)}) + if( session_data is None ): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La session de formation n'existe pas : Impossible d'importer la liste des participants ") + return False, "la session de formation n'existe pas. Impossible d'importer la liste des participants" + + #print(" #### session_data = ",session_data) + """ + x = range(0, total_rows) + for n in x: + mydata = {} + mydata['prenom'] = str(df['prenom'].values[n]) + mydata['nom'] = str(df['nom'].values[n]) + if (len(str(mydata['nom']).strip()) < 2): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'nom' de la ligne " + str( + n + 2) + " doit faire plus de deux caractères.") + return False, " Le champ nom de la ligne " + str( + n + 2) + " doit faire plus de deux caractères. " + + + mydata['employeur'] = str(df['employeur'].values[n]) + mydata['telephone'] = str(df['telephone'].values[n]) + mydata['email'] = str(df['email'].values[n]).strip().lower() + regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b' + if (not re.fullmatch(regex, str(df['email'].values[n]).strip() )): + mycommon.myprint( + str(inspect.stack()[0][3]) + " l'adresse email " + str(df['email'].values[n]).strip() + " est invalide") + return False, " l'adresse email -" + str(df['email'].values[n]).strip() + "- est invalide" + + + mydata['session_id'] = str(session_data['_id']) + mydata['token'] = str(my_token) + + date_naissance = "" + if ("date_naissance" in df.keys()): + if (str(df['date_naissance'].values[n])): + date_naissance = str(df['date_naissance'].values[n]) + mydata['date_naissance'] = date_naissance + + + modefinancement = "" + if ("modefinancement" in df.keys()): + if (str(df['modefinancement'].values[n])): + modefinancement = str(df['modefinancement'].values[n]) + mydata['modefinancement'] = modefinancement + + formation_code_externe = "" + if ("formation_code_externe" in df.keys()): + if (str(df['formation_code_externe'].values[n])): + formation_code_externe = str(df['formation_code_externe'].values[n]).strip() + + if( str(formation_code_externe).lower() != str(MyClass_external_code).lower()): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Le code externe de la formation" + str(df['formation_code_externe'].values[n]) + " ne correspond pas la formation en cours") + return False, " Le code externe de la formation" + str(df['formation_code_externe'].values[n]) + " ne correspond pas la formation en cours" + + local_code_session = "" + if ("code_session" in df.keys()): + if (str(df['code_session'].values[n])): + local_code_session = str(df['code_session'].values[n]).strip() + + if (str(local_code_session).lower() != str(code_session).lower()): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Le code session de la formation" + str( + df['code_session'].values[n]) + " ne correspond pas au code de la session en cours") + return False, " Le code externer de la formation" + str( + df['code_session'].values[n]) + " ne correspond pas au code de la session en cours" + + opco = "" + if ("opco" in df.keys()): + if (str(df['opco'].values[n])): + opco = str(df['opco'].values[n]) + mydata['opco'] = opco + + ##### + mode_financement_id = "" + if ("mode_financement_code" in df.keys()): + if (str(df['mode_financement_code'].values[n])): + mode_financement_code = str(df['mode_financement_code'].values[n]) + mode_financement_data = MYSY_GV.dbname['financement_mode'].find_one({'code':mode_financement_code, + 'valide':'1', + 'locked':'0', + 'partner_owner_recid':str(my_partner['recid'])}) + + if(mode_financement_data and '_id' in mode_financement_data.keys() ): + mode_financement_id = str(mode_financement_data['_id']) + else: + mycommon.myprint( + str(inspect.stack()[0][3]) + " Ligne : " + str( + n + 2) + ". Le code du mode de financement :" + str( + mode_financement_code) + " est invalide.") + return False, " Ligne : " + str( + n + 2) + ". Le code du mode de financement :" + str( + mode_financement_code) + " est invalide." + + mydata['modefinancement_id'] = mode_financement_id + + + type_apprenant_id = "" + if ("type_apprenant_code" in df.keys()): + if (str(df['type_apprenant_code'].values[n])): + type_apprenant_code = str(df['type_apprenant_code'].values[n]) + type_apprenant_data = MYSY_GV.dbname['type_apprenant'].find_one( + { + 'code': { + '$regex': f'^{re.escape(type_apprenant_code)}$', + '$options': 'i' + }, + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (type_apprenant_data and '_id' in type_apprenant_data.keys()): + type_apprenant_id = str(type_apprenant_data['_id']) + else: + mycommon.myprint( + str(inspect.stack()[0][3]) + " Ligne : " + str( + n + 2) + ". Le code du type d'apprenant :" + str( + type_apprenant_code) + " est invalide.") + return False, " Ligne : " + str( + n + 2) + ". Le code du type d'apprenant :" + str( + type_apprenant_code) + " est invalide." + + mydata['type_apprenant_id'] = type_apprenant_id + + ### + + # Verifier que le type d'apprenant est bien valide + type_apprenant = "0" + if ("type_apprenant" in df.keys()): + if (str(df['type_apprenant'].values[n])): + type_apprenant = str(df['type_apprenant'].values[n]) + type_apprenant = str(mycommon.tryInt(type_apprenant)) + + mydata['type_apprenant'] = type_apprenant + + + + + civilite = "" + if ("civilite" in df.keys()): + if (str(df['civilite'].values[n])): + civilite = str(df['civilite'].values[n]).lower() + + mydata['civilite'] = str(civilite).lower() + if( str(civilite).strip() == ""): + mydata['civilite'] = "neutre" + + + + if( civilite not in MYSY_GV.CIVILITE): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Ligne : " + str( + n + 2) + ". La civilité :" + str( + civilite) + " est invalide. Les valeurs acceptées sont : "+str(MYSY_GV.CIVILITE)) + return False, " Ligne : " + str( + n + 2) + ". La civilité :" + str( + civilite) + " est invalide. Les valeurs acceptées sont : "+str(MYSY_GV.CIVILITE) + + adresse = "" + if ("adresse" in df.keys()): + if (str(df['adresse'].values[n])): + adresse = str(df['adresse'].values[n]) + mydata['adresse'] = adresse + + code_postal = "" + if ("code_postal" in df.keys()): + if (str(df['code_postal'].values[n])): + code_postal = str(df['code_postal'].values[n]) + + if ("." in str(code_postal)): + # Important : : l'utilisateur envoie un code poster au format entier, plutot que string. + code_postal = str(code_postal).split(".")[0] + elif ("." in str(code_postal)): + # Important : : l'utilisateur envoie un code poster au format entier, plutot que string. + code_postal = str(code_postal).split(",")[0] + else: + code_postal = str(code_postal) + + mydata['code_postal'] = code_postal + + ville = "" + if ("ville" in df.keys()): + if (str(df['ville'].values[n])): + ville = str(df['ville'].values[n]) + mydata['ville'] = ville + + pays = "" + if ("pays" in df.keys()): + if (str(df['pays'].values[n])): + pays = str(df['pays'].values[n]) + mydata['pays'] = pays + + + """" + Gestion du client de rattachement/ + Avec l'email et le nom, on va aller récupérer l'_id du client + """ + client_rattachement_email = "" + if ("client_rattachement_email" in df.keys()): + if (str(df['client_rattachement_email'].values[n]) and str(df['client_rattachement_email'].values[n]) != "nan" ): + client_rattachement_email = str(df['client_rattachement_email'].values[n]).strip() + + + client_rattachement_nom = "" + if ("client_rattachement_nom" in df.keys() and str(df['client_rattachement_nom'].values[n]) != "nan"): + if (str(df['client_rattachement_nom'].values[n])): + client_rattachement_nom = str(df['client_rattachement_nom'].values[n]).strip() + + if( client_rattachement_email and client_rattachement_nom ): + local_client_retval_qry = {'email':str(client_rattachement_email), 'nom':str(client_rattachement_nom), 'valide':'1', + 'locked':'0', 'partner_owner_recid' :str(partner_recid)} + + print(" ### local_client_retval_qry = ", local_client_retval_qry) + local_client_retval_count = MYSY_GV.dbname['partner_client'].count_documents(local_client_retval_qry) + + if( local_client_retval_count > 1 ): + mycommon.myprint( + str(inspect.stack()[0][3]) +"Ligne : "+str(n) +". Plusieurs clients correspondent aux critère de nom :"+str(client_rattachement_nom)+" et email : "+str(client_rattachement_email)) + return False, "Ligne : "+str(n) +". Plusieurs clients correspondent aux critère de nom :"+str(client_rattachement_nom)+" et email : "+str(client_rattachement_email) + + if (local_client_retval_count < 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : "+str(n) +". Aucun client ne repond aux critères de nom :" + str( + client_rattachement_nom) + " et email : " + str(client_rattachement_email)) + return False, "Ligne : "+str(n) +". Aucun client ne repond aux critères de nom :" + str( + client_rattachement_nom) + " et email : " + str(client_rattachement_email) + + local_client_retval_data = MYSY_GV.dbname['partner_client'].find_one(local_client_retval_qry) + if( local_client_retval_data is not None ): + mydata['client_rattachement_id'] = str(local_client_retval_data['_id']) + + status = str(df['status'].values[n]).strip() + status = str(mycommon.tryInt(status)) + + if (str(status) != "0" and str(status) != "1" and str(status) != "2"): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'status' de la ligne " + str( + n) + " est incorrecte. Valeurs acceptées : 0,1,2") + return False, " Le champ status de la ligne " + str(n) + " est incorrecte. Valeurs acceptées : 0,1,2" + + mydata['status'] = str(df['status'].values[n]).strip() + if (status == "1"): + mydata['inscription_validation_date'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + + + mydata['class_internal_url'] = str(class_internal_url) + + + local_price = str(df['prix'].values[n]).strip() + local_status, new_price = mycommon.IsFloat(local_price) + if( local_status is False ): + mycommon.myprint( + str(inspect.stack()[0][ 3]) + " Le champ 'prix' de la ligne " + str( n) + " est incorrecte.") + return False, " Le champ prix de la ligne " + str(n) + " est incorrecte. " + + mydata['price'] = local_price + + + clean_dict = {k: mydata[k] for k in mydata if ( str(mydata[k]) != "nan") } + + print( "#### clean_dict 02 ", clean_dict) + status, retval = AddStagiairetoClass(clean_dict) + + if( status is False ): + return status, retval + + print(str(total_rows)+" participants ont été inserés") + + return True, str(total_rows)+" participants ont été inserés / 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 d'importer les participants en masse " + + +""" +Controle du fichier à importer avant import +""" + +def Controle_AddStagiairetoClass_mass(saved_file=None, Folder=None, diction=None): + try: + + diction = mycommon.strip_dictionary(diction) + + ''' + # 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', 'session_id', 'class_internal_url'] + 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, Creation participants annulée") + return False, " Verifier votre API, Toutes les informations techniques ne sont pas fournies" + + ''' + 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', 'session_id', 'class_internal_url'] + + 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, " Verifier votre API, Toutes les informations techniques ne sont pas fournies" + + my_token = "" + if ("token" in diction.keys()): + if diction['token']: + my_token = diction['token'] + + partner_recid = mycommon.get_parnter_recid_from_token(my_token) + if (partner_recid is False): + mycommon.myprint( + str(inspect.stack()[0][3]) + " - partner_recid KO : Impossible d'importer la liste des participants ") + return False, " Les information de connexion sont incorrectes. Impossible d'importer la liste des participants" + + # Verifier la validité du token + retval = mycommon.check_partner_token_validity("", my_token) + if retval is False: + return "Err_Connexion", " La session de connexion n'est pas valide" + + session_id = "" + if ("session_id" in diction.keys()): + if diction['session_id']: + session_id = diction['session_id'] + + class_internal_url = "" + if ("class_internal_url" in diction.keys()): + if diction['class_internal_url']: + class_internal_url = diction['class_internal_url'] + + # Verification de l'existance de la session + ## Verification de l'existance de session et recuperation du "code_session" + session_count = MYSY_GV.dbname['session_formation'].count_documents( + {'class_internal_url': str(class_internal_url), 'valide': '1', + '_id': ObjectId(str(session_id)), 'partner_owner_recid': str(partner_recid)}) + + if (session_count <= 0): + mycommon.myprint( + str(inspect.stack()[0][3]) + " -" + str(session_id) + " : ' Cette session n'est pas valide ") + return False, " Code de la session de formation n'est pas valide " + + if (session_count > 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " -" + str(session_id) + " : ' Cette session existe en double ") + return False, " Les données de la session de formation sont incohérentes " + + session_data = MYSY_GV.dbname['session_formation'].find_one( + {'class_internal_url': str(class_internal_url), 'valide': '1', + '_id': ObjectId(str(session_id)), 'partner_owner_recid': str(partner_recid)}) + + if ("code_session" not in session_data.keys()): + mycommon.myprint( + str(inspect.stack()[0][3]) + " - Cette session de formation n'a pas de code_session ") + return False, " Cette session de formation n'a pas de code_session " + + code_session = session_data['code_session'] + + # Verification de l'existance de la formation (class_internal_url) + tmp_count = MYSY_GV.dbname['myclass'].count_documents({'internal_url': str(class_internal_url), 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(partner_recid)}) + + # logging.info(" TMP = "+str(tmp)) + if (tmp_count <= 0): + mycommon.myprint( + str(inspect.stack()[0][3]) + " -" + str(class_internal_url) + " : ' Cette formation n'est pas valide ") + return False, " Cette formation n'est pas valide " + + MyClass_Data = MYSY_GV.dbname['myclass'].find_one({'internal_url': str(class_internal_url), 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(partner_recid)}) + + if ("external_code" not in MyClass_Data.keys()): + mycommon.myprint( + str(inspect.stack()[0][3]) + " -" + str( + class_internal_url) + " : ' Cette formation n'est pas valide (2)") + return False, " Cette formation n'est pas valide (2)" + + MyClass_external_code = MyClass_Data['external_code'] + + + # " Lecture du fichier " + # print(" Lecture du fichier : "+saved_file) + nb_line = 0 + + df = pd.read_csv(saved_file, encoding='utf8', on_bad_lines='skip', sep=';', encoding_errors='ignore', skipinitialspace=True) + df = df.fillna('') + df = df.applymap(lambda x: x.strip() if isinstance(x, str) else x) + + # Dictionnaire des champs utilisables + ''' + # Verification que les noms des colonne sont bien corrects" + ''' + field_list = ['formation_code_externe', 'code_session', 'prenom', 'nom', 'employeur', + 'telephone', 'email', 'modefinancement', 'opco', 'status', 'prix', 'adresse', 'code_postal', + 'ville', + 'pays', 'client_rattachement_email', 'client_rattachement_nom', 'type_apprenant', 'civilite', + 'date_naissance', 'mode_financement_code', 'type_apprenant_code'] + + # Controle du nombre de lignes dans le fichier. + total_rows = len(df) + if (total_rows > MYSY_GV.MAX_PARTICIPANT_BY_CSV): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le fichier comporte plus de " + str( + MYSY_GV.MAX_PARTICIPANT_BY_CSV) + " lignes.") + return False, " Le fichier comporte plus de " + str(MYSY_GV.MAX_PARTICIPANT_BY_CSV) + " lignes." + + # print(df.columns) + for val in df.columns: + if str(val).lower() not in field_list: + mycommon.myprint( + str(inspect.stack()[0][3]) + " : entete du fichier csv. '" + val + "' n'est pas acceptée") + return False, " Entete du fichier csv. La Colonne '" + val + "' n'est pas acceptée" + + # Verification des champs obligatoires dans le fichier + field_list_obligatoire_file = ['prenom', 'nom', 'email', 'status', 'prix'] + + for val in field_list_obligatoire_file: + if val not in df.columns: + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " : Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire") + return False, " Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire " + + + """ + # Recuperation des info de la session. + session_data = MYSY_GV.dbname['session_formation'].find_one({'formation_session_id':str(session_id)}) + if( session_data is None ): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La session de formation n'existe pas : Impossible d'importer la liste des participants ") + return False, "la session de formation n'existe pas. Impossible d'importer la liste des participants" + + #print(" #### session_data = ",session_data) + """ + x = range(0, total_rows) + for n in x: + mydata = {} + mydata['prenom'] = str(df['prenom'].values[n]) + mydata['nom'] = str(df['nom'].values[n]) + if(len(str(mydata['nom']).strip()) < 2 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'nom' de la ligne " + str( + n + 2) + " doit faire plus de deux caractères.") + return False, " Le champ nom de la ligne " + str( + n + 2) + " doit faire plus de deux caractères. " + + + mydata['employeur'] = str(df['employeur'].values[n]) + mydata['telephone'] = str(df['telephone'].values[n]) + mydata['email'] = str(df['email'].values[n]).strip().lower() + regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b' + if (not re.fullmatch(regex, str(df['email'].values[n]).strip() )): + mycommon.myprint( + str(inspect.stack()[0][3]) + " l'adresse email " + str(df['email'].values[n]).strip() + " est invalide") + return False, " l'adresse email -" + str(df['email'].values[n]).strip() + "- est invalide" + + mydata['session_id'] = str(session_data['_id']) + mydata['token'] = str(my_token) + + if ("date_naissance" in df.keys()): + mydata['date_naissance'] = str(df['date_naissance'].values[n]).strip().split(" ")[0] + if( mydata['date_naissance']): + local_status = mycommon.CheckisDate(mydata['date_naissance']) + if (local_status is False): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La date de naissance à ligne " + str(n + 2) + " n'est pas au format 'jj/mm/aaaa' .") + + return False, " La date de naissance à ligne " + str(n + 2) + " n'est pas au format 'jj/mm/aaaa' " + else: + mydata['date_naissance'] = "" + + + civilite = "" + if ("civilite" in df.keys()): + if (str(df['civilite'].values[n])): + civilite = str(df['civilite'].values[n]).lower() + mydata['civilite'] = str(civilite).lower() + if (civilite not in MYSY_GV.CIVILITE): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Ligne : " + str( + n + 2) + ". La civilité :" + str( + civilite) + " est invalide. Les valeurs acceptées sont : " + str(MYSY_GV.CIVILITE)) + return False, " Ligne : " + str( + n + 2) + ". La civilité :" + str( + civilite) + " est invalide. Les valeurs acceptées sont : " + str(MYSY_GV.CIVILITE) + + + ##### + mode_financement_id = "" + if ("mode_financement_code" in df.keys()): + if (str(df['mode_financement_code'].values[n])): + mode_financement_code = str(df['mode_financement_code'].values[n]) + mode_financement_data = MYSY_GV.dbname['financement_mode'].find_one( + {'code': mode_financement_code, + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(partner_recid)}) + + if (mode_financement_data and '_id' in mode_financement_data.keys()): + mode_financement_id = str(mode_financement_data['_id']) + else: + mycommon.myprint( + str(inspect.stack()[0][3]) + " Ligne : " + str( + n + 2) + ". Le code du mode de financement :" + str( + mode_financement_code) + " est invalide.") + return False, " Ligne : " + str( + n + 2) + ". Le code du mode de financement :" + str( + mode_financement_code) + " est invalide." + + mydata['modefinancement_id'] = mode_financement_id + + type_apprenant_id = "" + if ("type_apprenant_code" in df.keys()): + if (str(df['type_apprenant_code'].values[n])): + type_apprenant_code = str(df['type_apprenant_code'].values[n]) + type_apprenant_data = MYSY_GV.dbname['type_apprenant'].find_one( + { + 'code': { + '$regex': f'^{re.escape(type_apprenant_code)}$', + '$options': 'i' + }, + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(partner_recid)}) + + if (type_apprenant_data and '_id' in type_apprenant_data.keys()): + type_apprenant_id = str(type_apprenant_data['_id']) + else: + mycommon.myprint( + str(inspect.stack()[0][3]) + " Ligne : " + str( + n + 2) + ". Le code du type d'apprenant :" + str( + type_apprenant_code) + " est invalide.") + return False, " Ligne : " + str( + n + 2) + ". Le code du type d'apprenant :" + str( + type_apprenant_code) + " est invalide." + + mydata['type_apprenant_id'] = type_apprenant_id + + ### + modefinancement = "" + if ("modefinancement" in df.keys()): + if (str(df['modefinancement'].values[n])): + modefinancement = str(df['modefinancement'].values[n]) + mydata['modefinancement'] = modefinancement + + formation_code_externe = "" + if ("formation_code_externe" in df.keys()): + if (str(df['formation_code_externe'].values[n])): + formation_code_externe = str(df['formation_code_externe'].values[n]).strip() + + if (str(formation_code_externe).lower() != str(MyClass_external_code).lower()): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Le code externe de la formation" + str( + df['formation_code_externe'].values[ + n]) + " ne correspond pas la formation en cours") + return False, " Le code externe de la formation" + str( + df['formation_code_externe'].values[n]) + " ne correspond pas la formation en cours" + + local_code_session = "" + if ("code_session" in df.keys()): + if (str(df['code_session'].values[n])): + local_code_session = str(df['code_session'].values[n]).strip() + + if (str(local_code_session).lower() != str(code_session).lower()): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Le code session de la formation" + str( + df['code_session'].values[n]) + " ne correspond pas au code de la session en cours") + return False, " Le code externer de la formation" + str( + df['code_session'].values[n]) + " ne correspond pas au code de la session en cours" + + opco = "" + if ("opco" in df.keys()): + if (str(df['opco'].values[n])): + opco = str(df['opco'].values[n]) + mydata['opco'] = opco + + # Verifier que le type d'apprenant est bien valide + type_apprenant = "0" + if ("type_apprenant" in df.keys()): + if (str(df['type_apprenant'].values[n])): + type_apprenant = str(df['type_apprenant'].values[n]) + type_apprenant = str(mycommon.tryInt(diction['type_apprenant'])) + + if (type_apprenant not in MYSY_GV.INSCRIPTION_TYPE_APPRENANT): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : " + str( + n) + ". Le type d'apprenant est invalide ") + return False, " Ligne : " + str( + n) + ". Le type d'apprenant est invalide. Valeurs autorisées" + str( + MYSY_GV.INSCRIPTION_TYPE_APPRENANT) + + + + adresse = "" + if ("adresse" in df.keys()): + if (str(df['adresse'].values[n])): + adresse = str(df['adresse'].values[n]) + mydata['adresse'] = adresse + + code_postal = "" + if ("code_postal" in df.keys()): + if (str(df['code_postal'].values[n])): + code_postal = str(df['code_postal'].values[n]).strip() + + if ("." in str(code_postal)): + # Important : : l'utilisateur envoie un code poster au format entier, plutot que string. + code_postal = str(code_postal).split(".")[0] + elif ("." in str(code_postal)): + # Important : : l'utilisateur envoie un code poster au format entier, plutot que string. + code_postal = str(code_postal).split(",")[0] + else: + code_postal = str(code_postal) + + mydata['code_postal'] = code_postal + + + + ville = "" + if ("ville" in df.keys()): + if (str(df['ville'].values[n])): + ville = str(df['ville'].values[n]) + mydata['ville'] = ville + + pays = "" + if ("pays" in df.keys()): + if (str(df['pays'].values[n])): + pays = str(df['pays'].values[n]) + mydata['pays'] = pays + + """" + Gestion du client de rattachement/ + Avec l'email et le nom, on va aller récupérer l'_id du client + """ + client_rattachement_email = "" + if ("client_rattachement_email" in df.keys()): + if (str(df['client_rattachement_email'].values[n]) and str( + df['client_rattachement_email'].values[n]) != "nan"): + client_rattachement_email = str(df['client_rattachement_email'].values[n]) + + client_rattachement_nom = "" + if ("client_rattachement_nom" in df.keys() and str(df['client_rattachement_nom'].values[n]) != "nan"): + if (str(df['client_rattachement_nom'].values[n])): + client_rattachement_nom = str(df['client_rattachement_nom'].values[n]) + + if (client_rattachement_email and client_rattachement_nom): + local_client_retval_qry = {'email': str(client_rattachement_email), + 'nom': str(client_rattachement_nom), 'valide': '1', + 'locked': '0', 'partner_owner_recid': str(partner_recid)} + + print(" ### local_client_retval_qry = ", local_client_retval_qry) + local_client_retval_count = MYSY_GV.dbname['partner_client'].count_documents( + local_client_retval_qry) + + if (local_client_retval_count > 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : " + str( + n) + ". Plusieurs clients correspondent aux critère de nom :" + str( + client_rattachement_nom) + " et email : " + str(client_rattachement_email)) + return False, "Ligne : " + str( + n) + ". Plusieurs clients correspondent aux critère de nom :" + str( + client_rattachement_nom) + " et email : " + str(client_rattachement_email) + + if (local_client_retval_count < 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : " + str( + n) + ". Aucun client ne repond aux critères de nom :" + str( + client_rattachement_nom) + " et email : " + str(client_rattachement_email)) + return False, "Ligne : " + str(n) + ". Aucun client ne repond aux critères de nom :" + str( + client_rattachement_nom) + " et email : " + str(client_rattachement_email) + + local_client_retval_data = MYSY_GV.dbname['partner_client'].find_one(local_client_retval_qry) + if (local_client_retval_data is not None): + mydata['client_rattachement_id'] = str(local_client_retval_data['_id']) + + + status = str(df['status'].values[n]).strip() + status = str(mycommon.tryInt(status)) + + + if (str(status) != "0" and str(status) != "1" and str(status) != "2"): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'status' de la ligne " + str( + n) + " est incorrecte. Valeurs acceptées : 0,1,2") + return False, " Le champ status de la ligne " + str( + n) + " est incorrecte. Valeurs acceptées : 0,1,2" + + mydata['status'] = status + + + if (str(status).strip() == "1"): + mydata['inscription_validation_date'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + mydata['class_internal_url'] = str(class_internal_url) + + local_price = str(df['prix'].values[n]).strip() + local_status, new_price = mycommon.IsFloat(local_price) + if (local_status is False): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'prix' de la ligne " + str(n) + " est incorrecte.") + return False, " Le champ prix de la ligne " + str(n) + " est incorrecte. " + + mydata['price'] = local_price + + ## Verifier que le stagiaire n'est pas deja inscrit à cette formation. + qry_count = {'email': str(mydata['email']).lower(), 'session_id': str(session_id), 'partner_owner_recid':str(partner_recid) } + qry_count_result = MYSY_GV.dbname['inscription'].count_documents(qry_count) + + if( qry_count_result > 0 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Ligne " + str(n) + " : L'adresse email "+str()+" est déjà inscrite à la session :"+str(code_session)+". ") + return False, " Ligne " + str(n) + " : L'adresse email "+str(mydata['email'])+" est déjà inscrite à la session de formation :"+str(code_session)+". " + + + + return True, str(total_rows) + " participants lus dans le fichier excel" + + 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 controler le fichier " + + +""" +Cette fonction permet d'importer un fichier excel pour les stagiaire de plusieurs session, plusieurs formations +Important : : Controle session : on va utiliser les colonne : formation code externe et le code de la session +Important : : controle du client : on va utiliser le mail et le nom du client pour voir si ca concorde. + +update du 21/08/23 : +Pour eviter les imports partiels du fichier, on va créer une fonction qui va faire les controles. +Si cette fonction est ok, alors on lance la fonction d'import. + +Elle fera a peu pret les meme controle qui existe dans la fonction d'import actuelle. + +18/04/25 : +dans les arguments, 'session_id' sera fourni en option. Si cette dernière est fourni, alors il faudrait +obligatoirement s'assurer que le conteu du fichier excel correspond exclusivement a cette session + +""" +def AddStagiairetoClass_mass_for_many_session(file=None, Folder=None, diction=None): + try: + + diction = mycommon.strip_dictionary(diction) + + ''' + # 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', '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, Creation participants annulée") + return False, " Verifier votre API" + + ''' + 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, " Verifier votre API, Toutes les informations techniques ne sont pas fournies" + + 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 "Err_Connexion", " La session de connexion n'est pas valide" + + + + partner_recid = mycommon.get_parnter_recid_from_token(my_token) + if (partner_recid is False): + mycommon.myprint(str(inspect.stack()[0][3]) + " - partner_recid KO : Impossible d'importer la liste des participants ") + return False, " Les information de connexion sont incorrectes. Impossible d'importer la liste des participants" + + + """ + Si le champ 'session_id' est fourni, alors il faut s'assurer que l'import ne se fait exclusivement + pour la session indiquée + """ + + local_session_id = None + local_session_id_data = None + + if( "session_id"in diction.keys() and diction['session_id']): + local_session_id = diction['session_id'] + local_session_id_count = MYSY_GV.dbname['session_formation'].count_documents({'_id':ObjectId(str(local_session_id)), + 'valide':'1', + 'partner_owner_recid':partner_recid}) + + if( local_session_id_count != 1): + mycommon.myprint(str( + inspect.stack()[0][3]) + " L'identifiant de la session de formation est invalide ") + return False, " L'identifiant de la session de formation est invalide" + + local_session_id_data = MYSY_GV.dbname['session_formation'].find_one( + {'_id': ObjectId(str(local_session_id)), + 'valide': '1', + 'partner_owner_recid': partner_recid}) + + + + status, saved_file = mycommon.Upload_Save_CSV_File(file, Folder) + if (status == False): + mycommon.myprint("Impossible de récupérer correctement le fichier à importer") + return False, "Impossible d'importer la liste des participants, le nom du fichier est incorrect " + + #" Lecture du fichier " + #print(" Lecture du fichier : "+saved_file) + nb_line = 0 + + """" + update du 21/08/23 : Controle de l'integrité du fichier + """ + local_controle_status, local_controle_message = Controle_AddStagiairetoClass_mass_for_many_session(saved_file, Folder, + diction) + + if (local_controle_status is False): + return local_controle_status, local_controle_message + + print(" #### local_controle_message = ", local_controle_message) + + + df = pd.read_csv(saved_file, encoding='utf8', on_bad_lines='skip', sep=';', encoding_errors='ignore', skipinitialspace=True) + df = df.fillna('') + df = df.applymap(lambda x: x.strip() if isinstance(x, str) else x) + + # Dictionnaire des champs utilisables + ''' + # Verification que les noms des colonne sont bien corrects" + ''' + field_list = ['formation_code_externe', 'code_session', 'prenom', 'nom', 'employeur', + 'telephone', 'email', 'modefinancement', 'opco', 'status', 'prix', 'adresse', 'code_postal', + 'ville', 'pays', 'client_rattachement_email', 'client_rattachement_nom','facture_client_rattachement_email', + 'facture_client_rattachement_nom', 'civilite', 'type_apprenant', 'date_naissance', + 'mode_financement_code', 'type_apprenant_code'] + + + # Controle du nombre de lignes dans le fichier. + total_rows = len(df) + if( total_rows > MYSY_GV.MAX_PARTICIPANT_BY_CSV ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le fichier comporte plus de "+str(MYSY_GV.MAX_PARTICIPANT_BY_CSV)+" lignes.") + return False, " Le fichier comporte plus de "+str(MYSY_GV.MAX_PARTICIPANT_BY_CSV)+" lignes." + + + #print(df.columns) + for val in df.columns: + if str(val).lower() not in field_list: + mycommon.myprint( + str(inspect.stack()[0][3])+" : entete du fichier csv. '" + val + "' n'est pas acceptée") + return False, " Entete du fichier csv.La Colonne '" + val + "' n'est pas acceptée" + + + # Verification des champs obligatoires dans le fichier + field_list_obligatoire_file = ['prenom', 'nom', 'email', 'status', 'prix'] + + for val in field_list_obligatoire_file: + if val not in df.columns: + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " : Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire") + return False, " Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire " + + + """ + # Recuperation des info de la session. + session_data = MYSY_GV.dbname['session_formation'].find_one({'formation_session_id':str(session_id)}) + if( session_data is None ): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La session de formation n'existe pas : Impossible d'importer la liste des participants ") + return False, "la session de formation n'existe pas. Impossible d'importer la liste des participants" + + #print(" #### session_data = ",session_data) + """ + x = range(0, total_rows) + for n in x: + + if( str(df['prenom'].values[n]) and str(df['nom'].values[n]) and str(df['email'].values[n]) ) : + """ + 18/04/25 : + dans les arguments, 'session_id' sera fourni en option. Si cette dernière est fourni, alors il faudrait + obligatoirement s'assurer que le conteu du fichier excel correspond exclusivement a cette session + """ + if( local_session_id_data and "code_session" in local_session_id_data.keys() ): + if( str(local_session_id_data['code_session']).lower() != str(df['code_session'].values[n]).lower() ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Ligne " + str(n + 2) + " : Le code session '"+str(df['code_session'].values[n]) +"' ne correspond pas à la session selectionnée : '"+str(local_session_id_data['code_session'])+"' ") + return False, " Ligne " + str(n + 2) + " : Le code session '"+str(df['code_session'].values[n]) +"' ne correspond pas à la session selectionnée : '"+str(local_session_id_data['code_session'])+"' " + + + mydata = {} + class_external_code = str(df['formation_code_externe'].values[n]) + #mydata['code_session'] = str(df['code_session'].values[n]) + mydata['prenom'] = str(df['prenom'].values[n]).strip() + mydata['nom'] = str(df['nom'].values[n]).strip() + if (len(str(mydata['nom']).strip()) < 2): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'nom' de la ligne " + str( + n + 2) + " doit faire plus de deux caractères.") + return False, " Le champ nom de la ligne " + str( + n + 2) + " doit faire plus de deux caractères. " + + + mydata['employeur'] = str(df['employeur'].values[n]).strip() + mydata['telephone'] = str(df['telephone'].values[n]).strip() + mydata['email'] = str(df['email'].values[n]).strip().strip().lower() + regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b' + if (not re.fullmatch(regex, str(df['email'].values[n]).strip() )): + mycommon.myprint( + str(inspect.stack()[0][3]) + " l'adresse email " + str(df['email'].values[n]).strip() + " est invalide") + return False, " l'adresse email -" + str(df['email'].values[n]).strip() + "- est invalide" + + mydata['token'] = str(my_token) + + """ + Recuperation de l'internal url de la formation a partir de la cle + - formation code externe + - partner_owner_recid + """ + qry = {'external_code':str(class_external_code), 'valide':'1', 'locked':'0', 'partner_owner_recid':str(partner_recid)} + + myclass_data_count = MYSY_GV.dbname['myclass'].count_documents({'external_code':str(class_external_code), 'valide':'1', 'locked':'0', + 'partner_owner_recid':str(partner_recid)}) + + if( myclass_data_count != 1 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : " + str( + n + 2) + ": Le code externe de la formation et le code de la session ne correspondent pas .") + return False, "Ligne : " + str( + n + 2) + ": Le code externe de la formation et le code de la session ne correspondent pas." + + + myclass_data = MYSY_GV.dbname['myclass'].find_one({'external_code':str(class_external_code), 'valide':'1', 'locked':'0', + 'partner_owner_recid':str(partner_recid)}) + + mysession_count_qry = {'class_internal_url': str(myclass_data['internal_url']), 'valide': '1', + 'partner_owner_recid': str(partner_recid), 'code_session':str(df['code_session'].values[n]) } + + + + mysession_count = MYSY_GV.dbname['session_formation'].count_documents(mysession_count_qry) + + if( mysession_count != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : " + str( + n + 2) + ": Le code externe de la formation et le code de la session ne correspondent pas (2).") + return False, "Ligne : " + str( + n + 2) + ": Le code externe de la formation et le code de la session ne correspondent pas (2)." + + mysession_data = MYSY_GV.dbname['session_formation'].find_one(mysession_count_qry) + + + + mydata['session_id'] = str(mysession_data['_id']) + mydata['class_internal_url'] = str(mysession_data['class_internal_url']) + """ + Recuperation de l''_id' de la session à partir de la clé + - formation code externe + - code_session + - partner_owner_recid + """ + + """ + On verifie que le code de le session et le l'external class code correspondent. + En gros : que la formation en question a bien une session du meme code + """ + + + """check_class_session_query = [{'$match': {'code_session':str(df['code_session'].values[n])}}, + {'$lookup': + { + 'from': 'myclass', + 'localField': 'class_internal_url', + 'foreignField': 'internal_url', + 'pipeline': [{'$match': {'external_code':str(df['formation_code_externe'].values[n])}}, + {'$project': {'title': 1, }}], + 'as': 'myclass_collection' + } + } + ] + + print(" ##### myquery GetSessionFormation = " + str(check_class_session_query)) + + real_class_internal_url = "" + + for check_class_session_retval in MYSY_GV.dbname['session_formation'].aggregate(check_class_session_query): + if ('myclass_collection' in check_class_session_retval.keys() and len(check_class_session_retval['myclass_collection']) > 0): + real_class_internal_url = check_class_session_retval['class_internal_url'] + + if( str(real_class_internal_url) == ""): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : " + str( + n+2) + ": Le code externe de la formation et le code de la session ne correspondent pas .") + return False, "Ligne : " + str(n+2) + ": Le code externe de la formation et le code de la session ne correspondent pas." + """ + + modefinancement = "" + if ("modefinancement" in df.keys()): + if (str(df['modefinancement'].values[n])): + modefinancement = str(df['modefinancement'].values[n]).strip() + mydata['modefinancement'] = modefinancement + + + date_naissance = "" + if ("date_naissance" in df.keys()): + if (str(df['date_naissance'].values[n])): + date_naissance = str(df['date_naissance'].values[n]).strip().split(" ")[0] + mydata['date_naissance'] = date_naissance + + + opco = "" + if ("opco" in df.keys()): + if (str(df['opco'].values[n])): + opco = str(df['opco'].values[n]).strip() + mydata['opco'] = opco + + adresse = "" + if ("adresse" in df.keys()): + if (str(df['adresse'].values[n])): + adresse = str(df['adresse'].values[n]).strip() + mydata['adresse'] = adresse + + code_postal = "" + if ("code_postal" in df.keys()): + if (str(df['code_postal'].values[n])): + code_postal = str(df['code_postal'].values[n]).strip() + mydata['code_postal'] = code_postal + + ville = "" + if ("ville" in df.keys()): + if (str(df['ville'].values[n])): + ville = str(df['ville'].values[n]).strip() + mydata['ville'] = ville + + pays = "" + if ("pays" in df.keys()): + if (str(df['pays'].values[n])): + pays = str(df['pays'].values[n]).strip() + mydata['pays'] = pays + + civilite = "" + if ("civilite" in df.keys()): + if (str(df['civilite'].values[n])): + civilite = str(df['civilite'].values[n]).lower() + mydata['civilite'] = str(civilite).lower() + + if (str(civilite).strip() == ""): + mydata['civilite'] = "neutre" + + if (civilite not in MYSY_GV.CIVILITE): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Ligne : " + str( + n + 2) + ". La civilité :" + str( + civilite) + " est invalide. Les valeurs acceptées sont : " + str(MYSY_GV.CIVILITE)) + return False, " Ligne : " + str( + n + 2) + ". La civilité :" + str( + civilite) + " est invalide. Les valeurs acceptées sont : " + str(MYSY_GV.CIVILITE) + + + """" + Gestion du client de rattachement/ + Avec l'email et le nom, on va aller récupérer l'_id du client + """ + has_client_client = "" + client_rattachement_email = "" + if ("client_rattachement_email" in df.keys()): + if (str(df['client_rattachement_email'].values[n]) and str(df['client_rattachement_email'].values[n]) != "nan"): + client_rattachement_email = str(df['client_rattachement_email'].values[n]).strip() + + + client_rattachement_nom = "" + if ("client_rattachement_nom" in df.keys()): + if (str(df['client_rattachement_nom'].values[n]) and str(df['client_rattachement_nom'].values[n]) != "nan" ): + client_rattachement_nom = str(df['client_rattachement_nom'].values[n]).strip() + if (client_rattachement_email and client_rattachement_nom): + local_client_retval_qry = {'email':str(client_rattachement_email), 'nom':str(client_rattachement_nom), + 'valide':'1', 'locked':'0', 'partner_owner_recid' :str(partner_recid)} + print(" ### local_client_retval_qry = ", local_client_retval_qry) + local_client_retval_count = MYSY_GV.dbname['partner_client'].count_documents(local_client_retval_qry) + + if( local_client_retval_count > 1 ): + mycommon.myprint( + str(inspect.stack()[0][3]) +"Ligne : "+str(n+2) +". Plusieurs clients correspondent aux critère de nom :"+str(client_rattachement_nom)+" et email : "+str(client_rattachement_email)) + return False, "Ligne : "+str(n+2) +". Plusieurs clients correspondent aux critère de nom :"+str(client_rattachement_nom)+" et email : "+str(client_rattachement_email) + + if (local_client_retval_count < 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : "+str(n+2) +". Aucun client ne repond aux critères de nom :" + str( + client_rattachement_nom) + " et email : " + str(client_rattachement_email)) + return False, "Ligne : "+str(n+2) +". Aucun client ne repond aux critères de nom :" + str( + client_rattachement_nom) + " et email : " + str(client_rattachement_email) + + local_client_retval_data = MYSY_GV.dbname['partner_client'].find_one(local_client_retval_qry) + + if( local_client_retval_data is not None ): + mydata['client_rattachement_id'] = str(local_client_retval_data['_id']) + has_client_client = str(local_client_retval_data['_id']) + + # Important : : Par defaut, ont que le client de facturation = au client principale. comme ca + # Si il y un client de facturation plus bas, on l'ecrase + mydata['facture_client_rattachement_id'] = str(local_client_retval_data['_id']) + + """" + Gestion du client dà facturer/ + Avec l'email et le nom, on va aller récupérer l'_id du client + + + """ + has_client_facture = "" + facture_client_rattachement_email = "" + if ("facture_client_rattachement_email" in df.keys()): + if (str(df['facture_client_rattachement_email'].values[n]) and str( + df['facture_client_rattachement_email'].values[n]) != "nan"): + facture_client_rattachement_email = str(df['facture_client_rattachement_email'].values[n]).strip() + + facture_client_rattachement_nom = "" + if ("facture_client_rattachement_nom" in df.keys()): + if (str(df['facture_client_rattachement_nom'].values[n]) and str( + df['facture_client_rattachement_nom'].values[n]) != "nan"): + facture_client_rattachement_nom = str(df['facture_client_rattachement_nom'].values[n]).strip() + + if (facture_client_rattachement_email and facture_client_rattachement_nom): + local_client_retval_qry = {'email': str(facture_client_rattachement_email), 'nom': str(facture_client_rattachement_nom), + 'valide': '1', 'locked': '0', 'partner_owner_recid': str(partner_recid)} + + print(" ### local_client_retval_qry = ", local_client_retval_qry) + local_client_retval_count = MYSY_GV.dbname['partner_client'].count_documents(local_client_retval_qry) + + if (local_client_retval_count > 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : " + str( + n + 2) + ". Plusieurs entités de facturation correspondent aux critères de nom :" + str( + facture_client_rattachement_nom) + " et email : " + str(facture_client_rattachement_email)) + return False, "Ligne : " + str( + n + 2) + ". Plusieurs entités de facturation correspondent aux critères de nom :" + str( + facture_client_rattachement_nom) + " et email : " + str(facture_client_rattachement_email) + + if (local_client_retval_count < 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : " + str( + n + 2) + ". Aucune entité de facturation ne repond aux critères de nom :" + str( + facture_client_rattachement_nom) + " et email : " + str(facture_client_rattachement_email)) + return False, "Ligne : " + str(n + 2) + ". Aucune entité de facturation ne repond aux critères de nom :" + str( + facture_client_rattachement_nom) + " et email : " + str(facture_client_rattachement_email) + + local_client_retval_data = MYSY_GV.dbname['partner_client'].find_one(local_client_retval_qry) + if (local_client_retval_data is not None): + mydata['facture_client_rattachement_id'] = str(local_client_retval_data['_id']) + has_client_facture = str(local_client_retval_data['_id']) + + """ + 11/07/2024 - Important : Si je n'ai pas de client facturé mais que j'ai un client (classique), + alors on fait : client_facturé = client_normal + """ + if( len(str(has_client_facture).strip()) <= 1 and len(str(has_client_client).strip()) > 3 ): + mydata['facture_client_rattachement_id'] = str(has_client_client) + + + """ + 11/07/2024 - Important : Si j'ai un client facturé, mais pas un client normal, alors on fait : + client_client = client_facture + """ + if (len(str(has_client_client).strip()) <= 1 and len(str(has_client_facture).strip()) > 3): + mydata['client_rattachement_id'] = str(has_client_facture) + + + mydata['status'] = str(df['status'].values[n]).strip() + mydata['status'] = str(mycommon.tryInt(mydata['status'])) + + #print(" mydata['status'] = ", mydata['status']) + if( str(mydata['status']) != "0" and str(mydata['status']) != "1" and str(mydata['status']) != "2"): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'status' de la ligne " + str(n) + " est incorrecte. Valeurs acceptées : 0,1,2") + return False, " Le champ status de la ligne " + str(n) + " est incorrecte. Valeurs acceptées : 0,1,2" + + + if( str(df['status'].values[n]).strip() == "1"): + mydata['inscription_validation_date'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + + + local_price = str(df['prix'].values[n]).strip() + local_status, new_price = mycommon.IsFloat(local_price) + if( local_status is False ): + mycommon.myprint( + str(inspect.stack()[0][ 3]) + " Le champ 'prix' de la ligne " + str(n+2) + " est incorrecte.") + return False, " Le champ prix de la ligne " + str(n+2) + " est incorrecte. " + + mydata['price'] = local_price + + type_apprenant = "0" + if ("type_apprenant" in df.keys()): + if (str(df['type_apprenant'].values[n])): + type_apprenant = str(df['type_apprenant'].values[n]).strip() + type_apprenant = str(mycommon.tryInt(type_apprenant)) + + if( type_apprenant not in MYSY_GV.INSCRIPTION_TYPE_APPRENANT): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : " + str( + n + 2) + ". Le type apprenant doit etre l'une des valeurs suivantes :" + str( + MYSY_GV.INSCRIPTION_TYPE_APPRENANT) ) + return False, "Ligne : " + str( + n + 2) + ". Le type apprenant doit etre l'une des valeurs suivantes :" + str( + MYSY_GV.INSCRIPTION_TYPE_APPRENANT) + + mydata['type_apprenant'] = type_apprenant + + + clean_dict = {k: mydata[k] for k in mydata if ( str(mydata[k]) != "nan") } + + #print( "#### clean_dict tt 01 ", clean_dict) + status, retval = AddStagiairetoClass(clean_dict) + + if( status is False ): + return status, retval + + print(str(total_rows)+" participants ont été inserés") + + return True, str(total_rows)+" participants ont été inserées / Mises à 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 d'importer les participants en masse " + + + +""" +Fonction de controle du fichier +""" +def Controle_AddStagiairetoClass_mass_for_many_session(saved_file=None, Folder=None, diction=None): + try: + diction = mycommon.strip_dictionary(diction) + ''' + # 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','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, Creation participants annulée") + return False, " Verifier votre API" + + ''' + 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, " Verifier votre API, Toutes les informations techniques ne sont pas fournies" + + 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 "Err_Connexion", " La session de connexion n'est pas valide" + + + + partner_recid = mycommon.get_parnter_recid_from_token(my_token) + if (partner_recid is False): + mycommon.myprint(str(inspect.stack()[0][3]) + " - partner_recid KO : Impossible d'importer la liste des participants ") + return False, " Les information de connexion sont incorrectes. Impossible d'importer la liste des participants" + + + + df = pd.read_csv(saved_file, encoding='utf8', on_bad_lines='skip', sep=';', encoding_errors='ignore', skipinitialspace=True) + df = df.fillna('') + df = df.applymap(lambda x: x.strip() if isinstance(x, str) else x) + + + # Dictionnaire des champs utilisables + ''' + # Verification que les noms des colonne sont bien corrects" + ''' + field_list = ['formation_code_externe', 'code_session', 'prenom', 'nom', 'employeur', + 'telephone', 'email', 'modefinancement', 'opco', 'status', 'prix', 'adresse', 'code_postal', + 'ville', 'pays', 'client_rattachement_email', 'client_rattachement_nom', + 'facture_client_rattachement_email', 'facture_client_rattachement_nom', 'civilite', 'type_apprenant', + 'date_naissance', 'mode_financement_code', 'type_apprenant_code'] + + + # Controle du nombre de lignes dans le fichier. + total_rows = len(df) + if( total_rows > MYSY_GV.MAX_PARTICIPANT_BY_CSV ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le fichier comporte plus de "+str(MYSY_GV.MAX_PARTICIPANT_BY_CSV)+" lignes.") + return False, " Le fichier comporte plus de "+str(MYSY_GV.MAX_PARTICIPANT_BY_CSV)+" lignes." + + + #print(" ### df.columns = ", df.columns) + for val in df.columns: + #print(" ### val = ", val) + if str(val).lower() not in field_list: + mycommon.myprint( + str(inspect.stack()[0][3])+" : entete du fichier csv. '" + val + "' n'est pas acceptée") + return False, " Entete du fichier csv. La Colonne '" + val + "' n'est pas acceptée" + + + # Verification des champs obligatoires dans le fichier + field_list_obligatoire_file = ['prenom', 'nom', 'email', 'status', 'prix'] + + for val in field_list_obligatoire_file: + if val not in df.columns: + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " : Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire") + return False, " Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire " + + + + """ + # Recuperation des info de la session. + session_data = MYSY_GV.dbname['session_formation'].find_one({'formation_session_id':str(session_id)}) + if( session_data is None ): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La session de formation n'existe pas : Impossible d'importer la liste des participants ") + return False, "la session de formation n'existe pas. Impossible d'importer la liste des participants" + + #print(" #### session_data = ",session_data) + """ + + x = range(0, total_rows) + cpt_valide_row = 0 + for n in x: + if( str(df['prenom'].values[n]) and str(df['nom'].values[n]) and str(df['email'].values[n]) ) : + mydata = {} + class_external_code = str(df['formation_code_externe'].values[n]) + #mydata['code_session'] = str(df['code_session'].values[n]) + mydata['prenom'] = str(df['prenom'].values[n]) + mydata['nom'] = str(df['nom'].values[n]) + if (len(str(mydata['nom']).strip()) < 2): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'nom' de la ligne " + str( + n + 2) + " doit faire plus de deux caractères.") + return False, " Le champ nom de la ligne " + str( + n + 2) + " doit faire plus de deux caractères. " + + + mydata['employeur'] = str(df['employeur'].values[n]) + mydata['telephone'] = str(df['telephone'].values[n]) + mydata['email'] = str(df['email'].values[n]).strip().lower() + #print(" contole du mail = ", mydata['email']) + regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b' + if (not re.fullmatch(regex, str( mydata['email']) )): + mycommon.myprint( + str(inspect.stack()[0][3]) + " l'adresse email " + str(mydata['email']) + " est invalide") + return False, " l'adresse email -" + str(mydata['email']) + "- est invalide" + + mydata['token'] = str(my_token) + + """ + Recuperation de l'internal url de la formation a partir de la cle + - formation code externe + - partner_owner_recid + """ + qry = {'external_code':str(class_external_code), 'valide':'1', 'locked':'0', 'partner_owner_recid':str(partner_recid)} + + myclass_data_count = MYSY_GV.dbname['myclass'].count_documents(qry) + #print(" ### myclass_data_count = ", myclass_data_count) + + if( myclass_data_count != 1 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : " + str( + n + 2) + ": Le code externe de la formation et le code de la session ne correspondent pas .") + return False, "Ligne : " + str( + n + 2) + ": Le code externe de la formation et le code de la session ne correspondent pas." + + + myclass_data = MYSY_GV.dbname['myclass'].find_one({'external_code':str(class_external_code), 'valide':'1', 'locked':'0', + 'partner_owner_recid':str(partner_recid)}) + + mysession_count_qry = {'class_internal_url': str(myclass_data['internal_url']), 'valide': '1', + 'partner_owner_recid': str(partner_recid), 'code_session':str(df['code_session'].values[n]) } + + #print(" ### mysession_count_qry = ", mysession_count_qry) + + mysession_count = MYSY_GV.dbname['session_formation'].count_documents(mysession_count_qry) + + if( mysession_count != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : " + str( + n + 2) + ": Le code externe de la formation et le code de la session ne correspondent pas (2).") + return False, "Ligne : " + str( + n + 2) + ": Le code externe de la formation et le code de la session ne correspondent pas (2)." + + mysession_data = MYSY_GV.dbname['session_formation'].find_one(mysession_count_qry) + + if ("date_naissance" in df.keys()): + mydata['date_naissance'] = str(df['date_naissance'].values[n]).strip().split(" ")[0] + if( mydata['date_naissance'] ) : + local_status = mycommon.CheckisDate(mydata['date_naissance']) + if (local_status is False): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La date de naissance à ligne " + str( + n + 2) + " n'est pas au format 'jj/mm/aaaa' .") + + return False, " La date de naissance à ligne " + str(n + 2) + " n'est pas au format 'jj/mm/aaaa' " + + mydata['session_id'] = str(mysession_data['_id']) + mydata['class_internal_url'] = str(mysession_data['class_internal_url']) + + """ + Recuperation de l''_id' de la session à partir de la clé + - formation code externe + - code_session + - partner_owner_recid + """ + + """ + On verifie que le code de le session et le l'external class code correspondent. + En gros : que la formation en question a bien une session du meme code + """ + + modefinancement = "" + if ("modefinancement" in df.keys()): + if (str(df['modefinancement'].values[n])): + modefinancement = str(df['modefinancement'].values[n]) + mydata['modefinancement'] = modefinancement + + + opco = "" + if ("opco" in df.keys()): + if (str(df['opco'].values[n])): + opco = str(df['opco'].values[n]) + mydata['opco'] = opco + + adresse = "" + if ("adresse" in df.keys()): + if (str(df['adresse'].values[n])): + adresse = str(df['adresse'].values[n]) + mydata['adresse'] = adresse + + code_postal = "" + if ("code_postal" in df.keys()): + if (str(df['code_postal'].values[n])): + code_postal = str(df['code_postal'].values[n]) + mydata['code_postal'] = code_postal + + ville = "" + if ("ville" in df.keys()): + if (str(df['ville'].values[n])): + ville = str(df['ville'].values[n]) + mydata['ville'] = ville + + pays = "" + if ("pays" in df.keys()): + if (str(df['pays'].values[n])): + pays = str(df['pays'].values[n]) + mydata['pays'] = pays + + civilite = "" + if ("civilite" in df.keys()): + if (str(df['civilite'].values[n])): + civilite = str(df['civilite'].values[n]).lower() + mydata['civilite'] = str(civilite).lower() + + if( str(civilite).strip() == ""): + mydata['civilite'] = "neutre" + + if( civilite not in MYSY_GV.CIVILITE): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Ligne : " + str( + n + 2) + ". La civilité :" + str( + civilite) + " est invalide. Les valeurs acceptées sont : "+str(MYSY_GV.CIVILITE)) + return False, " Ligne : " + str( + n + 2) + ". La civilité :" + str( + civilite) + " est invalide. Les valeurs acceptées sont : "+str(MYSY_GV.CIVILITE) + + """" + Gestion du client de rattachement/ + Avec l'email et le nom, on va aller récupérer l'_id du client + """ + client_rattachement_email = "" + if ("client_rattachement_email" in df.keys()): + if (str(df['client_rattachement_email'].values[n]) and str(df['client_rattachement_email'].values[n]) != "nan"): + client_rattachement_email = str(df['client_rattachement_email'].values[n]).strip() + + + client_rattachement_nom = "" + if ("client_rattachement_nom" in df.keys()): + if (str(df['client_rattachement_nom'].values[n]) and str(df['client_rattachement_nom'].values[n]) != "nan" ): + client_rattachement_nom = str(df['client_rattachement_nom'].values[n]).strip() + if (client_rattachement_email and client_rattachement_nom): + local_client_retval_qry = {'email':str(client_rattachement_email), 'nom':str(client_rattachement_nom), + 'valide':'1', 'locked':'0', 'partner_owner_recid' :str(partner_recid)} + + print(" ### local_client_retval_qry = ", local_client_retval_qry) + local_client_retval_count = MYSY_GV.dbname['partner_client'].count_documents(local_client_retval_qry) + + if( local_client_retval_count > 1 ): + mycommon.myprint( + str(inspect.stack()[0][3]) +"Ligne : "+str(n+2) +". Plusieurs clients correspondent aux critère de nom :"+str(client_rattachement_nom)+" et email : "+str(client_rattachement_email)) + return False, "Ligne : "+str(n+2) +". Plusieurs clients correspondent aux critère de nom :"+str(client_rattachement_nom)+" et email : "+str(client_rattachement_email) + + if (local_client_retval_count < 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : "+str(n+2) +". Aucun client ne repond aux critères de nom :" + str( + client_rattachement_nom) + " et email : " + str(client_rattachement_email)) + return False, "Ligne : "+str(n+2) +". Aucun client ne repond aux critères de nom :" + str( + client_rattachement_nom) + " et email : " + str(client_rattachement_email) + + local_client_retval_data = MYSY_GV.dbname['partner_client'].find_one(local_client_retval_qry) + if( local_client_retval_data is not None ): + mydata['client_rattachement_id'] = str(local_client_retval_data['_id']) + + """" + Gestion du client dà facturer/ + Avec l'email et le nom, on va aller récupérer l'_id du client + """ + facture_client_rattachement_email = "" + if ("facture_client_rattachement_email" in df.keys()): + if (str(df['facture_client_rattachement_email'].values[n]) and str( + df['facture_client_rattachement_email'].values[n]) != "nan"): + facture_client_rattachement_email = str(df['facture_client_rattachement_email'].values[n]).strip() + + facture_client_rattachement_nom = "" + if ("facture_client_rattachement_nom" in df.keys()): + if (str(df['facture_client_rattachement_nom'].values[n]) and str( + df['facture_client_rattachement_nom'].values[n]) != "nan"): + facture_client_rattachement_nom = str(df['facture_client_rattachement_nom'].values[n]).strip() + + if (facture_client_rattachement_email and facture_client_rattachement_nom): + local_client_retval_qry = {'email': str(facture_client_rattachement_email), + 'nom': str(facture_client_rattachement_nom), + 'valide': '1', 'locked': '0', 'partner_owner_recid': str(partner_recid)} + + print(" ### local_client_retval_qry = ", local_client_retval_qry) + local_client_retval_count = MYSY_GV.dbname['partner_client'].count_documents(local_client_retval_qry) + + if (local_client_retval_count > 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : " + str( + n + 2) + ". Plusieurs entités de facturation correspondent aux critères de nom :" + str( + facture_client_rattachement_nom) + " et email : " + str(facture_client_rattachement_email)) + return False, "Ligne : " + str( + n + 2) + ". Plusieurs entités de facturation correspondent aux critères de nom :" + str( + facture_client_rattachement_nom) + " et email : " + str(facture_client_rattachement_email) + + if (local_client_retval_count < 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : " + str( + n + 2) + ". Aucune entité de facturation ne repond aux critères de nom :" + str( + facture_client_rattachement_nom) + " et email : " + str(facture_client_rattachement_email)) + return False, "Ligne : " + str( + n + 2) + ". Aucune entité de facturation ne repond aux critères de nom :" + str( + facture_client_rattachement_nom) + " et email : " + str(facture_client_rattachement_email) + + local_client_retval_data = MYSY_GV.dbname['partner_client'].find_one(local_client_retval_qry) + if (local_client_retval_data is not None): + mydata['facture_client_rattachement_id'] = str(local_client_retval_data['_id']) + + + mydata['status'] = str(df['status'].values[n]).strip() + mystatus = mycommon.tryInt(str(mydata['status'])) + + + if( str(mystatus) != "0" and str(mystatus) != "1" and str(mystatus) != "2"): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champ 'status' de la ligne " + str(n) + " est incorrecte. Valeurs acceptées : 0,1,2") + return False, " Le champ status de la ligne " + str(n) + " est incorrecte. Valeurs acceptées : 0,1,2" + + + if( str(mystatus).strip() == "1"): + mydata['inscription_validation_date'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + + local_price = str(df['prix'].values[n]).strip() + local_status, new_price = mycommon.IsFloat(local_price) + if( local_status is False ): + mycommon.myprint( + str(inspect.stack()[0][ 3]) + " Le champ 'prix' de la ligne " + str( n+2) + " est incorrecte.") + return False, " Le champ prix de la ligne " + str(n+2) + " est incorrecte. " + + mydata['price'] = local_price + + type_apprenant = "0" + if ("type_apprenant" in df.keys()): + if (str(df['type_apprenant'].values[n])): + type_apprenant = str(df['type_apprenant'].values[n]).strip() + type_apprenant = str(mycommon.tryInt(type_apprenant)) + + if (type_apprenant not in MYSY_GV.INSCRIPTION_TYPE_APPRENANT): + mycommon.myprint( + str(inspect.stack()[0][3]) + "Ligne : " + str( + n + 2) + ". Le type apprenant doit etre l'une des valeurs suivantes :" + str( + MYSY_GV.INSCRIPTION_TYPE_APPRENANT)) + return False, "Ligne : " + str( + n + 2) + ". Le type apprenant doit etre l'une des valeurs suivantes :" + str( + MYSY_GV.INSCRIPTION_TYPE_APPRENANT) + + mydata['type_apprenant'] = type_apprenant + + cpt_valide_row = cpt_valide_row + 1 + + + clean_dict = {k: mydata[k] for k in mydata if ( str(mydata[k]) != "nan") } + + #print( "#### clean_dict ", clean_dict) + + + return True, str(cpt_valide_row)+" participants dans le fichier" + + 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 controler le fichier des participants a importer en masse " + + + + +""" +Cette fonction permet d'imprimer/telecharger la fichier d'un inscrit à une session. +Cette fonction va utiliser un template pour imprimer le modele +""" +def PrintAttendeeDetail_perSession(diction): + try: + field_list_obligatoire = ['session_id', 'token', 'attendee_email', 'internal_url'] + + 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 d'imprimer la fiche detaillée" + + my_token = "" + if ("token" in diction.keys()): + if diction['token']: + my_token = diction['token'] + + internal_url = "" + if ("internal_url" in diction.keys()): + if diction['internal_url']: + internal_url = diction['internal_url'] + + + # Recuperation du recid du partenaire + partner_recid = mycommon.get_parnter_recid_from_token(str(my_token)) + if partner_recid is False: + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible d'imprimer la fiche detaillée") + return False, " Les informations d'identification sont invalides" + + local_status, my_partner_data = mycommon.Check_Connexion_And_Return_Partner_Data(diction) + if (local_status is not True): + return local_status, my_partner_data + + + RetObject = [] + # Recuperation des infos de la l'inscription + qry = {'session_id': str(diction['session_id']),'email': str(diction['attendee_email']), + 'class_internal_url':str(diction['internal_url'])} + + + + local_Insc_retval = MYSY_GV.dbname['inscription'].find_one({'session_id': str(diction['session_id']), + 'email': str(diction['attendee_email']), + 'class_internal_url':str(diction['internal_url'])}) + my_retrun_dict = {} + + my_retrun_dict['session_id'] = local_Insc_retval['session_id'] + + + date_du = "" + if ("date_du" in local_Insc_retval.keys()): + if local_Insc_retval['date_du']: + date_du = local_Insc_retval['date_du'] + my_retrun_dict['date_du'] = str(date_du)[0:10] + + date_au = "" + if ("date_au" in local_Insc_retval.keys()): + if local_Insc_retval['date_au']: + date_au = local_Insc_retval['date_au'] + my_retrun_dict['date_au'] = str(date_au)[0:10] + + ville = "" + if ("ville" in local_Insc_retval.keys()): + if local_Insc_retval['ville']: + code_postal = local_Insc_retval['ville'] + my_retrun_dict['ville'] = ville + + code_postal = "" + if ("code_postal" in local_Insc_retval.keys()): + if local_Insc_retval['code_postal']: + code_postal = local_Insc_retval['code_postal'] + my_retrun_dict['code_postal'] = code_postal + + + my_adresse = "" + if ("adresse" in local_Insc_retval.keys()): + if local_Insc_retval['adresse']: + my_adresse = local_Insc_retval['adresse'] + my_retrun_dict['adresse'] = my_adresse + + my_nom = "" + if ("nom" in local_Insc_retval.keys()): + if local_Insc_retval['nom']: + my_adresse = local_Insc_retval['nom'] + my_retrun_dict['nom'] = my_nom + + my_prenom = "" + if ("prenom" in local_Insc_retval.keys()): + if local_Insc_retval['prenom']: + my_prenom = local_Insc_retval['prenom'] + my_retrun_dict['prenom'] = my_prenom + + my_employeur = "" + if ("employeur" in local_Insc_retval.keys()): + if local_Insc_retval['employeur']: + my_employeur = local_Insc_retval['employeur'] + my_retrun_dict['employeur'] = my_employeur + + my_telephone = "" + if ("telephone" in local_Insc_retval.keys()): + if local_Insc_retval['telephone']: + my_telephone = local_Insc_retval['telephone'] + my_retrun_dict['telephone'] = my_telephone + + my_email = "" + if ("email" in local_Insc_retval.keys()): + if local_Insc_retval['email']: + my_email = local_Insc_retval['email'] + my_retrun_dict['email'] = my_email + + my_modefinancement = "" + if ("modefinancement" in local_Insc_retval.keys()): + if local_Insc_retval['modefinancement']: + my_modefinancement = local_Insc_retval['modefinancement'] + my_retrun_dict['modefinancement'] = my_modefinancement + + my_opco = "" + if ("opco" in local_Insc_retval.keys()): + if local_Insc_retval['opco']: + my_opco = local_Insc_retval['opco'] + my_retrun_dict['opco'] = my_opco + + my_class_internal_url = "" + if ("class_internal_url" in local_Insc_retval.keys()): + if local_Insc_retval['class_internal_url']: + my_class_internal_url = local_Insc_retval['class_internal_url'] + my_retrun_dict['class_internal_url'] = my_class_internal_url + + my_status = "" + if ("status" in local_Insc_retval.keys()): + if local_Insc_retval['status']: + my_status = local_Insc_retval['status'] + my_retrun_dict['status'] = my_status + + my_price = "" + if ("price" in local_Insc_retval.keys()): + if local_Insc_retval['price']: + my_price = local_Insc_retval['price'] + my_retrun_dict['price'] = my_price + + + if ("inscription_validation_date" in local_Insc_retval.keys()): + my_retrun_dict['inscription_validation_date'] = local_Insc_retval['inscription_validation_date'] + + if ("eval_eval" in local_Insc_retval.keys()): + my_retrun_dict['evaluation'] = local_Insc_retval['eval_eval'] + + if ("eval_note" in local_Insc_retval.keys()): + my_retrun_dict['note_eval'] = local_Insc_retval['eval_note'] + + if ("eval_date" in local_Insc_retval.keys()): + my_retrun_dict['date_eval'] = str(local_Insc_retval['eval_date'])[0:10] + + v = local_Insc_retval['_id'].generation_time + my_retrun_dict['creation_date'] = str(v.strftime("%d/%m/%Y")) + + my_retrun_dict['date_impression'] = str(datetime.today().strftime("%d/%m/%Y")) + + # Recuperation des infotrmations de la formation + local_formation = MYSY_GV.dbname['myclass'].find_one( + {'internal_url': str(local_Insc_retval['class_internal_url']), + 'partner_owner_recid':str(partner_recid)}) + + my_local_title = "" + if ("title" in local_formation.keys()): + if local_formation['title']: + my_retrun_dict['class_title'] = local_formation['title'] + my_local_title = local_formation['title'] + + + + local_query = {'_id':ObjectId(str(local_Insc_retval['session_id'])), 'valide':'1', + 'partner_owner_recid':str(partner_recid)} + + print(" ### local_query = ", local_query) + + # Recuperation du formation depuis la collection "session_formation" + tmp_val = MYSY_GV.dbname['session_formation'].find_one(local_query) + if( tmp_val is None): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " Impossible d'imprimer la fiche detaillée : code session erronée ") + return False, " Impossible d'imprimer la fiche detaillée : code session erronée " + + my_trainer = "" + if ("formateur_id" in tmp_val.keys()): + if tmp_val['formateur_id']: + + formateur_data = MYSY_GV.dbname['ressource_humaine'].find_one( + {'_id': ObjectId(str(tmp_val['formateur_id'])), + 'valide': '1', + 'locked': '1', + 'partner_recid': str(partner_recid)}) + + if (formateur_data and "nom" in formateur_data.keys() and "prenom" in formateur_data.keys()): + formateur = str(formateur_data['nom']) + " " + str(formateur_data['prenom']) + + + my_trainer = formateur + my_retrun_dict['formateur_id'] = tmp_val['formateur_id'] + + if (my_trainer == ""): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " Impossible d'imprimer la fiche detaillée : Aucun formateur designé pour la session") + return False, " Impossible d'imprimer la fiche detaillée : Aucun formateur designé pour la session" + + + if ("distantiel" in tmp_val.keys()): + if tmp_val['distantiel']: + my_retrun_dict['distantiel'] = tmp_val['distantiel'] + + if ("presentiel" in tmp_val.keys()): + if tmp_val['presentiel']: + my_retrun_dict['presentiel'] = tmp_val['presentiel'] + + my_partner = "" + if ("institut_formation" in local_formation.keys()): + if local_formation['institut_formation']: + my_partner = local_formation['institut_formation'] + my_retrun_dict['partner'] = my_partner + + my_img_url = "" + if ("img_url" in local_formation.keys()): + if local_formation['img_url']: + my_img_url = local_formation['img_url'] + my_retrun_dict['img_url'] = my_img_url + + + + ############################## + # Recuperation des fiches de presence + tab_presences = [] + for val_tmp in MYSY_GV.dbname['emargement'].find({'session_id':str(local_Insc_retval['session_id']), + 'email':str(local_Insc_retval['email'])}).sort([("date", pymongo.ASCENDING)]): + local_tmp = {} + local_tmp['email'] = val_tmp['email'] + local_tmp['matin'] = val_tmp['matin'] + local_tmp['apresmidi'] = val_tmp['apresmidi'] + local_tmp['date'] = val_tmp['date'] + + tab_presences.append(local_tmp) + + + # Recuperation image logo du partenaire en base de donnée + qery_images = {'locked': '0', 'valide': '1', 'related_collection': 'partnair_account', + 'related_collection_recid': str(my_partner_data['recid']), 'type_img':'logo'} + + + partner_media_logo = MYSY_GV.dbname['mysy_images'].find_one(qery_images) + + is_partner_logo = True + is_partner_logo_img = "" + if( partner_media_logo is None or "img" not in partner_media_logo.keys()): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La partner n'a pas de logo, le logo par defaut sera utilisé") + + is_partner_logo = False + else: + is_partner_logo_img = "data:image/png;base64," + str(partner_media_logo['img']) + + if( is_partner_logo is False ): + # récupérer l'image logo par default + default_qery_images = {'locked': '0', 'valide': '1', 'related_collection': 'partnair_account', 'type_img': 'logo_default'} + partner_media_logo = MYSY_GV.dbname['mysy_images'].find_one(default_qery_images) + + is_partner_logo_img = "data:image/png;base64," + str(partner_media_logo['img']) + + + my_retrun_dict['default_logo_partner'] = is_partner_logo_img + + #print(" ### my_retrun_dict =",my_retrun_dict) + + templateLoader = jinja2.FileSystemLoader(searchpath="./") + templateEnv = jinja2.Environment(loader=templateLoader) + TEMPLATE_FILE = "Template/fiche_detail_stagiaire_tpl.html" + template = templateEnv.get_template(TEMPLATE_FILE) + # This data can come from database query + body = { + "data": my_retrun_dict, + "presences": tab_presences + } + + # print(" ### body = " + str(body)) + + sourceHtml = template.render(json_data=body["data"], presences=body["presences"]) + mycode = str(datetime.now().timestamp()).replace(".", '').replace(',', '') + orig_file_name = "fichier_personnel_"+str(mycode)[:-3]+"pdf" + outputFilename = str(MYSY_GV.EMARGEMENT_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() + + # print(" ### outputFilename = "+str(outputFilename)) + if os.path.exists(outputFilename): + # print(" ### ok os.path.exists(outputFilename) "+str(outputFilename)) + return True, send_file(outputFilename, as_attachment=True) + + # return True on success and False on errors + print(pisaStatus.err, type(pisaStatus.err)) + + return True, " le fichier generé " + + + except Exception as e: + 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 d'imprimer la fiche detaillée" + + + + +""" Creation d'un evaluation sur une formation +Les infos d'evaluation sont rattachées à la collection inscription. + +eval_date : +eval_note : +eval_eval : +eval_pedagogie : + +""" +def Evaluation_Class(diction): + try: + + field_list_obligatoire = ['inscription_id', 'eval_note', 'eval_eval', 'eval_pedagogie', 'class_internal_url'] + 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" + + + + note = str(diction['eval_note']).strip() + if( mycommon.IsFloat( note ) is False ): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La note d'evaluation est incorrecte ") + return False, " La note d'evaluation est incorrecte " + + mydata = {} + mydata['eval_date'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + mydata['eval_note'] = str(diction['eval_note']).strip() + mydata['eval_status'] = "1" + mydata['eval_eval'] = str(diction['eval_eval']).strip() + mydata['eval_pedagogie'] = str(diction['eval_pedagogie']).strip() + + ret_val = MYSY_GV.dbname['inscription'].find_one_and_update({'_id': ObjectId(str(str(diction['inscription_id']).strip())),}, + {"$set": mydata}, + upsert=False, + return_document=ReturnDocument.AFTER + ) + + if ret_val is None or ret_val['_id'] is None: + mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible d'enregistrer l'evaluation ") + return False, " Impossible d'enregistrer l'evaluation " + + + # Declencer l'envoi de la notification de l'evaluation + email_mgt.EmailNotifEvaluation_Done(diction) + + """ + # Ajout de l'evenement dans l'historique + """ + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + history_event_dict = {} + history_event_dict['token'] = "" + history_event_dict['related_collection'] = "inscription" + history_event_dict['related_collection_recid'] = str(diction['inscription_id']) + history_event_dict['action_date'] = str(now) + history_event_dict['action_description'] = " Evaluation Formation " + 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, " L'evaluation a bien été enregistrée" + + except Exception as e: + 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 créer l'evaluation" + +""" +Cette fonction verifie si un token d'evaluation est valide. + +Un token est valide si : +token = ObjectId existe +internal_url et le objectId sont coherents (meme ligne dans la collection) +L'evaluation n'a pas deja ete faite. + +""" +def MySyckeckEvaluationToken(diction): + try: + field_list_obligatoire = ['eval_token', 'class_internal_url'] + 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" + + eval_token = "" + if ("eval_token" in diction.keys()): + if diction['eval_token']: + eval_token = diction['eval_token'] + + internal_url = "" + if ("class_internal_url" in diction.keys()): + if diction['class_internal_url']: + internal_url = diction['class_internal_url'] + + #local_qry = {'class_internal_url':internal_url, '_id': ObjectId(eval_token), "eval_date":{"$exists":False} } + + #print(" ### local_qry =",local_qry) + tmp_count = MYSY_GV.dbname['inscription'].count_documents({'class_internal_url':internal_url, + '_id': ObjectId(eval_token), "eval_date":{"$exists":False} } ) + + if (tmp_count != 1): + mycommon.myprint(str(inspect.stack()[0][3]) + " "+str(tmp_count)+" est different de 1. impossible de faire l'evaluation") + return False, " Impossible de faire l'evaluation. Verifier les informations fournies" + + + return True, "Ok" + + except Exception as e: + 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 verifier la validé du token" + + +""" +Cette fonction envoie l'email de demande d'evaluation +""" +def SendTrainingEvaluationEmail(diction): + try: + field_list_obligatoire = ['session_id', 'token', 'attendee_email', 'class_internal_url'] + + 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" + + 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 + + + # Recuperation du recid du partenaire + partner_recid = str(my_partner['recid']) + + + # Verifier qui la formation n'a pas deja été evaluée + tmp_count = MYSY_GV.dbname['inscription'].count_documents({'session_id': str(diction['session_id']), + 'email': str(diction['attendee_email']), + 'class_internal_url': str(diction['class_internal_url'],), + 'partner_owner_recid': str(partner_recid), + "eval_date": {"$exists": True}}) + + if (tmp_count > 0): + mycommon.myprint(str(inspect.stack()[0][3]) + " Cette formation a déjà été évaluée") + return False, " Cette formation a déjà été évaluée" + + + RetObject = [] + # Recuperation des infos de la formation + qry = {'session_id': str(diction['session_id']), + 'email': str(diction['attendee_email']), + 'class_internal_url': str(diction['class_internal_url']), + 'partner_owner_recid': str(partner_recid), + } + + + local_Insc_retval = MYSY_GV.dbname['inscription'].find_one({'session_id': str(diction['session_id']), + 'email': str(diction['attendee_email']), + 'class_internal_url': str(diction['class_internal_url']), + 'partner_owner_recid': str(partner_recid), + }) + + my_retrun_dict = {} + + print(' ##### local_Insc_retval = ', local_Insc_retval) + + my_retrun_dict['token_eval'] = local_Insc_retval['_id'] + if( "date_du" in local_Insc_retval.keys() ): + my_retrun_dict['date_du'] = str(local_Insc_retval['date_du'])[1:10] + else: + my_retrun_dict['date_du'] = "" + + if ("date_au" in local_Insc_retval.keys() ): + my_retrun_dict['date_au'] = str(local_Insc_retval['date_au'])[0:10] + else: + my_retrun_dict['date_au'] = "" + + my_retrun_dict['session_id'] = str(local_Insc_retval['_id']) + + ville = "" + if ("ville" in local_Insc_retval.keys() and local_Insc_retval['ville']): + ville = local_Insc_retval['ville'] + my_retrun_dict['ville'] = ville + + code_postal = "" + if ("code_postal" in local_Insc_retval.keys() and local_Insc_retval['code_postal']): + code_postal = local_Insc_retval['code_postal'] + my_retrun_dict['code_postal'] = code_postal + + internal_url = "" + if ("class_internal_url" in local_Insc_retval.keys() and local_Insc_retval['class_internal_url']): + internal_url = local_Insc_retval['class_internal_url'] + my_retrun_dict['internal_url'] = internal_url + + + + adresse = "" + if ("adresse" in local_Insc_retval.keys() and local_Insc_retval['adresse']): + adresse = local_Insc_retval['adresse'] + my_retrun_dict['adresse'] = adresse + + nom = "" + if ("nom" in local_Insc_retval.keys() and local_Insc_retval['nom']): + nom = local_Insc_retval['nom'] + my_retrun_dict['nom'] = nom + + prenom = "" + if ("prenom" in local_Insc_retval.keys() and local_Insc_retval['prenom']): + prenom = local_Insc_retval['prenom'] + my_retrun_dict['prenom'] = prenom + + employeur = "" + if ("employeur" in local_Insc_retval.keys() and local_Insc_retval['employeur']): + employeur = local_Insc_retval['employeur'] + my_retrun_dict['employeur'] = employeur + + telephone = "" + if ("telephone" in local_Insc_retval.keys() and local_Insc_retval['telephone']): + telephone = local_Insc_retval['telephone'] + my_retrun_dict['telephone'] = telephone + + + my_retrun_dict['email'] = local_Insc_retval['email'] + + # Recuperation des infotrmations de la formation + print(" ### str(local_Insc_retval['class_internal_url']) = ",str(local_Insc_retval['class_internal_url']) ) + local_formation = MYSY_GV.dbname['myclass'].find_one( + {'internal_url': str(local_Insc_retval['class_internal_url'])}) + my_retrun_dict['title'] = local_formation['title'] + + # Recuperation des info de session + local_session_info = MYSY_GV.dbname['session_formation'].find_one({'_id': ObjectId(str(diction['session_id'])), + 'valide': '1'}) + + + if( local_session_info is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible de récupérer les données de la session de formation") + return False, " Impossible de récupérer les données de la session de formation" + + if ("code_session" in local_session_info.keys()): + if local_session_info['code_session']: + my_retrun_dict['code_session'] = local_session_info['code_session'] + + if ("distantiel" in local_session_info.keys()): + if local_session_info['distantiel']: + my_retrun_dict['distantiel'] = local_session_info['distantiel'] + + if ("presentiel" in local_session_info.keys()): + if local_session_info['presentiel']: + my_retrun_dict['presentiel'] = local_session_info['presentiel'] + + session_ondemande = "" + if ("session_ondemande" in local_session_info.keys()): + if local_session_info['session_ondemande']: + session_ondemande = local_session_info['session_ondemande'] + + my_retrun_dict['session_ondemande'] = session_ondemande + + my_retrun_dict['partner_owner_recid'] = local_session_info['partner_owner_recid'] + + my_retrun_dict['token'] = str(diction['token']) + my_retrun_dict['session_id'] = str(diction['session_id']) + my_retrun_dict['inscription_id'] = str(local_Insc_retval['_id']) + + # Envoi de l'email de notification au formateur + local_status, local_message = email_session.Evaluation_training_confirmation_mail(my_retrun_dict) + + """ + # Ajout de l'evenement dans l'historique + """ + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + history_event_dict = {} + history_event_dict['token'] = diction['token'] + history_event_dict['related_collection'] = "inscription" + history_event_dict['related_collection_recid'] = str(local_Insc_retval['_id']) + history_event_dict['action_date'] = str(now) + history_event_dict['action_description'] = " Demande Evaluation Formation " + 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 local_status, str(local_message) + + except Exception as e: + 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 d'envoyer la demande d'evaluation" + + + +""" +Cette fonction envoie l'email de demande d'evaluation from tab_ids +""" +def SendTrainingEvaluationEmail_from_tab_ids(diction): + try: + field_list_obligatoire = ['session_id', 'token', 'tab_ids'] + + 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" + + 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 + + my_inscription_ids = "" + if ("tab_ids" in diction.keys()): + if diction['tab_ids']: + my_inscription_ids = diction['tab_ids'] + + + # Recuperation du recid du partenaire + partner_recid = str(my_partner['recid']) + + tab_my_inscription_ids = str(my_inscription_ids).split(",") + for my_inscription_id in tab_my_inscription_ids: + + # Verifier qui la formation n'a pas deja été evaluée + tmp_count = MYSY_GV.dbname['inscription'].count_documents({'session_id': str(diction['session_id']), + '_id':ObjectId(str(my_inscription_id)), + 'partner_owner_recid': str(partner_recid), + "eval_date": {"$exists": True}}) + + if (tmp_count > 0): + mycommon.myprint(str(inspect.stack()[0][3]) + " Cet apprenant a déjà évalué cette session") + return False, " Cet apprenant a déjà évalué cette session" + + + RetObject = [] + # Recuperation des infos de la formation + local_Insc_retval = MYSY_GV.dbname['inscription'].find_one({'session_id': str(diction['session_id']), + '_id':ObjectId(str(my_inscription_id)), + 'partner_owner_recid': str(partner_recid), + }) + + if(local_Insc_retval is None ): + mycommon.myprint(str(inspect.stack()[0][3]) + " L'identifiant de l'inscrit est invalide ") + return False, " L'identifiant de l'inscrit est invalide " + + my_retrun_dict = {} + + print(' ##### local_Insc_retval = ', local_Insc_retval) + + my_retrun_dict['token_eval'] = local_Insc_retval['_id'] + if( "date_du" in local_Insc_retval.keys() ): + my_retrun_dict['date_du'] = str(local_Insc_retval['date_du'])[1:10] + else: + my_retrun_dict['date_du'] = "" + + if ("date_au" in local_Insc_retval.keys() ): + my_retrun_dict['date_au'] = str(local_Insc_retval['date_au'])[0:10] + else: + my_retrun_dict['date_au'] = "" + + my_retrun_dict['session_id'] = str(local_Insc_retval['_id']) + + ville = "" + if ("ville" in local_Insc_retval.keys() and local_Insc_retval['ville']): + ville = local_Insc_retval['ville'] + my_retrun_dict['ville'] = ville + + code_postal = "" + if ("code_postal" in local_Insc_retval.keys() and local_Insc_retval['code_postal']): + code_postal = local_Insc_retval['code_postal'] + my_retrun_dict['code_postal'] = code_postal + + internal_url = "" + if ("class_internal_url" in local_Insc_retval.keys() and local_Insc_retval['class_internal_url']): + internal_url = local_Insc_retval['class_internal_url'] + my_retrun_dict['internal_url'] = internal_url + + + + adresse = "" + if ("adresse" in local_Insc_retval.keys() and local_Insc_retval['adresse']): + adresse = local_Insc_retval['adresse'] + my_retrun_dict['adresse'] = adresse + + nom = "" + if ("nom" in local_Insc_retval.keys() and local_Insc_retval['nom']): + nom = local_Insc_retval['nom'] + my_retrun_dict['nom'] = nom + + prenom = "" + if ("prenom" in local_Insc_retval.keys() and local_Insc_retval['prenom']): + prenom = local_Insc_retval['prenom'] + my_retrun_dict['prenom'] = prenom + + employeur = "" + if ("employeur" in local_Insc_retval.keys() and local_Insc_retval['employeur']): + employeur = local_Insc_retval['employeur'] + my_retrun_dict['employeur'] = employeur + + telephone = "" + if ("telephone" in local_Insc_retval.keys() and local_Insc_retval['telephone']): + telephone = local_Insc_retval['telephone'] + my_retrun_dict['telephone'] = telephone + + + my_retrun_dict['email'] = local_Insc_retval['email'] + + # Recuperation des infotrmations de la formation + print(" ### str(local_Insc_retval['class_internal_url']) = ",str(local_Insc_retval['class_internal_url']) ) + local_formation = MYSY_GV.dbname['myclass'].find_one( + {'internal_url': str(local_Insc_retval['class_internal_url'])}) + my_retrun_dict['title'] = local_formation['title'] + + # Recuperation des info de session + local_session_info = MYSY_GV.dbname['session_formation'].find_one({'_id': ObjectId(str(diction['session_id'])), + 'valide': '1'}) + + + if( local_session_info is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible de récupérer les données de la session de formation") + return False, " Impossible de récupérer les données de la session de formation" + + if ("code_session" in local_session_info.keys()): + if local_session_info['code_session']: + my_retrun_dict['code_session'] = local_session_info['code_session'] + + if ("distantiel" in local_session_info.keys()): + if local_session_info['distantiel']: + my_retrun_dict['distantiel'] = local_session_info['distantiel'] + + if ("presentiel" in local_session_info.keys()): + if local_session_info['presentiel']: + my_retrun_dict['presentiel'] = local_session_info['presentiel'] + + session_ondemande = "" + if ("session_ondemande" in local_session_info.keys()): + if local_session_info['session_ondemande']: + session_ondemande = local_session_info['session_ondemande'] + + my_retrun_dict['session_ondemande'] = session_ondemande + + my_retrun_dict['partner_owner_recid'] = local_session_info['partner_owner_recid'] + + my_retrun_dict['token'] = str(diction['token']) + my_retrun_dict['session_id'] = str(diction['session_id']) + my_retrun_dict['inscription_id'] = str(local_Insc_retval['_id']) + + # Envoi de l'email de notification au formateur + local_status, local_message = email_session.Evaluation_training_confirmation_mail(my_retrun_dict) + + """ + # Ajout de l'evenement dans l'historique + """ + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + history_event_dict = {} + history_event_dict['token'] = diction['token'] + history_event_dict['related_collection'] = "inscription" + history_event_dict['related_collection_recid'] = str(local_Insc_retval['_id']) + history_event_dict['action_date'] = str(now) + history_event_dict['action_description'] = " Demande Evaluation Formation " + 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 local_status, "Les demande d'évaluation ont été correctement envoyées " + + except Exception as e: + 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 d'envoyer la demande d'évaluation" + + + + +""" +Cette fonction envoie le certificat d'un stagiaire +""" +def SendAttendeeCertification(diction): + try: + + field_list_obligatoire = ['session_id', 'token', 'attendee_email', 'class_internal_url'] + + 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" + + 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 "Err_Connexion", " La session de connexion n'est pas valide" + + + # Recuperation du recid du partenaire + partner_recid = mycommon.get_parnter_recid_from_token(str(my_token)) + if partner_recid is False: + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible d'imprimer la fiche detaillée") + return False, " Les informations fournies sont incorrectes" + + # Verifier qui la formation n'a pas deja été evaluée + tmp_count = MYSY_GV.dbname['inscription'].count_documents({'session_id': str(diction['session_id']), + 'email': str(diction['attendee_email']), + 'class_internal_url': str(diction['class_internal_url']), + "certification_send_date": {"$exists": True}}) + + if (tmp_count > 0): + mycommon.myprint(str(inspect.stack()[0][3]) + " Vous avez deja envoyé le certificat") + return False, " Vous avez deja envoyé le certificat" + + # Recuperation du type/nom de la certifcation depuis la collecion "session_formation" + session_formation = MYSY_GV.dbname['session_formation'].find_one({'_id': ObjectId(str(diction['session_id'])), + 'class_internal_url': str( + diction['class_internal_url']), + 'valide': "1"}) + + if( session_formation['attestation_certif'] is None ): + mycommon.myprint(str(inspect.stack()[0][3]) + " impossible de trouver le modele d'attestation") + return False, " impossible de trouver le modele d'attestation" + + date_fin_session = str(session_formation['date_fin'] )[0:10] + local_status = mycommon.CheckisDate(date_fin_session) + if( local_status is False ): + mycommon.myprint(str(inspect.stack()[0][3]) + " La date de fin de session de formation est incorrecte.") + return False, " La date de fin de session de formation est incorrecte." + + mytoday = datetime.today().strftime("%d/%m/%Y") + """ + if (datetime.strptime(str(date_fin_session).strip(), '%d/%m/%Y') > datetime.strptime(str(mytoday).strip(), '%d/%m/%Y')): + mycommon.myprint(str(inspect.stack()[0][3]) + " Vous ne pouvez pas delivrer de certificat avant la date de fin de la session de formation ") + return False, " Vous ne pouvez pas delivrer de certificat avant la date de fin de la session de formation " + """ + print(" #### attestation_certif = ", str(session_formation['attestation_certif'])) + attestation_certificat = MYSY_GV.dbname['attestation_certificat'].find_one({'nom': str(session_formation['attestation_certif']), + 'valide': "1"}) + + if ( attestation_certificat is None or attestation_certificat['template_name'] is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Aucun type d'attestation/certificat trouvé 1") + return False, " Aucun type d'attestation/certificat trouvé " + + my_retrun_dict = {} + + my_retrun_dict['partner_recid'] = partner_recid + + my_template = "" + if ("template_name" in attestation_certificat.keys() and attestation_certificat['template_name']): + my_template = attestation_certificat['template_name'] + + if( str(my_template).strip() == ""): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Aucun type d'attestation/certificat trouvé 2") + return False, " Aucun type d'attestation/certificat trouvé " + + my_retrun_dict['attestation_tmpl'] = attestation_certificat['template_name'] + + # Recuperation des info de l'inscrit + local_qry = {'session_id': str(diction['session_id']), + 'class_internal_url': str( + diction['class_internal_url']), + 'email': str(diction['attendee_email'])} + + print("### "+str(inspect.stack()[0][3]) + "local_qry = ", local_qry ) + local_Insc_retval = MYSY_GV.dbname['inscription'].find_one({'session_id': str(diction['session_id']), + 'class_internal_url': str( + diction['class_internal_url']), + 'email': str(diction['attendee_email'])}) + + if (local_Insc_retval is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible de récupérer les données de l'inscrit") + return False, " Impossible de récupérer les données de l'inscrit" + + my_retrun_dict['date_du'] = local_Insc_retval['date_du'] + my_retrun_dict['date_au'] = local_Insc_retval['date_au'] + + ville = "" + if ("ville" in local_Insc_retval.keys() and local_Insc_retval['ville']): + ville = local_Insc_retval['ville'] + my_retrun_dict['ville'] = ville + + code_postal = "" + if ("code_postal" in local_Insc_retval.keys() and local_Insc_retval['code_postal']): + code_postal = local_Insc_retval['code_postal'] + my_retrun_dict['code_postal'] = code_postal + + internal_url = "" + if ("class_internal_url" in local_Insc_retval.keys() and local_Insc_retval['class_internal_url']): + internal_url = local_Insc_retval['class_internal_url'] + my_retrun_dict['code_postal'] = internal_url + + + my_retrun_dict['inscription_id'] = local_Insc_retval['_id'] + + adresse = "" + if ("adresse" in local_Insc_retval.keys() and local_Insc_retval['adresse']): + adresse = local_Insc_retval['adresse'] + my_retrun_dict['adresse'] = adresse + + nom = "" + if ("nom" in local_Insc_retval.keys() and local_Insc_retval['nom']): + nom = local_Insc_retval['nom'] + my_retrun_dict['nom'] = nom + + prenom = "" + if ("prenom" in local_Insc_retval.keys() and local_Insc_retval['prenom']): + prenom = local_Insc_retval['prenom'] + my_retrun_dict['prenom'] = prenom + + employeur = "" + if ("employeur" in local_Insc_retval.keys() and local_Insc_retval['employeur']): + employeur = local_Insc_retval['employeur'] + my_retrun_dict['employeur'] = employeur + + telephone = "" + if ("telephone" in local_Insc_retval.keys() and local_Insc_retval['telephone']): + telephone = local_Insc_retval['telephone'] + my_retrun_dict['telephone'] = telephone + + formateur = "" + if ("formateur" in session_formation.keys() and session_formation['formateur']): + formateur = session_formation['formateur'] + my_retrun_dict['formateur'] = formateur + + presentiel = "" + if ("presentiel" in session_formation.keys() and session_formation['presentiel']): + presentiel = session_formation['presentiel'] + my_retrun_dict['presentiel'] = presentiel + + distantiel = "" + if ("distantiel" in session_formation.keys() and session_formation['distantiel']): + distantiel = session_formation['distantiel'] + my_retrun_dict['distantiel'] = distantiel + + + #my_retrun_dict['formateur'] = session_formation['formateur'] + + my_retrun_dict['email'] = local_Insc_retval['email'] + + # Recuperation des infotrmations de la formation + ##print(" ## str(local_Insc_retval['class_internal_url']) = ", str(local_Insc_retval['class_internal_url'])) + local_formation = MYSY_GV.dbname['myclass'].find_one( + {'internal_url': str(local_Insc_retval['class_internal_url'])}) + my_retrun_dict['title'] = local_formation['title'] + + """ + field_list_obligatoire = ['partner_recid', 'session_id', 'class_internal_url', 'class_title' , + 'email_participant'] + """ + attestation_dict = {} + attestation_dict['partner_recid'] = str(partner_recid) + attestation_dict['session_id'] = str(diction['session_id']) + attestation_dict['class_internal_url'] = str(local_Insc_retval['class_internal_url']) + attestation_dict['class_title'] = local_formation['title'] + attestation_dict['email_participant'] = local_Insc_retval['email'] + attestation_dict['attestation_tmpl'] = attestation_certificat['template_name'] + + print(" ### attestation_dict = ", attestation_dict) + + # Envoi de l'email de notification au formateur + local_status, local_message = email_session.SendAttestion_to_attendee_by_email(attestation_dict) + + return local_status, str(local_message) + + except Exception as e: + 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 d'envoyer l'attestation" + + +""" Cette fonction imprime l'attestation +""" + + +def PrintAttendeeCertification(diction): + try: + + field_list_obligatoire = ['session_id', 'token', 'attendee_email', 'internal_url'] + + 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" + + my_token = "" + if ("token" in diction.keys()): + if diction['token']: + my_token = diction['token'] + + # Recuperation du recid du partenaire + partner_recid = mycommon.get_parnter_recid_from_token(str(my_token)) + if partner_recid is False: + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible d'imprimer la fiche detaillée") + return False, " Les informations fournies sont incorrectes" + + # Verifier qui la formation n'a pas deja été evaluée + tmp_count = MYSY_GV.dbname['inscription'].count_documents({'session_id': str(diction['session_id']), + 'email': str(diction['attendee_email']), + "certification_send": {"$exists": True}}) + + if (tmp_count > 0): + mycommon.myprint(str(inspect.stack()[0][3]) + " Vous avez deja envoyé le certificat") + return False, " Vous avez deja envoyé le certificat" + + # Recuperation des données du partenaire + local_partner = MYSY_GV.dbname['partnair_account'].find_one({'recid': str(partner_recid), + 'active': "1", + 'locked':'0'}) + + if( local_partner is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible de récupérer les données du partenaire") + return False, " Impossible de récupérer les données du partenaire " + + my_retrun_dict = {} + + partner_nom = "" + if ("nom" in local_partner.keys()): + partner_nom = local_partner['nom'] + my_retrun_dict['partner'] = partner_nom + + num_nda = "" + if ("num_nda" in local_partner.keys()): + num_nda = local_partner['num_nda'] + my_retrun_dict['num_declation'] = num_nda + + mysy_partner_adr_city = "" + if ("adr_city" in local_partner.keys()): + mysy_partner_adr_city = local_partner['adr_city'] + my_retrun_dict['mysy_partner_adr_city'] = mysy_partner_adr_city + + my_retrun_dict['cachet_signature'] = "https://img.mysy-training.com/perso/mysy_cachet.png" + ct = datetime.now() + ts = ct.timestamp() + date_jour = ct.strftime("%d/%m/%Y") + my_retrun_dict['date_jour'] = str(date_jour) + + # Recuperation du type/nom de la certifcation depuis la collecion "session_formation" + session_formation = MYSY_GV.dbname['session_formation'].find_one( + {'_id': ObjectId(str(diction['session_id'])), + 'valide': "1", 'class_internal_url':str(diction['internal_url'])}) + + if ("attestation_certif" not in session_formation.keys()): + mycommon.myprint(str(inspect.stack()[0][3]) + " impossible de trouver le modele d'attestation") + return False, " impossible de trouver le modele d'attestation" + + distantiel = "" + if ("distantiel" in session_formation.keys()): + distantiel = session_formation['distantiel'] + my_retrun_dict['distantiel'] = distantiel + + distantiel = "" + if ("distantiel" in session_formation.keys()): + distantiel = session_formation['formateur'] + my_retrun_dict['distantiel'] = distantiel + + formateur = "" + if ("formateur" in session_formation.keys()): + formateur = session_formation['formateur'] + my_retrun_dict['formateur'] = formateur + + contenu_ftion = "" + if ("contenu_ftion" in session_formation.keys()): + contenu_ftion = str(session_formation['contenu_ftion']).replace('

', '').replace('

', '').replace("\r\n", '
') + my_retrun_dict['contenu_ftion'] = contenu_ftion + + + # Recuperation des données de l'attestation + attestation_certificat = MYSY_GV.dbname['attestation_certificat'].find_one( + {'nom': str(session_formation['attestation_certif']), + 'valide': "1"}) + + if( attestation_certificat is None ): + mycommon.myprint(str(inspect.stack()[0][3]) + " impossible de trouver le modele d'attestation (2)") + return False, " impossible de trouver le modele d'attestation (2)" + + if ("template_name" not in attestation_certificat.keys()): + mycommon.myprint(str(inspect.stack()[0][3]) + " impossible de trouver le modele d'attestation (3)") + return False, " impossible de trouver le modele d'attestation (3)" + + + + my_retrun_dict['attestation_tmpl'] = attestation_certificat['template_name'] + + # Recuperation des info de l'inscrit + local_Insc_retval = MYSY_GV.dbname['inscription'].find_one({'session_id': str(diction['session_id']), + 'email': str(diction['attendee_email'])}) + + if (local_Insc_retval is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible de récupérer les données de l'inscrit") + return False, " Impossible de récupérer les données de l'inscrit" + + my_retrun_dict['date_du'] = str(local_Insc_retval['date_du'])[0:10] + my_retrun_dict['date_au'] = str(local_Insc_retval['date_au'])[0:10] + + ville = "" + if ("ville" in local_Insc_retval.keys()): + ville = local_Insc_retval['ville'] + my_retrun_dict['ville'] = ville + + code_postal = "" + if ("code_postal" in local_Insc_retval.keys()): + code_postal = local_Insc_retval['code_postal'] + my_retrun_dict['code_postal'] = code_postal + + class_internal_url = "" + if ("class_internal_url" in local_Insc_retval.keys()): + class_internal_url = local_Insc_retval['class_internal_url'] + my_retrun_dict['internal_url'] = class_internal_url + + + adresse = "" + if ("adresse" in local_Insc_retval.keys()): + adresse = local_Insc_retval['adresse'] + my_retrun_dict['adresse'] = adresse + + nom = "" + if ("nom" in local_Insc_retval.keys()): + nom = local_Insc_retval['nom'] + my_retrun_dict['nom'] = nom + + prenom = "" + if ("prenom" in local_Insc_retval.keys()): + prenom = local_Insc_retval['prenom'] + my_retrun_dict['prenom'] = prenom + + employeur = "" + if ("employeur" in local_Insc_retval.keys()): + employeur = local_Insc_retval['employeur'] + my_retrun_dict['employeur'] = employeur + + telephone = "" + if ("telephone" in local_Insc_retval.keys()): + telephone = local_Insc_retval['telephone'] + my_retrun_dict['telephone'] = telephone + + email = "" + if ("email" in local_Insc_retval.keys()): + email = local_Insc_retval['email'] + my_retrun_dict['email'] = email + + + + # Recuperation des infotrmations de la formation + #print(" ## str(local_Insc_retval['class_internal_url']) = ", str(local_Insc_retval['class_internal_url'])) + local_formation = MYSY_GV.dbname['myclass'].find_one( + {'internal_url': str(local_Insc_retval['class_internal_url'])}) + + if( local_formation is None ): + mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible de récupérer les données de la formation ") + return False, " Impossible de récupérer les données de la formation" + + title = "" + if ("title" in local_formation.keys()): + title = local_formation['title'] + my_retrun_dict['class_title'] = title + + logo_url = "" + if ("img_url" in local_formation.keys()): + logo_url = local_formation['img_url'] + my_retrun_dict['logo_url'] = logo_url + + + templateLoader = jinja2.FileSystemLoader(searchpath="./") + templateEnv = jinja2.Environment(loader=templateLoader) + TEMPLATE_FILE = "Template/"+str(my_retrun_dict['attestation_tmpl'])+".html" + template = templateEnv.get_template(TEMPLATE_FILE) + # This data can come from database query + body = { + "data": my_retrun_dict, + + } + + print(" ### body = " + str(body)) + + sourceHtml = template.render(json_data=body["data"]) + mycode = str(datetime.now().timestamp()).replace(".", '').replace(',', '') + orig_file_name = "Attestation_" + str(mycode)[:-3] + "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() + + # print(" ### outputFilename = "+str(outputFilename)) + if os.path.exists(outputFilename): + # print(" ### ok os.path.exists(outputFilename) "+str(outputFilename)) + return True, send_file(outputFilename, as_attachment=True) + + # return True on success and False on errors + print(pisaStatus.err, type(pisaStatus.err)) + + return True, " le fichier generé " + + except Exception as e: + 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 d'envoyer l'attestation" + + +""" +Cette fonction récupérer la liste des evaluations d'une session de formation +""" +def GetListEvaluation_Session(diction): + try: + field_list_obligatoire = ['session_id', 'token'] + + for val in field_list_obligatoire: + if val not in diction: + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La valeur '" + val + "' n'est pas presente dans la liste des arguments ") + return False, " Les informations fournies sont incorrectes" + + 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 "Err_Connexion", " La session de connexion n'est pas valide" + + + # Recuperation du recid du partenaire + 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 la liste des evaluations") + return False, " Les informations fournies sont incorrectes" + + RetObject = [] + val_tmp = 1 + + qry = {'session_id': str(diction['session_id']), 'partner_owner_recid':str(partner_recid)} + + + # Recuperation des infos de la formation + for local_Insc_retval in MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']), 'partner_owner_recid':str(partner_recid)}): + user = {} + user['id'] = str(val_tmp) + user['_id'] = str(local_Insc_retval['_id']) + val_tmp = val_tmp + 1 + user['session_id'] = local_Insc_retval['session_id'] + user['email'] = local_Insc_retval['email'] + user['nom'] = local_Insc_retval['nom'] + user['prenom'] = local_Insc_retval['prenom'] + + if ("eval_date" in local_Insc_retval.keys()): + user['eval_date'] = local_Insc_retval['eval_date'] + else: + user['eval_date'] = "---" + + + if ("eval_eval" in local_Insc_retval.keys()): + user['eval_eval'] = local_Insc_retval['eval_eval'] + else: + user['eval_eval'] = "---" + + + if ("eval_status" in local_Insc_retval.keys()): + user['eval_status'] = local_Insc_retval['eval_status'] + else: + user['eval_status'] = "" + + + if ("eval_note" in local_Insc_retval.keys()): + user['eval_note'] = local_Insc_retval['eval_note'] + else: + user['eval_note'] = "---" + + + if ("eval_pedagogie" in local_Insc_retval.keys()): + user['eval_pedagogie'] = local_Insc_retval['eval_pedagogie'] + else: + user['eval_pedagogie'] = "" + + + if ("date_demande_eval" in local_Insc_retval.keys()): + user['date_demande_eval'] = local_Insc_retval['date_demande_eval'] + else: + user['date_demande_eval'] = "" + + + + RetObject.append(mycommon.JSONEncoder().encode(user)) + + #print(" ### RetObject = ", RetObject) + return True, RetObject + + except Exception as e: + 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 récupérer la liste des evaluations" + + +""" +Cette fonction permet d'annuler l'inscription à une formation. +# status -1 ==> Inscription annulée +""" +def CancelAttendeeInscription(diction): + try: + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', 'email', 'class_internal_url', '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 ne sont pas correctes" + + mytoken = "" + if ("token" in diction.keys()): + if diction['token']: + mytoken = diction['token'] + + + + local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data({'token':str(diction['token'])}) + if (local_status is not True): + return local_status, my_partner + + partner_recid = str(my_partner['recid']) + + data_mail = {} + # 1 - Recuperation des données de la formation + local_class = MYSY_GV.dbname['myclass'].find({'internal_url': str(diction['class_internal_url'])}) + data_mail['title'] = local_class[0]['title'] + class_title = local_class[0]['title'] + + # 2 - Recuperation des données de l'inscription + local_inscription = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']), + 'email': str(diction['email']), + 'class_internal_url':str(diction['class_internal_url'])}) + lms_class_code = "" + if ("lms_class_code" in local_inscription[0].keys()): + if local_inscription[0]['lms_class_code']: + lms_class_code = local_inscription[0]['lms_class_code'] + + lms_user_id = "" + if ("lms_user_id" in local_inscription[0].keys()): + if local_inscription[0]['lms_user_id']: + lms_user_id = local_inscription[0]['lms_user_id'] + + nom = "" + if ("nom" in local_inscription[0].keys()): + if local_inscription[0]['nom']: + nom = local_inscription[0]['nom'] + + prenom = "" + if ("prenom" in local_inscription[0].keys()): + if local_inscription[0]['prenom']: + prenom = local_inscription[0]['prenom'] + + email = "" + if ("email" in local_inscription[0].keys()): + if local_inscription[0]['email']: + email = local_inscription[0]['email'] + + date_du = "" + if ("date_du" in local_inscription[0].keys()): + if local_inscription[0]['date_du']: + date_du = str(local_inscription[0]['date_du'])[0:10] + + date_au = "" + if ("date_au" in local_inscription[0].keys()): + if local_inscription[0]['date_au']: + date_au = str(local_inscription[0]['date_au'])[0:10] + + + # Recuperation des données de la session + local_session = MYSY_GV.dbname['session_formation'].find_one( + {'_id': ObjectId(str(diction['session_id'])), 'class_internal_url': str(diction['class_internal_url']), 'valide':'1'}) + + if (local_session is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer les données de la session ") + return False, " Impossible de récupérer les données de la session " + + # Annulation de l'inscription + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + + ret_val2 = MYSY_GV.dbname['inscription'].find_one_and_update( + {'session_id': str(diction['session_id']), 'email': str(diction['email']), 'class_internal_url':str(diction['class_internal_url'])}, + {"$set": {'status':'-1', 'inscription_refuse_date':now, 'date_update':now}}, + return_document=ReturnDocument.AFTER, + upsert=False, + ) + + if( ret_val2 is None ): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible d'annuler l'inscription ") + return False, " Impossible d'annuler l'inscription " + + """ + Verification s'il y a une inscription LMS, au quel cas, on l'annule aussi + """ + + return_message = "" + + if( lms_user_id.strip() != ""): + # Il a une inscription à une formation dans le LMS, il faut l'annuler + new_diction = {} + new_diction['token'] = str(diction['token']) + new_diction['user_lms_id'] = str(lms_user_id) + new_diction['course_code'] = str(lms_class_code) + + local_status, local_message = mys_lms.Remove_User_From_LMS_Class(new_diction) + if (local_status is False): + mycommon.myprint(str(inspect.stack()[0][3]) + " - WARNING : Impossible de supprimer l'inscription dans le LMS pour "+str( diction['email']) ) + return_message = "Impossible de supprimer l'inscription dans le LMS pour : "+str( diction['email']) + + """ + 13/12/2025 : + On n'envoit la notification d'annulation que la paramettre 'annulation_inscription_notification_email' est à 1 + """ + local_insc_status, local_insc_retval = mycommon.Is_Partnair_Annulation_Inscription_Notification( {'token': diction['token']}) + if (local_insc_status and local_insc_retval == "1"): + print(" ###OK on doit envoyer l'email d'annulation à l'apprenant = ") + email_data = {} + email_data['token'] = str(diction['token']) + email_data['nom'] = nom + email_data['prenom'] = prenom + email_data['email'] = email + email_data['date_du'] = date_du + email_data['date_au'] = date_au + email_data['title'] = class_title + email_data['partner_owner_recid'] = str(partner_recid) + + + local_status, local_message = email_session.incription_training_cancelled_mail(email_data) + if( local_status is False ): + mycommon.myprint(str( + inspect.stack()[0][3]) + " - WARNING : Impossible d'envoyer le mail de notification pour " + str( + diction['email'])) + return_message = return_message + str(" Impossible d'envoyer le mail de notification pour : " + str(diction['email'])) + + if( return_message.strip() != ""): + return True, return_message + + else: + print(" ### ON NE DOIT PASSS on doit envoyer l'email d'annulation à l'apprenant = ") + + return True, "L'inscription a été correctement annulée" + + except Exception as e: + 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 d'annuler l'inscription" + + + +""" +Cette fonction refuse une inscription, met jour le motif de refus +et envoie un email au participants +""" +def RefuseAttendeeInscription_with_motif(diction): + try: + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', 'email', 'inscription_id', 'motif'] + 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 ne sont pas correctes" + + mytoken = "" + if ("token" in diction.keys()): + if diction['token']: + mytoken = diction['token'] + + + local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data({'token':str(diction['token'])}) + if (local_status is not True): + return local_status, my_partner + + partner_recid = str(my_partner['recid']) + + # 0 - Verifier de l'existance et de la validité de l'inscription (preinscription à refuser) + my_inscription_count = MYSY_GV.dbname['inscription'].count_documents({'_id':ObjectId(str(diction['inscription_id'])), + 'partner_owner_recid':str(partner_recid)}) + if( my_inscription_count <= 0 ): + mycommon.myprint(str(inspect.stack()[0][3]) + " - L'identifiant d'inscription est invalide") + return False, "L'identifiant d'inscription est invalide" + + + data_mail = {} + + # 2 - Recuperation des données de l'inscription + local_inscription = MYSY_GV.dbname['inscription'].find({'_id': ObjectId(str(diction['inscription_id'])), + 'email': str(diction['email']), + 'partner_owner_recid':str(partner_recid)}) + lms_class_code = "" + if ("lms_class_code" in local_inscription[0].keys()): + if local_inscription[0]['lms_class_code']: + lms_class_code = local_inscription[0]['lms_class_code'] + + lms_user_id = "" + if ("lms_user_id" in local_inscription[0].keys()): + if local_inscription[0]['lms_user_id']: + lms_user_id = local_inscription[0]['lms_user_id'] + + nom = "" + if ("nom" in local_inscription[0].keys()): + if local_inscription[0]['nom']: + nom = local_inscription[0]['nom'] + + prenom = "" + if ("prenom" in local_inscription[0].keys()): + if local_inscription[0]['prenom']: + prenom = local_inscription[0]['prenom'] + + email = "" + if ("email" in local_inscription[0].keys()): + if local_inscription[0]['email']: + email = local_inscription[0]['email'] + + date_du = "" + if ("date_du" in local_inscription[0].keys()): + if local_inscription[0]['date_du']: + date_du = str(local_inscription[0]['date_du'])[0:10] + + date_au = "" + if ("date_au" in local_inscription[0].keys()): + if local_inscription[0]['date_au']: + date_au = str(local_inscription[0]['date_au'])[0:10] + + # 3 - Recuperation des données de la formation + local_class = MYSY_GV.dbname['myclass'].find({'internal_url': str(local_inscription[0]['class_internal_url']), + 'partner_owner_recid':str(partner_recid)}) + data_mail['title'] = local_class[0]['title'] + class_title = local_class[0]['title'] + + + # Recuperation des données de la session + local_session = MYSY_GV.dbname['session_formation'].find_one( + {'_id': ObjectId(str(local_inscription[0]['session_id'])), + 'valide':'1', 'partner_owner_recid':str(partner_recid)}) + + if (local_session is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer les données de la session ") + return False, " Impossible de récupérer les données de la session " + + # Annulation de l'inscription + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + + ret_val2 = MYSY_GV.dbname['inscription'].find_one_and_update( + {'_id': ObjectId( str(diction['inscription_id'])), 'email': str(diction['email'])}, + {"$set": {'status':'-1', 'inscription_refuse_date':now, 'date_update':now, + 'comment':str(diction['motif'])}}, + return_document=ReturnDocument.AFTER, + upsert=False, + ) + + if( ret_val2 is None ): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible d'annuler l'inscription ") + return False, " Impossible d'annuler l'inscription " + + """ + 12/10/2024 - loguer les action dans l'historique général + + """ + ## Add to log history pour l'inscrit 'inscription' + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + history_event_dict = {} + history_event_dict['token'] = str(mytoken) + history_event_dict['related_collection'] = "inscription" + history_event_dict['related_collection_recid'] = str(local_inscription[0]['_id']) + history_event_dict['action_date'] = str(now) + + local_session_info = "" + + if ("code_session" in local_session.keys()): + local_session_info = local_session_info + ", Code Session : " + local_session["code_session"] + + history_event_dict['action_description'] = "Refus inscription à " + str(local_session_info) + 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)) + + ## Add to log history pour la session 'session_formation' + history_event_dict = {} + history_event_dict['token'] = str(mytoken) + history_event_dict['related_collection'] = "session_formation" + history_event_dict['related_collection_recid'] = str(local_session['_id']) + history_event_dict['action_date'] = str(now) + + local_inscrit_info = "" + if ("_id" in local_inscription[0].keys()): + local_inscrit_info = "_Id Inscrit : " + str(local_inscription[0]["_id"]) + if ("email" in local_inscription[0].keys()): + local_inscrit_info = local_inscrit_info + ", " + local_inscription[0]["email"] + + if ("nom" in local_inscription[0].keys()): + local_inscrit_info = local_inscrit_info + ", " + local_inscription[0]["nom"] + + if ("prenom" in local_inscription[0].keys()): + local_inscrit_info = local_inscrit_info + ", " + local_inscription[0]["prenom"] + + history_event_dict['action_description'] = "Refus inscription de " + str(local_inscrit_info) + + # print(" ### laaaaaaaaa history_event_dict = ", history_event_dict) + + 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)) + + """ + Verification s'il y a une inscription LMS, au quel cas, on l'annule aussi + """ + + return_message = "" + + if( lms_user_id.strip() != ""): + # Il a une inscription à une formation dans le LMS, il faut l'annuler + new_diction = {} + new_diction['token'] = str(diction['token']) + new_diction['user_lms_id'] = str(lms_user_id) + new_diction['course_code'] = str(lms_class_code) + + local_status, local_message = mys_lms.Remove_User_From_LMS_Class(new_diction) + if (local_status is False): + mycommon.myprint(str(inspect.stack()[0][3]) + " - WARNING : Impossible de supprimer l'inscription dans le LMS pour "+str( diction['email']) ) + return_message = "Impossible de supprimer l'inscription dans le LMS pour : "+str( diction['email']) + + email_data = {} + email_data['token'] = str(diction['token']) + email_data['nom'] = nom + email_data['prenom'] = prenom + email_data['email'] = email + email_data['date_du'] = date_du + email_data['date_au'] = date_au + email_data['title'] = class_title + email_data['comment'] = str(diction['motif']) + email_data['partner_owner_recid'] = str(partner_recid) + + + local_status, local_message = email_session.incription_training_cancelled_mail(email_data) + if( local_status is False ): + mycommon.myprint(str( + inspect.stack()[0][3]) + " - WARNING : Impossible d'envoyer le mail de notification pour " + str( + diction['email'])) + return_message = return_message + str(" Impossible d'envoyer le mail de notification pour : " + str(diction['email'])) + + if( return_message.strip() != ""): + return True, return_message + + + + return True, "L'inscription a été correctement annulée" + + except Exception as e: + 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 d'annuler l'inscription" + + +""" +Cette fonction refuse les inscription en mase avec un motif +""" + +""" +Cette fonction une liste d'inscrit à une session de formation +""" +def Refuse_List_AttendeeInscription_with_motif(diction): + try: + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', 'list_inscription_id', 'motif'] + 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 ne sont pas correctes" + + 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'] + + list_inscription_id = [] + if ("list_inscription_id" in diction.keys()): + if diction['list_inscription_id']: + list_inscription_id = str(diction['list_inscription_id']).replace(",", ";").split(";") + + for inscription_id in list_inscription_id: + """ + # Verification que l'inscription existe et qu'elle est valide et qu'elle est au statut : en cours (status =2) ou + preinscrit (status = 0) ou validé (status = 1) + """ + ret_val2_count = MYSY_GV.dbname['inscription'].count_documents( + {'_id': ObjectId(str(inscription_id)), 'partner_owner_recid':str(my_partner['recid']), + }, + ) + + if (ret_val2_count != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + "L'identifiant de l'inscription "+ str(inscription_id) +" n'est pas valide ") + return False, " L'identifiant de l'inscription "+ str(inscription_id) +" n'est pas valide " + + inscription_id_data = MYSY_GV.dbname['inscription'].find_one( + {'_id': ObjectId(str(inscription_id)), 'partner_owner_recid': str(my_partner['recid']), + }, + ) + + if( "status" not in inscription_id_data.keys() or inscription_id_data['status'] not in ['0', '2', '1']): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " Toutes les inscriptions doivent être au statut : en cours ou preinscription ") + return False, " Toutes les inscriptions doivent être au statut : en cours ou preinscription " + + + # Verifier que la session de formation concernée est valide + is_valide_session = MYSY_GV.dbname['session_formation'].count_documents({'_id':ObjectId(str(inscription_id_data['session_id'])), + 'partner_owner_recid':str(my_partner['recid']), + 'valide':'1'}) + + if (is_valide_session != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " L'identifiant de la session de formation "+ str(inscription_id_data['session_id']) +" n'est pas valide ") + return False, " L'identifiant de la session de formation "+ str(inscription_id_data['session_id']) +" n'est pas valide " + + + + # A present les controles sont ok sur la liste on peut valide la liste des inscription + warning_msg = "" + is_warning = "" + for inscription_id in list_inscription_id: + + inscription_id_data = MYSY_GV.dbname['inscription'].find_one( + {'_id': ObjectId(str(inscription_id)), 'partner_owner_recid': str(my_partner['recid']), + 'status':{'$in':['0', '1', '2']} + }, + ) + + #print(" ### inscription_id_data = ",inscription_id_data) + if( inscription_id_data ): + new_diction = {} + new_diction['token'] = diction['token'] + new_diction['motif'] = diction['motif'] + new_diction['inscription_id'] = str(inscription_id_data['_id']) + new_diction['email'] = str(inscription_id_data['email']) + + #print(" ### new_diction = ",new_diction) + + local_status, local_retval = RefuseAttendeeInscription_with_motif(new_diction) + if( local_status is False ): + is_warning = "1" + warning_msg = warning_msg + "\n"+str(local_retval) + + if( is_warning == "1" ): + return True, str(warning_msg) + + return True, "La liste des inscriptions a été refusée" + + except Exception as e: + 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 refuser la liste des inscriptions" + + +""" +26/05/2025 : Gestion Formation initiale +Si il s'agit d'une inscription à une formation initiale, alors +on créer le contenu des collection : +- inscription_liste_ue : Dans cette collection on les UE auxquelles l'apprenant est inscrit +- inscription_liste_ue_type_eval : Dans cette collection on a types d'evaluation que doit passer un apprenant sur une UE + ==> Cela permet de gerer par exemple les personne qui s'inscrivent juste pour passer l'exemple final, ou juste les project + etc. + +Important : Pour determiner si une inscription concerne la formation initiale, on regarde si le compte utilisateur qui + valide l'inscription est un compte de 'formation initiale' + + +cette fonction prend en entrée : +- inscription_id +- class_id + +Important : on fait l'inscription que pour les UE qui sont marquées sur la session. Verifier la cohérence, que ces +UE soient bien sur la formation aussi. + +""" +def Init_AcceptAttendeeInscription_For_Initial_Formation(diction): + try: + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', 'inscription_id', 'class_id', 'tab_ue_ids'] + 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 ne sont pas correctes" + + 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 + + formation_initiale = "0" + if( "formation_initiale" in my_partner.keys() ): + formation_initiale = my_partner['formation_initiale'] + + if( formation_initiale != "1"): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Il ne s'agit pas d'un formation initiale ") + return True, [] + + + """ + Verifier que l'inscription est valide + """ + is_valide_inscription_count = MYSY_GV.dbname['inscription'].count_documents({'_id':ObjectId(diction['inscription_id']), + 'partner_owner_recid':str(my_partner['recid']), + 'valide':'1'}) + + if( is_valide_inscription_count != 1) : + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de l'inscrit est invalide ") + return False, " L'identifiant de l'inscrit est invalide " + + + """ + Verifier la validité de la formation et créer le contenu de la collection + """ + is_valide_class_count = MYSY_GV.dbname['myclass'].count_documents( + {'_id': ObjectId(diction['class_id']), + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked':'0'}) + + if (is_valide_class_count != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de la formation est invalide ") + return False, " L'identifiant de la formation est invalide " + + + """ + Suppression des données existe dans les collections : inscription_liste_ue et inscription_liste_ue_type_eval + pour l'inscrit et la formation concernée + """ + + clean_inscription_liste_ue = MYSY_GV.dbname['inscription_liste_ue'].delete_many({"partner_owner_recid": str(my_partner['recid']), + 'class_id': str(diction['class_id']), 'inscription_id': str(diction['inscription_id']), }) + + clean_inscription_liste_ue_type_eval = MYSY_GV.dbname['inscription_liste_ue_type_evalution'].delete_many( + {"partner_owner_recid": str(my_partner['recid']), + 'class_id': str(diction['class_id']), 'inscription_id': str(diction['inscription_id']), }) + + my_ue_ids = "" + tab_ue_ids = [] + if ("tab_ue_ids" in diction.keys()): + if diction['tab_ue_ids']: + my_ue_ids = diction['tab_ue_ids'] + tab_ue_ids_work = str(my_ue_ids).split(",") + + for tmp in tab_ue_ids_work: + if (tmp): + tab_ue_ids.append(tmp) + + """ + Recuperer les UE de la promotion, en s'assurant qu'elle est bien configurée sur la formationformation + """ + tab_class_ue_id = [] + + qry = {"partner_owner_recid": str(my_partner['recid']), 'valide': '1', 'locked': '0', + '_id': ObjectId(str(diction['class_id']))} + + + """ + Remplissage de la collection : inscription_liste_ue + """ + for New_retVal in MYSY_GV.dbname['myclass'].find(qry).sort([("_id", pymongo.DESCENDING), ]): + if( "list_unite_enseignement" in New_retVal.keys() ): + for local_val in New_retVal['list_unite_enseignement'] : + + + + is_ue_in_session = MYSY_GV.dbname['session_formation'].count_documents({"partner_owner_recid": str(my_partner['recid']), + 'valide': '1', + 'class_id': str(diction['class_id']), + 'list_unite_enseignement._id':str(local_val['_id'])}) + + + + if( ("tab_ue_ids" not in diction.keys() or str(diction['tab_ue_ids']).strip() == "") and is_ue_in_session > 0 ): + tab_class_ue_id.append(str(local_val['_id'])) + + + new_data = {} + new_data['inscription_id'] = str(diction['inscription_id']) + new_data['class_id'] = str(diction['class_id']) + new_data['class_eu_id'] = str(local_val['_id']) + new_data['update_date'] = str(datetime.now()) + new_data['update_by'] = str(my_partner['_id']) + new_data['partner_owner_recid'] = str(my_partner['recid']) + new_data['valide'] = "1" + new_data['locked'] = "0" + + + key_data = {} + key_data['inscription_id'] = str(diction['inscription_id']) + key_data['class_id'] = str(diction['class_id']) + key_data['class_eu_id'] = str(local_val['_id']) + key_data['valide'] = "1" + key_data['partner_owner_recid'] = str(my_partner['recid']) + + #print(" ### key_data = ", key_data) + + result = MYSY_GV.dbname['inscription_liste_ue'].find_one_and_update( + key_data, + {"$set": new_data}, + upsert=True, + return_document=ReturnDocument.AFTER + ) + if ("_id" not in result.keys()): + mycommon.myprint( + " Impossible de valider l'inscription pour la formation initiale (2) ") + return False, "Impossible de valider l'inscription pour la formation initiale (2) " + + elif ( "tab_ue_ids" in diction.keys() and str(diction['tab_ue_ids']).strip() != "" and str(local_val['_id']) in tab_ue_ids and is_ue_in_session > 0): + #print(" ### traitement inscription PARTIEL UEEE ", str(local_val['_id'])) + + tab_class_ue_id.append(str(local_val['_id'])) + + new_data = {} + new_data['inscription_id'] = str(diction['inscription_id']) + new_data['class_id'] = str(diction['class_id']) + new_data['class_eu_id'] = str(local_val['_id']) + new_data['update_date'] = str(datetime.now()) + new_data['update_by'] = str(my_partner['_id']) + new_data['partner_owner_recid'] = str(my_partner['recid']) + new_data['valide'] = "1" + new_data['locked'] = "0" + + key_data = {} + key_data['inscription_id'] = str(diction['inscription_id']) + key_data['class_id'] = str(diction['class_id']) + key_data['class_eu_id'] = str(local_val['_id']) + key_data['valide'] = "1" + key_data['partner_owner_recid'] = str(my_partner['recid']) + + result = MYSY_GV.dbname['inscription_liste_ue'].find_one_and_update( + key_data, + {"$set": new_data}, + upsert=True, + return_document=ReturnDocument.AFTER + ) + if ("_id" not in result.keys()): + mycommon.myprint( + " Impossible de valider l'inscription pour la formation initiale (2) ") + return False, "Impossible de valider l'inscription pour la formation initiale (2) " + + + """ + Remplissage de la collection : inscription_liste_ue_type_eval + """ + + for val in MYSY_GV.dbname['class_unite_enseignement_type_evaluation'].find({'partner_owner_recid':str(my_partner['recid']), + 'valide':'1', + 'locked':'0', + 'class_id':str(diction['class_id'])}): + new_data = {} + new_data['inscription_id'] = str(diction['inscription_id']) + new_data['class_id'] = str(diction['class_id']) + new_data['class_eu_id'] = str(val['class_ue_id']) + new_data['type_evaluation_id'] = str(val['type_evaluation_id']) + new_data['update_date'] = str(datetime.now()) + new_data['update_by'] = str(my_partner['_id']) + new_data['partner_owner_recid'] = str(my_partner['recid']) + new_data['valide'] = "1" + new_data['locked'] = "0" + + key_data = {} + key_data['inscription_id'] = str(diction['inscription_id']) + key_data['class_id'] = str(diction['class_id']) + key_data['class_eu_id'] = str(local_val['_id']) + key_data['valide'] = "1" + key_data['partner_owner_recid'] = str(my_partner['recid']) + + result = MYSY_GV.dbname['inscription_liste_ue_type_evalution'].find_one_and_update( + key_data, + {"$set": new_data}, + upsert=True, + return_document=ReturnDocument.AFTER + ) + if ("_id" not in result.keys()): + mycommon.myprint( + " Impossible de valider l'inscription pour la formation initiale (2) ") + return False, "Impossible de valider l'inscription pour la formation initiale (2) " + + + return True, "L'inscription a été correctement validée" + + except Exception as e: + 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 valider l'inscription pour la formation initiale" + + + +""" +Mise à jour de la liste des evaluations et type d'evaluation +auxquels sont inscrit un apprenant +""" + + +def Update_AcceptAttendeeInscription_For_Initial_Formation(diction): + try: + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', 'inscription_id', 'class_id', 'list_eu', 'list_eu_eval'] + 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 ne sont pas correctes" + + 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 + + formation_initiale = "0" + if ("formation_initiale" in my_partner.keys()): + formation_initiale = my_partner['formation_initiale'] + + if (formation_initiale != "1"): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Il ne s'agit pas d'un formation initiale ") + return True, [] + + + """ + Recuper la liste des UE + """ + list_eu_json = ast.literal_eval(diction['list_eu']) + + """ + Recuper la liste des evaluations UE + """ + list_eu_eval_json = ast.literal_eval(diction['list_eu_eval']) + + print(" ### list_eu_json = ", list_eu_json) + + print(" ### list_eu_eval_json = ", list_eu_eval_json) + + # Verifier que la nouvelle liste des UE est valide et appartient bien à la formation. + for local_val in list_eu_json: + is_ue_include_in_class_count = MYSY_GV.dbname['myclass'].count_documents({'valide':'1','locked':'0', + 'partner_owner_recid':my_partner['recid'], + 'list_unite_enseignement._id':str(local_val['_id']), + '_id':ObjectId(str(diction['class_id']))}) + + if( is_ue_include_in_class_count != 1 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de l'UE "+str(local_val)+" n'est pas valide ") + return True, " L'identifiant de l'UE "+str(local_val['_id'])+" n'est pas valide " + + is_ue_valide = MYSY_GV.dbname['unite_enseignement'].count_documents({'_id':ObjectId(str(local_val['_id'])), + 'valide':'1', + 'locked':'0', + 'partner_owner_recid':my_partner['recid']}) + + + if( is_ue_valide != 1 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de l'UE " + str(local_val) + " n'est pas valide (2) ") + return True, " L'identifiant de l'UE " + str(local_val['_id']) + " n'est pas valide (2)" + + + + """ + Verifier que les types d'evaluations sont valides pour les ue + """ + for local_val in list_eu_eval_json: + + is_evaluation_ok_for_class_and_ue = MYSY_GV.dbname['class_unite_enseignement_type_evaluation'].count_documents({'valide': '1', 'locked': '0', + 'partner_owner_recid': my_partner[ 'recid'], + 'class_id': str(diction['class_id']), + '_id': ObjectId( str(local_val['_id']))}) + + if (is_evaluation_ok_for_class_and_ue != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant du type d'evaluation " + str(local_val) + " n'est pas valide ") + return True, " L'identifiant du type d'evaluation " + str(local_val['_id']) + " n'est pas valide " + + + + """ + Verifier que l'inscription est valide + """ + is_valide_inscription_count = MYSY_GV.dbname['inscription'].count_documents( + {'_id': ObjectId(diction['inscription_id']), + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1'}) + + if (is_valide_inscription_count != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de l'inscrit est invalide ") + return False, " L'identifiant de l'inscrit est invalide " + + """ + Verifier la validité de la formation et créer le contenu de la collection + """ + is_valide_class_count = MYSY_GV.dbname['myclass'].count_documents( + {'_id': ObjectId(diction['class_id']), + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked': '0'}) + + if (is_valide_class_count != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de la formation est invalide ") + return False, " L'identifiant de la formation est invalide " + + """ + Suppression des données existe dans les collections : inscription_liste_ue et inscription_liste_ue_type_eval + pour l'inscrit et la formation conernée + """ + + clean_inscription_liste_ue = MYSY_GV.dbname['inscription_liste_ue'].delete_many( + {"partner_owner_recid": str(my_partner['recid']), + 'class_id': str(diction['class_id']), 'inscription_id': str(diction['inscription_id']), }) + + + qry_del = {"partner_owner_recid": str(my_partner['recid']), + 'class_id': str(diction['class_id']), 'inscription_id': str(diction['inscription_id']) } + + #print(' qry_delete === ', qry_del) + + clean_inscription_liste_ue_type_eval = MYSY_GV.dbname['inscription_liste_ue_type_evalution'].delete_many(qry_del) + + #mycommon.myprint( " ela-Token - " + str(clean_inscription_liste_ue_type_eval.deleted_count) + " documents deleted. ") + + """ + Recuperer les UE de la formation + """ + tab_class_ue_id = [] + + qry = {"partner_owner_recid": str(my_partner['recid']), 'valide': '1', 'locked': '0', + '_id': ObjectId(str(diction['class_id']))} + + """ + Remplissage de la collection : inscription_liste_ue + """ + + for New_retVal in list_eu_json: + + tab_class_ue_id.append(str(local_val['_id'])) + + new_data = {} + new_data['inscription_id'] = str(diction['inscription_id']) + new_data['class_id'] = str(diction['class_id']) + new_data['class_eu_id'] = str(New_retVal['_id']) + + new_data['update_date'] = str(datetime.now()) + new_data['update_by'] = str(my_partner['_id']) + new_data['partner_owner_recid'] = str(my_partner['recid']) + new_data['valide'] = "1" + new_data['locked'] = "0" + + key_data = {} + key_data['inscription_id'] = str(diction['inscription_id']) + key_data['class_id'] = str(diction['class_id']) + key_data['class_eu_id'] = str(New_retVal['_id']) + key_data['valide'] = "1" + key_data['partner_owner_recid'] = str(my_partner['recid']) + + result = MYSY_GV.dbname['inscription_liste_ue'].find_one_and_update( + key_data, + {"$set": new_data}, + upsert=True, + return_document=ReturnDocument.AFTER + ) + if ("_id" not in result.keys()): + mycommon.myprint( + " Impossible de mettre à jour la liste des UE de l'inscrit (2) ") + return False, "Impossible de mettre à jour la liste des UE de l'inscrit (2) " + + """ + Remplissage de la collection : inscription_liste_ue_type_eval + """ + + for val in list_eu_eval_json: + new_data = {} + new_data['inscription_id'] = str(diction['inscription_id']) + new_data['class_id'] = str(diction['class_id']) + new_data['class_eu_id'] = str(val['class_ue_id']) + new_data['type_evaluation_id'] = str(val['type_evaluation_id']) + + new_data['update_date'] = str(datetime.now()) + new_data['update_by'] = str(my_partner['_id']) + new_data['partner_owner_recid'] = str(my_partner['recid']) + new_data['valide'] = "1" + new_data['locked'] = "0" + + key_data = {} + key_data['inscription_id'] = str(diction['inscription_id']) + key_data['class_id'] = str(diction['class_id']) + key_data['class_eu_id'] = str(local_val['_id']) + key_data['valide'] = "1" + key_data['partner_owner_recid'] = str(my_partner['recid']) + + result = MYSY_GV.dbname['inscription_liste_ue_type_evalution'].find_one_and_update( + key_data, + {"$set": new_data}, + upsert=True, + return_document=ReturnDocument.AFTER + ) + if ("_id" not in result.keys()): + mycommon.myprint( + " Impossible de mettre à jour les UE et Evaluations de l'apprenant (2) ") + return False, "Impossible de mettre à jour les UE et Evaluations de l'apprenant (2) " + + return True, "La mise à jour a été correctement faite" + + except Exception as e: + 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 mettre à jour les UE et Evaluations de l'apprenant " + + +""" +Fontion de validation / acceptation d'une inscription + +23/07/2024 : +A la validation, on regarde si l'inscription a un 'client_rattachement_id' alors on considère qu'il +s'agit d'une inscription pour un client, on met le champ 'entreprise' à '1', si non à '0' + +10/03/2026 - S'il s'agit d'une promotion, alors apres l'acceptation de l'inscrit +on va l'jouter au groupe "promo" associé +""" +def AcceptAttendeeInscription(diction): + try: + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', 'email', '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, " Les informations fournies ne sont pas correctes" + + 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'] + + # 0 - Verifier de l'existance et de la validité de l'inscription (preinscription à refuser) + my_inscription_count = MYSY_GV.dbname['inscription'].count_documents({'_id':ObjectId(str(diction['inscription_id'])), + 'partner_owner_recid':str(partner_recid)}) + if( my_inscription_count <= 0 ): + mycommon.myprint(str(inspect.stack()[0][3]) + " - L'identifiant d'inscription est invalide") + return False, "L'identifiant d'inscription est invalide" + + + data_mail = {} + + + + # 2 - Recuperation des données de l'inscription + local_inscription = MYSY_GV.dbname['inscription'].find({'_id': ObjectId(str(diction['inscription_id'])), + 'email': str(diction['email']), + 'partner_owner_recid':str(partner_recid)}) + entreprise = "0" + if ("client_rattachement_id" in local_inscription[0].keys()): + if local_inscription[0]['client_rattachement_id']: + entreprise = "1" + + lms_class_code = "" + if ("lms_class_code" in local_inscription[0].keys()): + if local_inscription[0]['lms_class_code']: + lms_class_code = local_inscription[0]['lms_class_code'] + + lms_user_id = "" + if ("lms_user_id" in local_inscription[0].keys()): + if local_inscription[0]['lms_user_id']: + lms_user_id = local_inscription[0]['lms_user_id'] + + nom = "" + if ("nom" in local_inscription[0].keys()): + if local_inscription[0]['nom']: + nom = local_inscription[0]['nom'] + + prenom = "" + if ("prenom" in local_inscription[0].keys()): + if local_inscription[0]['prenom']: + prenom = local_inscription[0]['prenom'] + + email = "" + if ("email" in local_inscription[0].keys()): + if local_inscription[0]['email']: + email = local_inscription[0]['email'] + + date_du = "" + if ("date_du" in local_inscription[0].keys()): + if local_inscription[0]['date_du']: + date_du = str(local_inscription[0]['date_du'])[0:10] + + date_au = "" + if ("date_au" in local_inscription[0].keys()): + if local_inscription[0]['date_au']: + date_au = str(local_inscription[0]['date_au'])[0:10] + + # 3 - Recuperation des données de la formation + local_class = MYSY_GV.dbname['myclass'].find({'internal_url': str(local_inscription[0]['class_internal_url']), + 'partner_owner_recid':str(partner_recid)}) + data_mail['title'] = local_class[0]['title'] + class_title = local_class[0]['title'] + + class_inscription_directe = "" + if( "inscription_direct" in local_class[0].keys()): + class_inscription_directe = local_class[0]['inscription_direct'] + + + # Recuperation des données de la session + local_session = MYSY_GV.dbname['session_formation'].find_one( + {'_id': ObjectId(str(local_inscription[0]['session_id'])), + 'valide':'1', 'partner_owner_recid':str(partner_recid)}) + + if (local_session is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer les données de la session ") + return False, " Impossible de récupérer les données de la session " + + lms_class_code = "" + if( "lms_class_code" in local_class[0].keys() ): + if(len(str(local_class[0]['lms_class_code'])) > 2 ): + lms_class_code = str(local_class[0]['lms_class_code']) + + + session_end_date = "" + if( "date_fin" in local_session.keys() ): + session_end_date = str(local_session['date_fin']).strip()[0:10] + + """ + Inscription sur le LMS : + Si la formation associée à la session possede un code de formation lms 'lms_class_code' + + Alors cela veut dire que c'est une formation qui est gérée avec le LMS de MYSY. + Donc l'inscription va generer : + 1 - La creation du compte LMS participant + 2 - L'inscription de l'utilisateur à la formation. + 3 - Envoie par email des accès a l'apprenant + + """ + return_message = " Inscription validée avec warning : " + is_warning_message = 0 + + if( str(lms_class_code) != ""): + new_diction = {} + new_diction['token'] = diction['token'] + new_diction['lastname'] = nom + new_diction['firstname'] = prenom + new_diction['email'] = email + new_diction['password'] = secrets.token_urlsafe(6) + new_diction['locked'] = "0" + new_diction['username'] = email + new_diction['session_end_date'] = session_end_date + + # 01/02/2025 : gestion date fin validité compte lms. Par defaut la session est active 30 jours apres la fin de la session + local_session_end_date = datetime.strptime(str(session_end_date).strip(), '%d/%m/%Y') + local_lms_access_end_date = local_session_end_date+timedelta(days=30) + local_lms_access_end_date_formated = str(local_lms_access_end_date.strftime("%d/%m/%Y")) + + + local_status, local_message, local_participant_lms_id = mys_lms.Create_MySy_LMS_Apprenant(new_diction) + + if (local_status is False): + mycommon.myprint(str(inspect.stack()[0][3]) + " WARNING : le compte LSM n'a pas été correctement crée") + return_message = return_message + " - Le compte LSM n'a pas été correctement crée. \n" + is_warning_message = 1 + else: + """ + Mettre à jour la collection "inscription" en ajoutant local_participant_lms_id et et le mot de passe + et la date d'expiration du compte LMS + """ + + local_ret_val = MYSY_GV.dbname['inscription'].find_one_and_update( + {'_id': ObjectId(str(diction['inscription_id'])), 'partner_owner_recid':str(my_partner['recid'])}, + {"$set": {'lms_user_id': str(local_participant_lms_id), + 'lms_pwd': str(new_diction['password']), + 'lms_class_code': str(lms_class_code), + 'lms_account_expiration_date':str(local_lms_access_end_date_formated)} + }, + upsert=False, + return_document=ReturnDocument.AFTER + ) + if (local_ret_val and local_ret_val['_id']): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " Le compte LMS du participant a été correctement mis à jour : local_ret_val['_id'] = " + str( + local_ret_val['_id'])) + """" + A present, on va proceder à l'inscription à la formation + """ + print(" ### Debut de l'inscription à la formation dans le LMS ") + new_diction = {} + new_diction['token'] = diction['token'] + new_diction['user_lms_id'] = local_participant_lms_id + new_diction['course_code'] = lms_class_code + + local_status2, local_message2 = mys_lms.Add_User_To_LMS_Class(new_diction) + if (local_status2 is False): + mycommon.myprint( + str(inspect.stack()[0][3]) + " WARNING : Impossbile de finaliser l'inscription dans le LMS") + return_message = return_message + " - Impossbile de finaliser l'inscription dans le LMS. "+str(local_message2)+" \n" + is_warning_message = 1 + else: + mycommon.myprint( + str(inspect.stack()[0][3]) + " TOP, l'inscription dans le LMS a ete correctement faite") + + """ + 11/07/2025 : + Vu que l'inscription est ok, on va envoyer les credentials à l'inscrit + si et seulement local_session['lms_account_automatic'] == "1" + """ + if( local_session and "lms_account_automatic" in local_session.keys() and local_session['lms_account_automatic'] == "1"): + + print(" ### AUTOMATIC INSCRIPTION LMS a faire zzzzzz") + local_node_send_credential = {} + local_node_send_credential['token'] = diction['token'] + local_node_send_credential['class_internal_url'] = local_ret_val['class_internal_url'] + local_node_send_credential['session_id'] = local_ret_val['session_id'] + local_node_send_credential['email'] = local_ret_val['email'] + local_node_send_credential['nom'] = local_ret_val['nom'] + local_node_send_credential['prenom'] = local_ret_val['prenom'] + + local_node_send_credential['date_du'] = local_ret_val['date_du'] + local_node_send_credential['date_au'] = local_ret_val['date_au'] + local_node_send_credential['title'] = str(class_title) + + local_node_send_credential['login'] = local_ret_val['email'] + local_node_send_credential['pwd'] = local_ret_val['lms_pwd'] + local_node_send_credential['lms_url'] = str(my_partner['lms_virtualhost_url']) + + local_node_send_credential['course_owner_email'] = my_partner['email'] + local_node_send_credential['partner_recid'] = my_partner['recid'] + + local_node_send_credential['inscription_id'] = str(local_ret_val['_id']) + local_node_send_credential['session_code'] = str(local_session['code_session']) + + # split_mail_tab = str(email).split('@') + # email_data['login'] = split_mail_tab[0] + print(" ### local_node_send_credential = ", local_node_send_credential) + + local_status, local_message = email_session.LMS_Credential_Sending_mail(local_node_send_credential) + if (local_status is False): + mycommon.myprint(str( + inspect.stack()[0][ + 3]) + " - WARNING : Impossible d'envoyer le mail de notification pour " + str( + diction['email'])) + return_message = return_message + str( + " Impossible d'envoyer le mail de notification pour : " + str(diction['email'])) + + + else: + mycommon.myprint( + str(inspect.stack()[0][3]) + " - WARNING : Impossible de mettre à jour le compte LMS ") + return_message = return_message + " - Impossible de mettre à jour le compte LMS. \n" + is_warning_message = 1 + + + + # date de validation de l'inscription + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + + ret_val2 = MYSY_GV.dbname['inscription'].find_one_and_update( + {'_id': ObjectId( str(diction['inscription_id'])), 'email': str(diction['email']), 'partner_owner_recid':str(my_partner['recid'])}, + {"$set": {'status':'1', 'inscription_validation_date':now, 'date_update':now, 'entreprise':str(entreprise) + }}, + return_document=ReturnDocument.AFTER, + upsert=False, + ) + + if( ret_val2 is None ): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de valider l'inscription (1) ") + return False, " Impossible de valider l'inscription (2) " + + """ + Verification s'il y a une inscription LMS, au quel cas, on l'annule aussi + """ + + """ + 26/02/2025 : + Si le paramettre, 'inscription_notification_email' de la collection 'base_partner_setup' est à 1, + alors on envoie un email de notification à l'apprenant + """ + local_insc_status, local_insc_retval = mycommon.Is_Partnair_Inscription_Notification({'token':diction['token']}) + if( local_insc_status and str(local_insc_retval) == "1"): + email_data = {} + email_data['nom'] = nom + email_data['prenom'] = prenom + email_data['email'] = email + email_data['date_du'] = date_du + email_data['date_au'] = date_au + email_data['title'] = class_title + email_data['partner_owner_recid'] = str(partner_recid) + email_data['token'] = str(diction['token']) + email_data['class_inscription_directe'] = class_inscription_directe + + if ("_id" in local_session.keys()): + email_data['session_id'] = str(local_session['_id']) + else: + email_data['session_id'] = "" + + + if( "code_session" in local_session.keys()): + email_data['code_session'] = local_session['code_session'] + else: + email_data['code_session'] = "" + + if ("date_debut" in local_session.keys()): + email_data['date_debut'] = local_session['date_debut'] + else: + email_data['date_debut'] = "" + + session_presentiel = "" + session_distantiel = "" + session_hybrid = "" + if ("mode_animation" in local_session.keys() and local_session['mode_animation']): + if (str(local_session['mode_animation']) == "1"): + session_presentiel = "" + session_distantiel = "1" + session_hybrid = "" + elif (str(local_session['mode_animation']) == "2"): + session_presentiel = "" + session_distantiel = "" + session_hybrid = "1" + elif (str(local_session['mode_animation']) == "0"): + session_presentiel = "1" + session_distantiel = "" + session_hybrid = "" + + + email_data['distantiel'] = str(session_distantiel) + email_data['presentiel'] = str(session_presentiel) + email_data['hybrid'] = str(session_hybrid) + + + + if ("session_ondemande" in local_session.keys()): + email_data['session_ondemande'] = local_session['session_ondemande'] + else: + email_data['session_ondemande'] = "" + + if ("adresse" in local_session.keys()): + email_data['adresse'] = local_session['adresse'] + else: + email_data['adresse'] = "" + + if ("code_postal" in local_session.keys()): + email_data['code_postal'] = local_session['code_postal'] + else: + email_data['code_postal'] = "" + + if ("ville" in local_session.keys()): + email_data['ville'] = local_session['ville'] + else: + email_data['ville'] = "" + + if ("pays" in local_session.keys()): + email_data['pays'] = local_session['pays'] + else: + email_data['pays'] = "" + + if ("formateur" in local_session.keys()): + email_data['formateur'] = local_session['formateur'] + else: + email_data['formateur'] = "" + + if ("ville" in local_session.keys()): + email_data['ville'] = local_session['ville'] + else: + email_data['ville'] = "" + + if ("mode_animation_detail_organisation" in local_session.keys()): + email_data['mode_animation_detail_organisation'] = local_session['mode_animation_detail_organisation'] + else: + email_data['mode_animation_detail_organisation'] = "" + + print(" ### 2izmmm er envoie emailll email_data = ", email_data) + local_status, local_message = email_session.incription_training_confirmation_mail(email_data) + if( local_status is False ): + mycommon.myprint(str( + inspect.stack()[0][3]) + " - WARNING : Impossible d'envoyer le mail de notification pour " + str( + diction['email'])) + return_message = return_message + str(" - Impossible d'envoyer le mail de notification pour : " + str(diction['email'])+" \n") + is_warning_message = 1 + + + + + """ + A présent que l'inscription s'est bien passée, on va créer le dossier apprenant + """ + inscription_data = MYSY_GV.dbname['inscription'].find_one({'_id': ObjectId( str(diction['inscription_id'])), + 'email': str(diction['email']), + 'partner_owner_recid':str(my_partner['recid'])}) + + new_apprenant_diction = {} + new_apprenant_diction['token'] = str(diction['token']) + new_apprenant_diction['nom'] = inscription_data['nom'] + new_apprenant_diction['email'] = inscription_data['email'] + new_apprenant_diction['prenom'] = inscription_data['prenom'] + new_apprenant_diction['civilite'] = "" + + if( "civilite" in inscription_data.keys()): + new_apprenant_diction['civilite'] = str(inscription_data['civilite']).lower() + else: + new_apprenant_diction['civilite'] = "" + + if (str(new_apprenant_diction['civilite']) not in MYSY_GV.CIVILITE): + new_apprenant_diction['civilite'] = "neutre" + + if( str(new_apprenant_diction['civilite']).strip() == ""): + new_apprenant_diction['civilite'] = "neutre" + + + if("telephone" in inscription_data.keys()): + new_apprenant_diction['telephone'] = inscription_data['telephone'] + else: + new_apprenant_diction['telephone'] = "" + + if ("employeur" in inscription_data.keys()): + new_apprenant_diction['employeur'] = inscription_data['employeur'] + else: + new_apprenant_diction['employeur'] = "" + + if("client_rattachement_id" in inscription_data.keys()): + new_apprenant_diction['client_rattachement_id'] = inscription_data['client_rattachement_id'] + else: + new_apprenant_diction['client_rattachement_id'] = "" + + + if("adresse" in inscription_data.keys()): + new_apprenant_diction['adresse'] = inscription_data['adresse'] + else: + new_apprenant_diction['adresse'] = "" + + + if("code_postal" in inscription_data.keys()): + new_apprenant_diction['code_postal'] = inscription_data['code_postal'] + else: + new_apprenant_diction['code_postal'] = "" + + if("ville" in inscription_data.keys()): + new_apprenant_diction['ville'] = inscription_data['ville'] + else: + new_apprenant_diction['ville'] = "" + + if("pays" in inscription_data.keys()): + new_apprenant_diction['pays'] = inscription_data['pays'] + else: + new_apprenant_diction['pays'] = "" + + if("tuteur1_nom" in inscription_data.keys()): + new_apprenant_diction['tuteur1_nom'] = inscription_data['tuteur1_nom'] + else: + new_apprenant_diction['tuteur1_nom'] = "" + + if("tuteur1_prenom" in inscription_data.keys()): + new_apprenant_diction['tuteur1_prenom'] = inscription_data['tuteur1_prenom'] + else: + new_apprenant_diction['tuteur1_prenom'] = "" + + if("tuteur1_email" in inscription_data.keys()): + new_apprenant_diction['tuteur1_email'] = inscription_data['tuteur1_email'] + else: + new_apprenant_diction['tuteur1_email'] = "" + + if("tuteur1_telephone" in inscription_data.keys()): + new_apprenant_diction['tuteur1_telephone'] = inscription_data['tuteur1_telephone'] + else: + new_apprenant_diction['tuteur1_telephone'] = "" + + new_apprenant_diction['tuteur1_civilite'] = "" + if ("tuteur1_civilite" in inscription_data.keys()): + new_apprenant_diction['tuteur1_civilite'] = inscription_data['tuteur1_civilite'] + else: + new_apprenant_diction['tuteur1_civilite'] = "" + + if( str(new_apprenant_diction['tuteur1_civilite']).strip() == ""): + new_apprenant_diction['tuteur1_civilite'] = "neutre" + + new_apprenant_diction['tuteur2_civilite'] = "" + if ("tuteur2_civilite" in inscription_data.keys()): + new_apprenant_diction['tuteur2_civilite'] = inscription_data['tuteur2_civilite'] + else: + new_apprenant_diction['tuteur2_civilite'] = "" + if (str(new_apprenant_diction['tuteur2_civilite']).strip() == ""): + new_apprenant_diction['tuteur2_civilite'] = "neutre" + + + if("tuteur2_nom" in inscription_data.keys()): + new_apprenant_diction['tuteur2_nom'] = inscription_data['tuteur2_nom'] + else: + new_apprenant_diction['tuteur2_nom'] = "" + + if("tuteur2_email" in inscription_data.keys()): + new_apprenant_diction['tuteur2_prenom'] = inscription_data['tuteur2_email'] + else: + new_apprenant_diction['tuteur2_prenom'] = "" + + + if("tuteur2_email" in inscription_data.keys()): + new_apprenant_diction['tuteur2_email'] = inscription_data['tuteur2_email'] + else: + new_apprenant_diction['tuteur2_email'] = "" + + if ("tuteur2_telephone" in inscription_data.keys()): + new_apprenant_diction['tuteur2_telephone'] = inscription_data['tuteur2_telephone'] + else: + new_apprenant_diction['tuteur2_telephone'] = "" + + + if ("opco" in inscription_data.keys()): + new_apprenant_diction['opco'] = inscription_data['opco'] + else: + new_apprenant_diction['opco'] = "" + + if ("tuteur1_adresse" in inscription_data.keys()): + new_apprenant_diction['tuteur1_adresse'] = inscription_data['tuteur1_adresse'] + else: + new_apprenant_diction['tuteur1_adresse'] = "" + + if ("tuteur1_cp" in inscription_data.keys()): + new_apprenant_diction['tuteur1_cp'] = inscription_data['tuteur1_cp'] + else: + new_apprenant_diction['tuteur1_cp'] = "" + + if ("tuteur1_ville" in inscription_data.keys()): + new_apprenant_diction['tuteur1_ville'] = inscription_data['tuteur1_ville'] + else: + new_apprenant_diction['tuteur1_ville'] = "" + + if ("tuteur1_pays" in inscription_data.keys()): + new_apprenant_diction['tuteur1_pays'] = inscription_data['tuteur1_pays'] + else: + new_apprenant_diction['tuteur1_pays'] = "" + + if ("tuteur1_include_com" in inscription_data.keys()): + new_apprenant_diction['tuteur1_include_com'] = inscription_data['tuteur1_include_com'] + else: + new_apprenant_diction['tuteur1_include_com'] = "0" + + if ("tuteur2_adresse" in inscription_data.keys()): + new_apprenant_diction['tuteur2_adresse'] = inscription_data['tuteur2_adresse'] + else: + new_apprenant_diction['tuteur2_adresse'] = "" + + if ("tuteur2_cp" in inscription_data.keys()): + new_apprenant_diction['tuteur2_cp'] = inscription_data['tuteur2_cp'] + else: + new_apprenant_diction['tuteur2_cp'] = "" + + if ("tuteur2_ville" in inscription_data.keys()): + new_apprenant_diction['tuteur2_ville'] = inscription_data['tuteur2_ville'] + else: + new_apprenant_diction['tuteur2_ville'] = "" + + + if ("tuteur2_pays" in inscription_data.keys()): + new_apprenant_diction['tuteur2_pays'] = inscription_data['tuteur2_pays'] + else: + new_apprenant_diction['tuteur2_pays'] = "" + + if ("tuteur2_include_com" in inscription_data.keys()): + new_apprenant_diction['tuteur2_include_com'] = inscription_data['tuteur2_include_com'] + else: + new_apprenant_diction['tuteur2_include_com'] = "0" + + """ + # Si la personne de cette inscription existe deja dans la collection appenant, alors on fait une mise à jour. + En effet si l'apprenant avait deja suivi une formation, alors il a forcement un dossier. + a clé est toujours l'adresse email + """ + local_apprenant_id = "" + is_apprenant_existe_count = MYSY_GV.dbname['apprenant'].count_documents({'email':str(inscription_data['email']), + 'partner_owner_recid':str(my_partner['recid']), + 'valide':'1', + 'locked':'0'}) + + + + if( is_apprenant_existe_count > 0 ): + # Il faut mettre à jour un dossier apprenant + is_apprenant_existe = MYSY_GV.dbname['apprenant'].find_one( + {'email': str(inscription_data['email']), + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked': '0'}, {'_id':1}) + + new_apprenant_diction['_id'] = str(is_apprenant_existe['_id']) + local_apprenant_id = str(is_apprenant_existe['_id']) + + if ("tab_ue_ids" in new_apprenant_diction.keys()): + del new_apprenant_diction['tab_ue_ids'] + + if( "price" in new_apprenant_diction.keys() ): + del new_apprenant_diction['price'] + + + + local_status, local_retval = apprenant_mgt.Update_Apprenant(new_apprenant_diction) + if (local_status is False): + return local_status, local_retval + + else: + # Il faut créer un dossier apprenant + if ("tab_ue_ids" in new_apprenant_diction.keys()): + del new_apprenant_diction['tab_ue_ids'] + + local_status, local_retval = apprenant_mgt.Add_Apprenant(new_apprenant_diction) + if( local_status is False): + return local_status, local_retval + """ + recuperation de l'id du dossier qui vient d'etre créer + """ + apprenant_data = MYSY_GV.dbname['apprenant'].find_one({'email': str(inscription_data['email']), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}, + {'_id': 1}) + + if (apprenant_data is None): + mycommon.myprint(str( + inspect.stack()[0][3]) + " Impossible de récuperer l'identifiant du dossier créé ") + return False, " Impossible de récuperer l'identifiant du dossier créé " + + local_apprenant_id = str(apprenant_data['_id']) + + + """ + Apres la creation du dossier on met à jour l'inscription en rajoutant l'apprenant_id + """ + ret_val2 = MYSY_GV.dbname['inscription'].find_one_and_update( + {'_id': ObjectId(str(diction['inscription_id'])), 'email': str(diction['email']), 'partner_owner_recid':str(my_partner['recid'])}, + {"$set": {'apprenant_id': str(local_apprenant_id), 'date_update':str(datetime.now()), + 'update_by':str(my_partner['_id'])}}, + return_document=ReturnDocument.AFTER, + upsert=False, + ) + + + """ + Creation des acces à l'ENT si et seulement si Si l'ent_account_automatic =='1' + && si l'apprenant n'a pas deja de compte + """ + if (local_session and "ent_account_automatic" in local_session.keys() and local_session[ 'ent_account_automatic'] == "1"): + data_key = {} + data_key['type'] = 'student' + data_key['apprenant_id'] = str(local_apprenant_id) + data_key['partner_owner_recid'] = str(my_partner['recid']) + + is_user_ent_acces = MYSY_GV.dbname['user_account'].count_documents(data_key) + + if( is_user_ent_acces <= 0 ): + local_diction_create_ent_acces = {} + local_diction_create_ent_acces['token'] = diction['token'] + local_diction_create_ent_acces['tab_apprenant_ids'] = str(local_apprenant_id) + + create_ent_acces_status, create_ent_acces_retval = apprenant_mgt.ENT_Create_Apprenant_Account(local_diction_create_ent_acces) + if( create_ent_acces_status is False ): + mycommon.myprint(str( + inspect.stack()[0][3]) + " - WARNING : Impossible de créer le compte d'accès à l'espace ENT pour " + str( ret_val2['email'])) + return_message = return_message + str( + " - WARNING : Impossible de créer le compte d'accès à l'espace ENT pour " + str( ret_val2['email']) + " \n") + is_warning_message = 1 + + + + + """ + 10/03/2026 - s'il s'agit d'une promo, alors on inscrit la personne si on a un groupe "type_promo" + on va recuperer le type de groupe (groupe_inscription_type) ayant is_promotion_grp = '1' + """ + if( "type_session" in local_session and local_session['type_session'] == "1"): + + groupe_inscription_type_promo_data = MYSY_GV.dbname['groupe_inscription_type'].find_one({'is_promotion_grp':'1', + 'valide':'1','locked':'0', + 'partner_owner_recid':str(my_partner['recid'])}) + + if( groupe_inscription_type_promo_data ): + + groupe_promo = MYSY_GV.dbname['groupe_inscription'].find_one({'groupe_inscription_type_id':str(groupe_inscription_type_promo_data['_id']), + 'session_id':str(local_session['_id']), + 'partner_owner_recid':str(my_partner['recid'])}) + + + + if( groupe_promo): + local_diction = {} + local_diction['token'] = diction['token'] + local_diction['_id'] = str(groupe_promo['_id']) + local_diction['tab_inscriptions_ids'] = str(diction['inscription_id']) + + add_to_groupe_status, add_to_groupe_retval = groupe_inscrit_mgt.Add_Update_Groupe_Inscrit_Membres(local_diction) + if (add_to_groupe_status is False): + mycommon.myprint(str( + inspect.stack()[0][3]) + " WARNING : Impossible d'ajouter l'inscrit "+str(diction['inscription_id'])+" au groupe promo") + + + + """ + 12/10/2024 - loguer les action dans l'historique général + + """ + ## Add to log history pour l'inscrit 'inscription' + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + history_event_dict = {} + history_event_dict['token'] = str(mytoken) + history_event_dict['related_collection'] = "inscription" + history_event_dict['related_collection_recid'] = str(diction['inscription_id']) + history_event_dict['action_date'] = str(now) + + local_session_info = "" + + if( "code_session" in local_session.keys() ): + local_session_info = local_session_info+ ", Code Session : "+local_session["code_session"] + + history_event_dict['action_description'] = "Validation inscription à "+str(local_session_info) + 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)) + + ## Add to log history pour la session 'session_formation' + history_event_dict = {} + history_event_dict['token'] = str(mytoken) + history_event_dict['related_collection'] = "session_formation" + history_event_dict['related_collection_recid'] = str(local_session['_id']) + history_event_dict['action_date'] = str(now) + + local_inscrit_info = "" + if ("_id" in local_inscription[0].keys() ): + local_inscrit_info = "_Id Inscrit : " + str(local_inscription[0]["_id"]) + if ("email" in local_inscription[0].keys()): + local_inscrit_info = local_inscrit_info + ", " + local_inscription[0]["email"] + + if ("nom" in local_inscription[0].keys()): + local_inscrit_info = local_inscrit_info + ", " + local_inscription[0]["nom"] + + if ("prenom" in local_inscription[0].keys()): + local_inscrit_info = local_inscrit_info + ", " + local_inscription[0]["prenom"] + + history_event_dict['action_description'] = "Validation inscription de " + str(local_inscrit_info) + + #print(" ### laaaaaaaaa history_event_dict = ", history_event_dict) + + 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)) + + + + """ + update du 30/01/2024 : + Apres la mise à jour de l'inscription avec l'apprenant_id, + loger une action dans la collection ==> courrier_template_tracking_history + """ + + local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(my_partner, "CONF_INSCRIPTION", + str(ret_val2['session_id']), 'inscription', str(diction['inscription_id']), "") + + + + if (is_warning_message == 1): + return True, return_message + + return True, "L'inscription a été correctement validée" + + except Exception as e: + 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 valider l'inscription" + + + +""" +Cette fonction accepte une liste d'inscrit à une session de formation + + +""" +def Accept_List_AttendeeInscription(diction): + try: + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', 'list_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, " Les informations fournies ne sont pas correctes" + + 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'] + + list_inscription_id = [] + if ("list_inscription_id" in diction.keys()): + if diction['list_inscription_id']: + list_inscription_id = str(diction['list_inscription_id']).replace(",", ";").split(";") + + for inscription_id in list_inscription_id: + # Verification que l'inscription existe et qu'elle est valide et qu'elle est au statut : en cours (status =2) ou preinscrit (status = 0) + ret_val2_count = MYSY_GV.dbname['inscription'].count_documents( + {'_id': ObjectId(str(inscription_id)), 'partner_owner_recid':str(my_partner['recid']), + }, + ) + + if (ret_val2_count != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + "L'identifiant de l'inscription "+ str(inscription_id) +" n'est pas valide ") + return False, " L'identifiant de l'inscription "+ str(inscription_id) +" n'est pas valide " + + inscription_id_data = MYSY_GV.dbname['inscription'].find_one( + {'_id': ObjectId(str(inscription_id)), 'partner_owner_recid': str(my_partner['recid']), + }, + ) + + if( "status" not in inscription_id_data.keys() or inscription_id_data['status'] not in ['0', '2', '1']): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " Toutes les inscriptions doivent être au statut : en cours ou preinscription ") + return False, " Toutes les inscriptions doivent être au statut : en cours ou preinscription " + + + # Verifier que la session de formation concernée est valide + is_valide_session = MYSY_GV.dbname['session_formation'].count_documents({'_id':ObjectId(str(inscription_id_data['session_id'])), + 'partner_owner_recid':str(my_partner['recid']), + 'valide':'1'}) + + if (is_valide_session != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " L'identifiant de la session de formation "+ str(inscription_id_data['session_id']) +" n'est pas valide ") + return False, " L'identifiant de la session de formation "+ str(inscription_id_data['session_id']) +" n'est pas valide " + + + + # A present les controles sont ok sur la liste on peut valide la liste des inscription + warning_msg = "" + is_warning = "" + for inscription_id in list_inscription_id: + + inscription_id_data = MYSY_GV.dbname['inscription'].find_one( + {'_id': ObjectId(str(inscription_id)), 'partner_owner_recid': str(my_partner['recid']), + 'status':{'$in':['0', '2']} + }, + ) + + #print(" ### inscription_id_data = ",inscription_id_data) + if( inscription_id_data ): + new_diction = {} + new_diction['token'] = diction['token'] + new_diction['inscription_id'] = str(inscription_id_data['_id']) + new_diction['email'] = str(inscription_id_data['email']) + + #print(" ### new_diction = ",new_diction) + + local_status, local_retval = AcceptAttendeeInscription(new_diction) + if( local_status is False ): + is_warning = "1" + warning_msg = warning_msg + "\n"+str(local_retval) + + if( is_warning == "1" ): + return True, str(warning_msg) + + return True, "La liste des inscriptions a été validée" + + except Exception as e: + 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 valider la liste des inscriptions" + + +""" +Cette fonction supprime un stagiaire. +Important : : seuls les preinscrit, ou les inscription annulés (donc status : 0 ou -1) +""" +def DeleteAttendeeInscription(diction): + try: + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', 'email', 'class_internal_url', '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 ne sont pas correctes" + + mytoken = "" + if ("token" in diction.keys()): + if diction['token']: + mytoken = diction['token'] + + # Verifier la validité du token + retval = mycommon.check_partner_token_validity("", mytoken) + if retval is False: + return "Err_Connexion", " La session de connexion n'est pas valide" + + partner_recid = mycommon.get_parnter_recid_from_token(mytoken) + 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 récupérer le recid du partenaire" + + data_mail = {} + # 1 - Recuperation des données de la formation + local_class = MYSY_GV.dbname['myclass'].find({'internal_url': str(diction['class_internal_url'])}) + data_mail['title'] = local_class[0]['title'] + class_title = local_class[0]['title'] + + # 2 - Recuperation des données de l'inscription + local_inscription = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']), + 'email': str(diction['email']), 'class_internal_url':str(diction['class_internal_url'])}) + lms_class_code = "" + if ("lms_class_code" in local_inscription[0].keys()): + if local_inscription[0]['lms_class_code']: + lms_class_code = local_inscription[0]['lms_class_code'] + + lms_user_id = "" + if ("lms_user_id" in local_inscription[0].keys()): + if local_inscription[0]['lms_user_id']: + lms_user_id = local_inscription[0]['lms_user_id'] + + nom = "" + if ("nom" in local_inscription[0].keys()): + if local_inscription[0]['nom']: + nom = local_inscription[0]['nom'] + + prenom = "" + if ("prenom" in local_inscription[0].keys()): + if local_inscription[0]['prenom']: + prenom = local_inscription[0]['prenom'] + + email = "" + if ("email" in local_inscription[0].keys()): + if local_inscription[0]['email']: + email = local_inscription[0]['email'] + + date_du = "" + if ("date_du" in local_inscription[0].keys()): + if local_inscription[0]['date_du']: + date_du = str(local_inscription[0]['date_du'])[0:10] + + date_au = "" + if ("date_au" in local_inscription[0].keys()): + if local_inscription[0]['date_au']: + date_au = str(local_inscription[0]['date_au'])[0:10] + + + # Recuperation des données de la session + local_session = MYSY_GV.dbname['session_formation'].find_one( + {'_id': ObjectId(str(diction['session_id'])), 'class_internal_url': str(diction['class_internal_url']), 'valide':'1',}) + + if (local_session is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer les données de la session ") + return False, " Impossible de récupérer les données de la session " + + + # Verification que l'inscription existe et qu'elle est supprimable (donc status = 0 ou -1) + ret_val2_count = MYSY_GV.dbname['inscription'].count_documents( + {'session_id': str(diction['session_id']), 'email': str(diction['email']), 'class_internal_url':str(diction['class_internal_url'])}, + ) + + if( ret_val2_count != 1): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de supprimer l'inscription. Il y a plusieurs inscription pour ce mail et cette formation") + return False, " Impossible de supprimer l'inscription (1)" + + ret_val2 = MYSY_GV.dbname['inscription'].find_one( + {'session_id': str(diction['session_id']), 'email': str(diction['email']), + 'class_internal_url': str(diction['class_internal_url'])}, + ) + + if( "status" in ret_val2.keys()): + if( str(ret_val2['status']) != "0" and str(ret_val2['status']) != "-1"): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " - Impossible de supprimer l'inscription. L'inscription doit être annulée ou à l'etat 'préinscrit' avant d'être supprimé") + return False, " - Impossible de supprimer l'inscription. L'inscription doit être annulée ou à l'etat 'préinscrit' avant d'être supprimé" + + + + """ + ## Add to log history + """ + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + # Pour la collection inscription + history_event_dict = {} + history_event_dict['token'] = mytoken + history_event_dict['related_collection'] = "inscription" + history_event_dict['related_collection_recid'] = str(local_inscription[0]['_id']) + history_event_dict['action_date'] = str(now) + + local_inscrit_info = "Id Inscrit : " + str(local_inscription[0]['_id']) + if ("email" in local_inscription[0].keys()): + local_inscrit_info = local_inscrit_info + ", " + local_inscription[0]["email"] + + if ("nom" in local_inscription[0].keys()): + local_inscrit_info = local_inscrit_info + ", " + local_inscription[0]["nom"] + + if ("prenom" in local_inscription[0].keys()): + local_inscrit_info = local_inscrit_info + ", " + local_inscription[0]["prenom"] + + history_event_dict['action_description'] = "Suppression de " + str(local_inscrit_info) + 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)) + + detlete_retval = MYSY_GV.dbname['inscription'].delete_one( + {'session_id': str(diction['session_id']), 'email': str(diction['email']), + 'class_internal_url': str(diction['class_internal_url'])}, + ) + + + return True, "L'inscription a été correctement supprimée" + + except Exception as e: + 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 supprimer l'inscription " + + +""" +Fonction de suppression d'une liste de stagiaires en partant de l'_id, ceci si +les conditions sont reunies. +Important : : seuls les preinscrit, ou les inscription annulés (donc status : 0 ou -1) +""" +def Delete_List_AttendeeInscription(diction): + try: + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', 'list_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, " Les informations fournies ne sont pas correctes" + + mytoken = "" + if ("token" in diction.keys()): + if diction['token']: + mytoken = diction['token'] + + # Verifier la validité du token + retval = mycommon.check_partner_token_validity("", mytoken) + if retval is False: + return "Err_Connexion", " La session de connexion n'est pas valide" + + partner_recid = mycommon.get_parnter_recid_from_token(mytoken) + 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 récupérer le recid du partenaire" + + list_inscription_id = [] + if ("list_inscription_id" in diction.keys()): + if diction['list_inscription_id']: + list_inscription_id = str(diction['list_inscription_id']).replace(",", ";").split(";") + + data_mail = {} + + for inscription_id in list_inscription_id : + # Verification que l'inscription existe et qu'elle est supprimable (donc status = 0 ou -1) + ret_val2_count = MYSY_GV.dbname['inscription'].count_documents( + {'_id': ObjectId(str(inscription_id)), }, + ) + + if( ret_val2_count != 1): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de supprimer l'inscription. Il y a plusieurs inscription pour ce mail et cette formation") + return False, " Impossible de supprimer l'inscription (1)" + + ret_val2 = MYSY_GV.dbname['inscription'].find_one( + {'_id': ObjectId(str(inscription_id)),}, + ) + + if( "status" in ret_val2.keys()): + if( str(ret_val2['status']) != "0" and str(ret_val2['status']) != "-1"): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " - Impossible de supprimer l'inscription de l'utilisateur "+str(ret_val2['email'])+" à la session "+str(ret_val2['session_id'])+". L'inscription doit être annulée ou à l'etat 'préinscrit' avant d'être supprimé") + return False, " Impossible de supprimer l'inscription de l'utilisateur "+str(ret_val2['email'])+" à la session "+str(ret_val2['session_id'])+". L'inscription doit être annulée ou à l'etat 'préinscrit' avant d'être supprimé" + + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + for inscription_id in list_inscription_id: + + ret_val2 = MYSY_GV.dbname['inscription'].find_one( + {'_id': ObjectId(str(inscription_id)), }, + ) + + """ + ## Add to log history + """ + + # Pour la collection inscription + history_event_dict = {} + history_event_dict['token'] = mytoken + history_event_dict['related_collection'] = "inscription" + history_event_dict['related_collection_recid'] = str(ret_val2['_id']) + history_event_dict['action_date'] = str(now) + + local_inscrit_info = "Id Inscrit : " + str(ret_val2['_id']) + if ("email" in ret_val2.keys()): + local_inscrit_info = local_inscrit_info + ", " + ret_val2["email"] + + if ("nom" in ret_val2.keys()): + local_inscrit_info = local_inscrit_info + ", " + ret_val2["nom"] + + if ("prenom" in ret_val2.keys()): + local_inscrit_info = local_inscrit_info + ", " + ret_val2["prenom"] + + history_event_dict['action_description'] = "Suppression de " + str(local_inscrit_info) + 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)) + + ## pour finir on fait la suppression + + detlete_retval = MYSY_GV.dbname['inscription'].delete_one( + {'_id': ObjectId(str(inscription_id)),}, + ) + + + + return True, "La liste des inscriptions a été correctement supprimée" + + except Exception as e: + 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 supprimer la liste des inscriptions " + + + + +""" +Cette fonction envoie l'email de connexion à la plateformation LMS +au participant +Cet email met en copie le responsable de la formation. ceci pour pouvoir renvoyer le mail au besoin +""" +def Send_LMS_Credentials_to_particpants(diction): + try: + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', 'email', 'class_internal_url', '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 ne sont pas correctes" + + mytoken = "" + if ("token" in diction.keys()): + if diction['token']: + mytoken = diction['token'] + + partner_recid = mycommon.get_parnter_recid_from_token(mytoken) + 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 récupérer le recid du partenaire" + + # 0 -Recuperation des données du partenaire + local_status, my_partner = mycommon.get_partner_data_from_recid(partner_recid) + if (local_status is False): + mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données du partenaire") + return False, " - impossible de récupérer les données du partenaire" + + + # Par defaut, lms_virtualhost_url = l'url racine. + lms_virtualhost_url = MYSY_GV.MYSY_LMS_URL + if ("lms_virtualhost_url" in my_partner.keys()): + if my_partner['lms_virtualhost_url']: + lms_virtualhost_url = my_partner['lms_virtualhost_url'] + + + data_mail = {} + # 1 - Recuperation des données de la formation + local_class = MYSY_GV.dbname['myclass'].find({'internal_url': str(diction['class_internal_url'])}) + data_mail['title'] = local_class[0]['title'] + class_title = local_class[0]['title'] + + # 2 - Recuperation des données de l'inscription + local_inscription = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']), + 'email': str(diction['email'])}) + lms_class_code = "" + if ("lms_class_code" in local_inscription[0].keys()): + if local_inscription[0]['lms_class_code']: + lms_class_code = local_inscription[0]['lms_class_code'] + + lms_user_id = "" + if ("lms_user_id" in local_inscription[0].keys()): + if local_inscription[0]['lms_user_id']: + lms_user_id = local_inscription[0]['lms_user_id'] + + lms_pwd = "" + if ("lms_pwd" in local_inscription[0].keys()): + if local_inscription[0]['lms_pwd']: + lms_pwd = local_inscription[0]['lms_pwd'] + + nom = "" + if ("nom" in local_inscription[0].keys()): + if local_inscription[0]['nom']: + nom = local_inscription[0]['nom'] + + prenom = "" + if ("prenom" in local_inscription[0].keys()): + if local_inscription[0]['prenom']: + prenom = local_inscription[0]['prenom'] + + email = "" + if ("email" in local_inscription[0].keys()): + if local_inscription[0]['email']: + email = local_inscription[0]['email'] + + date_du = "" + if ("date_du" in local_inscription[0].keys()): + if local_inscription[0]['date_du']: + date_du = str(local_inscription[0]['date_du'])[0:10] + + date_au = "" + if ("date_au" in local_inscription[0].keys()): + if local_inscription[0]['date_au']: + date_au = str(local_inscription[0]['date_au'])[0:10] + + # Recuperation des données de la session + local_session = MYSY_GV.dbname['session_formation'].find_one( + {'_id': ObjectId(str(diction['session_id'])), + 'class_internal_url': str(diction['class_internal_url']), 'valide':'1',}) + + if (local_session is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer les données de la session ") + return False, " Impossible de récupérer les données de la session " + + + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + return_message = "" + email_data = {} + email_data['nom'] = nom + email_data['prenom'] = prenom + email_data['email'] = email + email_data['date_du'] = date_du + email_data['date_au'] = date_au + email_data['title'] = class_title + + email_data['login'] = email + email_data['pwd'] = lms_pwd + email_data['lms_url'] = str(lms_virtualhost_url) + email_data['course_owner_email'] = my_partner['email'] + email_data['partner_recid'] = my_partner['recid'] + email_data['token'] = str(mytoken) + email_data['inscription_id'] = str(local_inscription[0]['_id']) + email_data['session_code'] = str(local_session['code_session']) + + + #split_mail_tab = str(email).split('@') + #email_data['login'] = split_mail_tab[0] + + + local_status, local_message = email_session.LMS_Credential_Sending_mail(email_data) + if (local_status is False): + mycommon.myprint(str( + inspect.stack()[0][3]) + " - WARNING : Impossible d'envoyer le mail de notification pour " + str( + diction['email'])) + return_message = return_message + str( + " Impossible d'envoyer le mail de notification pour : " + str(diction['email'])) + + if (return_message.strip() != ""): + return True, return_message + + + return True, " Les informations de connexion ont été correctement envoyées" + + except Exception as e: + 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 d'envoyer les informations de connexion à la plateforme LMS" + +""" +Cette fonction ajoute une image de profil d'un stagaire +""" +def Update_Stagiaire_Image(file_img=None, Folder=None, 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 = ['token', 'file_img_recid', 'class_internal_url', 'session_id', 'email', ] + + + 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 + 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 + + class_internal_url = "" + if ("class_internal_url" in diction.keys()): + if diction['class_internal_url']: + class_internal_url = diction['class_internal_url'] + + session_id = "" + if ("session_id" in diction.keys()): + if diction['session_id']: + session_id = diction['session_id'] + + email = "" + if ("email" in diction.keys()): + if diction['email']: + email = diction['email'] + + + ## Recuperation de l'"_id" du stagiaire -- Exceptionnement on va mettre dans "_id" dans le 'related_collection_recid' + local_retval = MYSY_GV.dbname['inscription'].find_one({'class_internal_url':str(class_internal_url), + 'session_id':str(session_id), 'email':str(email) }) + if( local_retval is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " : Le stagiaire "+str(email)+" n'est pas reconnu pour la session bb"+str(str(session_id)) ) + return False, " Le stagiaire n'est pas reconnu " + + + """ + A present que le partenaire est mis à jour / créé, on va mettre à jour les image logo et image cachet s'il y en a + """ + + + if( file_img ): + recordimage_diction = {} + recordimage_diction['token'] = diction['token'] + recordimage_diction['related_collection'] = "inscription" + recordimage_diction['type_img'] = "user" + recordimage_diction['related_collection_recid'] = str(local_retval['_id']) + recordimage_diction['image_recid'] = diction['file_img_recid'] + + print(" ### recordimage_diction stagaire = ", recordimage_diction) + local_status, local_message = mycommon.recordClassImage_v2(file_img, MYSY_GV.upload_folder, recordimage_diction) + if( local_status is False): + return local_status, local_message + + + + return True, "L'image a été correctement enregistrée" + + 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'enregistrer l'image" + + + +""" Recuperation de l'image d'un stagiaire + +Important : important : on prend le 'related_collection_recid' comme le '_id' de la collection inscription +""" +def getRecodedStagiaireImage_from_front(diction=None): + try: + # Dictionnaire des champs utilisables + field_list = ['token', 'class_internal_url', 'session_id', 'email'] + 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, requete annulée") + return False, " Impossible de récupérer les informations" + + ''' + 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', 'class_internal_url', 'session_id', 'email'] + 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 récupérer les informations" + + + local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) + if (local_status is not True): + return local_status, my_partner + + class_internal_url = "" + if ("class_internal_url" in diction.keys()): + if diction['class_internal_url']: + class_internal_url = diction['class_internal_url'] + + session_id = "" + if ("session_id" in diction.keys()): + if diction['session_id']: + session_id = diction['session_id'] + + email = "" + if ("email" in diction.keys()): + if diction['email']: + email = diction['email'] + + ## Recuperation de l'"_id" du stagiaire -- Exceptionnement on va mettre dans "_id" dans le 'related_collection_recid' + local_retval = MYSY_GV.dbname['inscription'].find_one({'class_internal_url': str(class_internal_url), + 'session_id': str(session_id), + 'email': str(email)}) + if (local_retval is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " : Le stagiaire " + str( + email) + " n'est pas reconnu pour la session aa" + str(str(session_id))) + return False, " Le stagiaire n'est pas reconnu " + + + qery_images = {'locked': '0', 'valide': '1', 'related_collection': 'inscription', + 'related_collection_recid': str(local_retval['_id'])} + + #print(" ### qery_images = ", qery_images) + + RetObject = [] + partner_images = {} + # Recuperation des image 'logo' et 'cachet' si le partenaire en a + for retVal in MYSY_GV.dbname['mysy_images'].find(qery_images): + if ('type_img' in retVal.keys()): + if (retVal['type_img'] == "user"): + partner_images['logo_img'] = retVal['img'].decode() + partner_images['logo_img_recid'] = retVal['recid'] + + + RetObject.append(mycommon.JSONEncoder().encode(partner_images)) + + + return True, RetObject + + except Exception as e: + 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 recupérer l'image du stagiaire" + + +""" +Suppression d'un image d'un stagiaire +""" +def DeleteImage_Stagiaire_v2(diction=None): + try: + + # Dictionnaire des champs utilisables + field_list = ['token', 'image_recid', ] + incom_keys = diction.keys() + + ''' + # 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. + ''' + 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'est pas accepté dans cette API") + return False, " Impossible de se connecter" + + ''' + 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', 'image_recid'] + 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 des champs") + return False, "Impossible de se connecter" + + mydata = {} + mytoken = "" + + # recuperation des paramettre + if ("token" in diction.keys()): + if diction['token']: + mytoken = diction['token'] + + image_recid = "" + if ("image_recid" in diction.keys()): + if diction['image_recid']: + image_recid = diction['image_recid'] + + local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) + if (local_status is not True): + return local_status, my_partner + + # " Lecture du fichier " + # print(" Lecture du fichier : " + saved_file + ". le token est :" + str(mytoken)) + nb_line = 0 + coll_name = MYSY_GV.dbname['mysy_images'] + + query_delete = {"recid": image_recid,} + + + ret_val = coll_name.delete_one({"recid": image_recid,}, ) + + + + #print(" ### recordClassImage_v2 :L'image a été correctement supprimée ") + return True, "L'image a été correctement supprimée" + + + except Exception as e: + 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 supprimer l'image " + +""" +Cette fonction récupérer la liste des stagiaire d'un partenaire. +On y ajoute la formation concernée +""" +def Get_Statgaire_List_Partner_with_filter_OLD(diction): + try: + field_list = ['token', 'class_internal_url', 'code_session', 'status', 'email', 'nom', + 'class_title', 'code_session','client_nom', 'client_rattachement_id', + 'session_id', 'archive'] + 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_class_title = {} + if ("class_title" in diction.keys()): + filt_class_title = {'title': {'$regex': mycommon.regex_replace_cartere(str(diction['class_title'])), "$options": "i"}} + + filt_class_internal_url = {} + if ("class_internal_url" in diction.keys()): + filt_class_internal_url = { + 'class_internal_url': {'$regex': mycommon.regex_replace_cartere(str(diction['class_internal_url'])), "$options": "i"}} + + filt_email = {} + if ("email" in diction.keys()): + filt_email = {'email': {'$regex': mycommon.regex_replace_cartere(str(diction['email'])), "$options": "i"}} + + filt_nom = {} + if ("nom" in diction.keys()): + filt_nom = {'nom': {'$regex': mycommon.regex_replace_cartere(str(diction['nom'])), "$options": "i"}} + + filt_class_partner_recid = {'partner_owner_recid': str(partner_recid)} + + filt_client_rattachement_id = {} + if ("client_rattachement_id" in diction.keys()): + filt_client_rattachement_id = {'client_rattachement_id': str(diction['client_rattachement_id'])} + + + filt_session_id = {} + if ("session_id" in diction.keys()): + filt_session_id = {'session_id': str(diction['session_id'])} + + # ----- + + filt_client_nom = {} + sub_filt_client_nom = {} + Lists_partner_client_id = [] + if ("client_nom" in diction.keys()): + sub_filt_client_nom = {'nom': {'$regex': str(diction['client_nom']), "$options": "i"}, + 'partner_owner_recid': str(partner_recid), 'valide': '1', 'locked': '0'} + # Recuperation des '_id' des clients dont le nom match en regexp + # print(" ### sub_filt_client_nom = ", sub_filt_client_nom) + for List_Client_Data in MYSY_GV.dbname['partner_client'].find(sub_filt_client_nom, {'_id': 1}): + Lists_partner_client_id.append(str(List_Client_Data['_id'])) + + filt_client_nom = {'client_rattachement_id': {'$in': Lists_partner_client_id, }} + # print(' ### filt_client_nom = ', filt_client_nom) + + + #---- + + + query = [{'$match':{ '$and' : [ filt_archive, filt_class_internal_url, filt_session_code, filt_email, filt_nom, filt_client_nom, filt_client_rattachement_id, + 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_title, 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' + } + }, + {'$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_Statgaire_List_Partner_with_filter laa 02 : 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(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" + + + + """ + Important : : 28/12/2023 - update + S'il y a de la data dans la collection 'apprenant_collection' cela veut dire qu'il y a un dossier apprenant, + alors on va plutot retourner les info qui sont dans cette collection + + Important : 31/07/2024 - annulation de la recheche de l'apprenant + if ('apprenant_collection' in retVal.keys() and len( retVal['apprenant_collection']) > 0): + if ("civilite" in retVal['apprenant_collection'][0].keys()): + val['civilite'] = str(retVal['apprenant_collection'][0]['civilite']).lower() + else: + val['civilite'] = "" + + if (str(val['civilite']) not in MYSY_GV.CIVILITE): + val['civilite'] = "neutre" + + local_nom = "" + if ("nom" in retVal['apprenant_collection'][0].keys()): + local_nom = retVal['apprenant_collection'][0]['nom'] + val['nom'] = local_nom + + local_prenom = "" + if ("prenom" in retVal['apprenant_collection'][0].keys()): + local_prenom = retVal['apprenant_collection'][0]['prenom'] + val['prenom'] = local_prenom + + if ("date_naissance" in retVal['apprenant_collection'][0].keys()): + val['date_naissance'] = retVal['apprenant_collection'][0]['date_naissance'] + else: + val['date_naissance'] = "" + + if ("adresse" in retVal['apprenant_collection'][0].keys()): + val['adresse'] = retVal['apprenant_collection'][0]['adresse'] + else: + val['adresse'] = "" + + if ("code_postal" in retVal['apprenant_collection'][0].keys()): + val['code_postal'] = retVal['apprenant_collection'][0]['code_postal'] + else: + val['code_postal'] = "" + + if ("ville" in retVal['apprenant_collection'][0].keys()): + val['ville'] = retVal['apprenant_collection'][0]['ville'] + else: + val['ville'] = "" + + if ("pays" in retVal['apprenant_collection'][0].keys()): + val['pays'] = retVal['apprenant_collection'][0]['pays'] + else: + val['pays'] = "" + + + + local_employeur = "" + if ("employeur" in retVal['apprenant_collection'][0].keys()): + local_employeur = retVal['apprenant_collection'][0]['employeur'] + val['employeur'] = local_employeur + + local_telephone = "" + if ("telephone" in retVal['apprenant_collection'][0].keys()): + local_telephone = retVal['apprenant_collection'][0]['telephone'] + val['telephone'] = local_telephone + + local_email = "" + if ("email" in retVal['apprenant_collection'][0].keys()): + local_email = retVal['apprenant_collection'][0]['email'] + val['email'] = local_email + + local_adresse = "" + if ("adresse" in retVal['apprenant_collection'][0].keys()): + local_adresse = retVal['apprenant_collection'][0]['adresse'] + val['adresse'] = local_adresse + + if ("ville" in retVal['apprenant_collection'][0].keys()): + val['ville'] = retVal['apprenant_collection'][0]['ville'] + else: + val['ville'] = "" + + if ("code_postal" in retVal['apprenant_collection'][0].keys()): + val['code_postal'] = retVal['apprenant_collection'][0]['code_postal'] + else: + val['code_postal'] = "" + + if ("pays" in retVal['apprenant_collection'][0].keys()): + val['pays'] = retVal['apprenant_collection'][0]['pays'] + else: + val['pays'] = "" + + """ + + 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" + + +""" +Cette fonction récupérer la liste des stagiaire d'un partenaire. +On y ajoute la formation concernée +""" + + +def Get_Statgaire_List_Partner_with_filter(diction): + try: + field_list = ['token', 'class_internal_url', 'code_session', 'status', 'email', 'nom', + 'class_title', 'code_session', 'client_nom', 'client_rattachement_id', + 'session_id', 'archive', 'invoiced'] + 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_class_title = {} + if ("class_title" in diction.keys()): + filt_class_title = { + 'title': {'$regex': mycommon.regex_replace_cartere(str(diction['class_title'])), "$options": "i"}} + + filt_class_internal_url = {} + if ("class_internal_url" in diction.keys()): + filt_class_internal_url = { + 'class_internal_url': {'$regex': mycommon.regex_replace_cartere(str(diction['class_internal_url'])), + "$options": "i"}} + + filt_email = {} + if ("email" in diction.keys()): + filt_email = {'email': {'$regex': mycommon.regex_replace_cartere(str(diction['email'])), "$options": "i"}} + + filt_nom = {} + if ("nom" in diction.keys()): + filt_nom = {'nom': {'$regex': mycommon.regex_replace_cartere(str(diction['nom'])), "$options": "i"}} + + """ + Filtre général + """ + if ("nom" in diction.keys()): + qry_gle = {"$or": [ + {'prenom': {'$regex': mycommon.regex_replace_cartere(str(diction['nom'])), "$options": "i"}}, + {'nom': {'$regex': mycommon.regex_replace_cartere(str(diction['nom'])), "$options": "i"}}, + {'email': {'$regex': mycommon.regex_replace_cartere(str(diction['nom'])), "$options": "i"}}, + {'telephone': {'$regex': mycommon.regex_replace_cartere(str(diction['nom'])), "$options": "i"}}, + ]} + else: + qry_gle = {} + + filt_class_partner_recid = {'partner_owner_recid': str(partner_recid)} + + filt_client_rattachement_id = {} + if ("client_rattachement_id" in diction.keys()): + filt_client_rattachement_id = {'client_rattachement_id': str(diction['client_rattachement_id'])} + + filt_session_id = {} + if ("session_id" in diction.keys()): + filt_session_id = {'session_id': str(diction['session_id'])} + + filt_invoiced = {} + if ("invoiced" in diction.keys() and str(diction['invoiced']).strip() == "1"): + filt_invoiced = {'invoiced': str(diction['invoiced'])} + + if ("invoiced" in diction.keys() and str(diction['invoiced']).strip() != "1" ): + filt_invoiced = {'invoiced': {'$ne':'1'} } + + # ----- + + filt_client_nom = {} + sub_filt_client_nom = {} + Lists_partner_client_id = [] + if ("client_nom" in diction.keys()): + + sub_filt_client_nom = {"$or": [ + {'raison_sociale': {'$regex': mycommon.regex_replace_cartere(str(diction['client_nom'])), "$options": "i"}, }, + {'nom': {'$regex': mycommon.regex_replace_cartere(str(diction['client_nom'])), "$options": "i"}, 'partner_owner_recid': str(partner_recid), 'valide': '1', 'locked': '0'}, + {'email': {'$regex': mycommon.regex_replace_cartere(str(diction['client_nom'])), "$options": "i"}, 'partner_owner_recid': str(partner_recid), 'valide': '1', 'locked': '0'}, + {'telephone': {'$regex': mycommon.regex_replace_cartere(str(diction['client_nom'])), "$options": "i"}, 'partner_owner_recid': str(partner_recid), 'valide': '1', 'locked': '0'}, + + ]} + + + # Recuperation des '_id' des clients dont le nom match en regexp + print(" ### sub_filt_client_nom = ", sub_filt_client_nom) + for List_Client_Data in MYSY_GV.dbname['partner_client'].find(sub_filt_client_nom, {'_id': 1}): + Lists_partner_client_id.append(str(List_Client_Data['_id'])) + + filt_client_nom = {'client_rattachement_id': {'$in': Lists_partner_client_id, }} + print(' ### filt_client_nom = ', filt_client_nom) + + # ---- + + query = [{'$match': + { + '$and': [filt_archive, filt_class_internal_url, filt_session_code, qry_gle, filt_client_nom, + filt_client_rattachement_id, + filt_session_id, filt_invoiced, {'partner_owner_recid': str(partner_recid), 'valide': '1'}]}}, + + {'$sort': {'_id': -1}}, + {'$lookup': + { + 'from': 'myclass', + 'let': {'class_id': "$class_id", 'partner_owner_recid': '$partner_owner_recid'}, + 'pipeline': [ + {'$match': + {'$expr': + {'$and': + [ + {'$eq': ["$_id", {'$convert': { + 'input': "$$class_id", + 'to': "objectId", + 'onError': {'error': 'true'}, + 'onNull': {'isnull': 'true'} + }}]}, + + {'$eq': ["$valide", "1"]}, + {'$eq': ["$partner_owner_recid", '$$partner_owner_recid']}, + + ] + } + } + }, + {'$project': {"_id": 1, "order_header_ref_interne": 1, "external_code": 1, + "title": 1, "partner_owner_recid": 1, "valide": 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_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'] + + ### + modefinancement_code = "" + modefinancement_id = "" + if ("modefinancement_id" in retVal.keys() and retVal['modefinancement_id']): + modefinancement_data = MYSY_GV.dbname['financement_mode'].find_one( + {'_id': ObjectId(str(retVal['modefinancement_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(retVal['partner_owner_recid'])}) + + if (modefinancement_data and "code" in modefinancement_data.keys()): + modefinancement_code = str(modefinancement_data['code']) + modefinancement_id = str(modefinancement_data['_id']) + + val['modefinancement_code'] = modefinancement_code + val['modefinancement_id'] = modefinancement_id + + type_apprenant_code = "" + type_apprenant_id = "" + if ("type_apprenant_id" in retVal.keys() and retVal['type_apprenant_id']): + type_apprenant_data = MYSY_GV.dbname['type_apprenant'].find_one( + {'_id': ObjectId(str(retVal['type_apprenant_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(retVal['partner_owner_recid'])}) + + if (type_apprenant_data and "code" in type_apprenant_data.keys()): + type_apprenant_code = str(type_apprenant_data['code']) + type_apprenant_id = str(type_apprenant_data['_id']) + + val['type_apprenant_code'] = type_apprenant_code + val['type_apprenant_id'] = type_apprenant_id + + ### + + + 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'] = "" + + + if ("is_ftion_initiale" in retVal['myclass_collection'][0].keys()): + val['is_ftion_initiale'] = retVal['myclass_collection'][0]['is_ftion_initiale'] + else: + val['is_ftion_initiale'] = "" + + 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" + + local_class_recyclage = "0" + local_class_recyclage_float = 0 + if ('myclass_collection' in retVal.keys() and len(retVal['myclass_collection']) > 0 + and "recyclage_alert" in retVal['myclass_collection'][0].keys() + and retVal['myclass_collection'][0]['recyclage_alert'] ): + local_class_recyclage = retVal['myclass_collection'][0]['recyclage_alert'] + local_class_recyclage_float = mycommon.tryFloat(str(retVal['myclass_collection'][0]['recyclage_alert'])) + + + if( local_class_recyclage_float > 0 ): + 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" + + +""" +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)} + #---- + + + + + query2 = [{'$match': {'$and': [filt_archive, filt_session_code, + filt_session_id, {'partner_owner_recid': str(partner_recid), 'valide': '1'}]}}, + {'$sort': {'_id': -1}}, + {'$lookup': + { + 'from': 'myclass', + 'let': {'class_id': "$class_id", 'partner_owner_recid': '$partner_owner_recid'}, + 'pipeline': [ + + {'$match': + {'$expr': + {'$and': + [ + + {'$eq': ["$_id", {'$convert': { + 'input': "$$class_id", + 'to': "objectId", + 'onError': {'error': 'true'}, + 'onNull': {'isnull': 'true'} + }}]}, + + {'$eq': ["$valide", "1"]}, + {'$eq': ["$partner_owner_recid", '$$partner_owner_recid']}, + + ] + } + } + }, + {'$project': {"_id": 1, "order_header_ref_interne": 1, "external_code": 1, + "title": 1, "partner_owner_recid": 1, "valide":1} + }, + ], + 'as': 'myclass_collection' + + } + }, + + ] + + #print("#### Get_Statgaire_List_Partner_with_filter laa 01 zzz : query22 = ", query2) + RetObject = [] + cpt = 0 + for retVal in MYSY_GV.dbname['inscription'].aggregate(query2): + 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'] + + ### + modefinancement_code = "" + modefinancement_id = "" + if ("modefinancement_id" in retVal.keys() and retVal['modefinancement_id']): + modefinancement_data = MYSY_GV.dbname['financement_mode'].find_one( + {'_id': ObjectId(str(retVal['modefinancement_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(retVal['partner_owner_recid'])}) + + if (modefinancement_data and "code" in modefinancement_data.keys()): + modefinancement_code = str(modefinancement_data['code']) + modefinancement_id = str(modefinancement_data['_id']) + + val['modefinancement_code'] = modefinancement_code + val['modefinancement_id'] = modefinancement_id + + type_apprenant_code = "" + type_apprenant_id = "" + if ("type_apprenant_id" in retVal.keys() and retVal['type_apprenant_id']): + type_apprenant_data = MYSY_GV.dbname['type_apprenant'].find_one( + {'_id': ObjectId(str(retVal['type_apprenant_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(retVal['partner_owner_recid'])}) + + if (type_apprenant_id and "code" in type_apprenant_id.keys()): + type_apprenant_code = str(type_apprenant_data['code']) + type_apprenant_id = str(type_apprenant_data['_id']) + + val['type_apprenant_code'] = type_apprenant_code + val['type_apprenant_id'] = type_apprenant_id + + ### + + 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'] = "" + + if ("is_ftion_initiale" in retVal['myclass_collection'][0].keys()): + val['is_ftion_initiale'] = retVal['myclass_collection'][0]['is_ftion_initiale'] + else: + val['is_ftion_initiale'] = "" + + + 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 +Ex : l'inscrit ne souhaite plus le repasser, donc on met 'recyclage_managed' à '0' +ou le cas la personne s'est bien reinscrite, donc plus besoin de traiter les donnees de recyclage + +""" +def Inscription_Recyclage_Management_Done(diction): + try: + diction = mycommon.strip_dictionary(diction) + + field_list_obligatoire = ['token', 'tab_inscriptions_ids'] + + 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 + + tab_inscriptions_ids = "" + if ("tab_inscriptions_ids" in diction.keys()): + if diction['tab_inscriptions_ids']: + tab_inscriptions_ids = diction['tab_inscriptions_ids'] + + tab_inscriptions_ids_splited = str(tab_inscriptions_ids).split(",") + + tab_inscriptions_ids_splited_obj = [] + for tmp in tab_inscriptions_ids_splited : + tab_inscriptions_ids_splited_obj.append(ObjectId(str(tmp))) + + print(" ### tab_inscriptions_ids_splited_obj = ", tab_inscriptions_ids_splited_obj) + + """ + Verifier que les inscriptions sont valides + """ + for inscription in tab_inscriptions_ids_splited_obj: + print({'_id':inscription, 'valide':'1', + 'partner_owner_recid':str(my_partner['recid'])}) + + is_valide_inscription_count = MYSY_GV.dbname['inscription'].count_documents({'_id':inscription, 'valide':'1', + 'partner_owner_recid':str(my_partner['recid'])}) + + if( is_valide_inscription_count != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de l'inscription "+str(inscription)+" est invalide ") + return False, " L'identifiant de l'inscription "+str(inscription)+" est invalide " + + + + for inscription in tab_inscriptions_ids_splited_obj: + new_data = {} + new_data['update_date'] = str(datetime.now()) + new_data['update_by'] = str(my_partner['_id']) + new_data['recyclage_managed'] = "1" + + ret_val = MYSY_GV.dbname['inscription'].find_one_and_update( + {'_id': inscription, 'valide': '1', + 'partner_owner_recid': str(my_partner['recid'])}, + {"$set": new_data}, + upsert=False, + return_document=ReturnDocument.AFTER + ) + + + + return True, " La mise à jour à été correctement faite " + + 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 faire la mise à jour " + +""" +Cette fonction prend '_id' d'une ligne et retour les information de l'inscription associé. + +Un controle sera fait avec le partner_recid +""" + +def GetAttendeeDetail_perSession_from_line_id(diction): + try: + field_list_obligatoire = [ 'token', '_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, " Impossible de récupérer les informations detaillées" + + 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 "Err_Connexion", " La session de connexion n'est pas valide" + + + # Recuperation du recid du partenaire + 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, " Les informations d'identification sont invalides" + + RetObject = [] + + qry_filter = {'_id':ObjectId(str(diction['_id'])),'partner_owner_recid':str(partner_recid),} + + + pipe_qry = ([{'$match':qry_filter}, + {'$lookup': + { + 'from': 'session_formation', + 'let': {'session_id': "$session_id", 'class_internal_url': '$class_internal_url', 'partner_owner_recid':'$partner_owner_recid'}, + + 'pipeline': [ + {'$match': + {'$expr': + {'$and': + [ + {'$eq': ['$_id', { '$toObjectId': '$$session_id' }]}, + {'$eq': ["$valide", "1"]}, + {'$eq': ["$partner_owner_recid", '$$partner_owner_recid']} + ] + } + } + }, + + ], + 'as': 'inscription_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(" ### GetAttendeeDetail_perSession_from_line_id ici pipe_qry = ",pipe_qry) + # Recuperation des infos de la formation + """local_Insc_retval = MYSY_GV.dbname['inscription'].find_one({'session_id':str(diction['session_id']), + 'email':str(diction['attendee_email']), + 'class_internal_url':str(diction['internal_url']),}) + """ + + + for local_Insc_retval in MYSY_GV.dbname['inscription'].aggregate(pipe_qry) : + + #print(" ### local_Insc_retval laa== ", local_Insc_retval) + + if( local_Insc_retval is None): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer le recid du partenaire (2)") + return False, " Les informations d'identifier la session (2) " + + if ('inscription_collection' in local_Insc_retval.keys() and len(local_Insc_retval['inscription_collection']) > 0): + my_retrun_dict = {} + + if ("session_id" in local_Insc_retval.keys()): + my_retrun_dict['session_id'] = local_Insc_retval['session_id'] + + if ("apprenant_id" in local_Insc_retval.keys()): + my_retrun_dict['apprenant_id'] = local_Insc_retval['apprenant_id'] + else: + my_retrun_dict['apprenant_id'] = "" + + my_retrun_dict['tuteur1_civilite'] = "" + if ("tuteur1_civilite" not in local_Insc_retval.keys()): + my_retrun_dict['tuteur1_civilite'] = "" + elif (local_Insc_retval['tuteur1_civilite'] not in MYSY_GV.CIVILITE): + # la civilité n'est pas une de celle autorisée, alors je renvoie vide + my_retrun_dict['tuteur1_civilite'] = "" + else: + my_retrun_dict['tuteur1_civilite'] = local_Insc_retval['tuteur1_civilite'] + + + if( my_retrun_dict['tuteur1_civilite'] == ""): + my_retrun_dict['tuteur1_civilite'] = "neutre" + + my_retrun_dict['tuteur2_civilite'] = "" + if ("tuteur2_civilite" not in local_Insc_retval.keys()): + my_retrun_dict['tuteur2_civilite'] = "" + elif (local_Insc_retval['tuteur2_civilite'] not in MYSY_GV.CIVILITE): + # la civilité n'est pas une de celle autorisée, alors je renvoie vide + my_retrun_dict['tuteur2_civilite'] = "" + else: + my_retrun_dict['tuteur2_civilite'] = local_Insc_retval['tuteur2_civilite'] + + if( my_retrun_dict['tuteur2_civilite'] == ""): + my_retrun_dict['tuteur2_civilite'] = "neutre" + + + if ("code_session" in local_Insc_retval['inscription_collection'][0].keys()): + my_retrun_dict['code_session'] = str(local_Insc_retval['inscription_collection'][0]['code_session']) + + if ("date_debut" in local_Insc_retval['inscription_collection'][0].keys()): + my_retrun_dict['date_du'] = str(local_Insc_retval['inscription_collection'][0]['date_debut'])[0:10] + + if ("date_fin" in local_Insc_retval['inscription_collection'][0].keys()): + my_retrun_dict['date_au'] = str(local_Insc_retval['inscription_collection'][0]['date_fin'])[0:10] + + if ("ville" in local_Insc_retval.keys()): + my_retrun_dict['ville'] = local_Insc_retval['ville'] + + if ("code_postal" in local_Insc_retval.keys()): + my_retrun_dict['code_postal'] = local_Insc_retval['code_postal'] + + if ("certification_send_date" in local_Insc_retval.keys()): + if (str(local_Insc_retval['certification_send_date'])): + my_retrun_dict['certification_send_date'] = str(local_Insc_retval['certification_send_date'])[0:10] + + local_adresse = "" + if ("adresse" in local_Insc_retval.keys()): + local_adresse = local_Insc_retval['adresse'] + my_retrun_dict['adresse'] = local_adresse + + local_nom = "" + if ("nom" in local_Insc_retval.keys()): + local_nom = local_Insc_retval['nom'] + my_retrun_dict['nom'] = local_nom + + local_prenom = "" + if ("prenom" in local_Insc_retval.keys()): + local_prenom = local_Insc_retval['prenom'] + my_retrun_dict['prenom'] = local_prenom + + local_civilite = "" + if ("civilite" in local_Insc_retval.keys()): + local_civilite = local_Insc_retval['civilite'] + + if (local_civilite not in MYSY_GV.CIVILITE): + local_civilite = "neutre" + + if( str(local_civilite) == ""): + local_civilite = "neutre" + + my_retrun_dict['civilite'] = str(local_civilite).lower() + + + local_employeur = "" + if ("employeur" in local_Insc_retval.keys()): + local_employeur = local_Insc_retval['employeur'] + my_retrun_dict['employeur'] = local_employeur + + memo = "" + if ("memo" in local_Insc_retval.keys()): + memo = local_Insc_retval['memo'] + my_retrun_dict['memo'] = memo + + handicap_detail = "" + if ("handicap_detail" in local_Insc_retval.keys()): + handicap_detail = local_Insc_retval['handicap_detail'] + my_retrun_dict['handicap_detail'] = handicap_detail + + nom_fille = "" + if ("nom_fille" in local_Insc_retval.keys()): + nom_fille = local_Insc_retval['nom_fille'] + my_retrun_dict['nom_fille'] = nom_fille + + num_cvec = "" + if ("num_cvec" in local_Insc_retval.keys()): + num_cvec = local_Insc_retval['handicap_detail'] + my_retrun_dict['num_cvec'] = num_cvec + + + ine = "" + if ("ine" in local_Insc_retval.keys()): + ine = local_Insc_retval['ine'] + my_retrun_dict['ine'] = ine + + matricule = "" + if ("matricule" in local_Insc_retval.keys()): + matricule = local_Insc_retval['matricule'] + my_retrun_dict['matricule'] = matricule + + comment = "" + if ("comment" in local_Insc_retval.keys()): + comment = local_Insc_retval['comment'] + my_retrun_dict['comment'] = comment + + ### + modefinancement_code = "" + modefinancement_id = "" + if ("modefinancement_id" in local_Insc_retval.keys() and local_Insc_retval['modefinancement_id']): + modefinancement_data = MYSY_GV.dbname['financement_mode'].find_one( + {'_id': ObjectId(str(local_Insc_retval['modefinancement_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(local_Insc_retval['partner_owner_recid'])}) + + if (modefinancement_data and "code" in modefinancement_data.keys()): + modefinancement_code = str(modefinancement_data['code']) + modefinancement_id = str(modefinancement_data['_id']) + + my_retrun_dict['modefinancement_code'] = modefinancement_code + my_retrun_dict['modefinancement_id'] = modefinancement_id + + type_apprenant_code = "" + type_apprenant_id = "" + if ("type_apprenant_id" in local_Insc_retval.keys() and local_Insc_retval['type_apprenant_id']): + type_apprenant_data = MYSY_GV.dbname['type_apprenant'].find_one( + {'_id': ObjectId(str(local_Insc_retval['type_apprenant_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(local_Insc_retval['partner_owner_recid'])}) + + if (type_apprenant_data and "code" in type_apprenant_data.keys()): + type_apprenant_code = str(type_apprenant_data['code']) + type_apprenant_id = str(type_apprenant_data['_id']) + + my_retrun_dict['type_apprenant_code'] = type_apprenant_code + my_retrun_dict['type_apprenant_id'] = type_apprenant_id + + ### + # --------- + employeur_id = "" + if ("employeur_id" in local_Insc_retval.keys() and local_Insc_retval['employeur_id']): + valide_employeur_count = MYSY_GV.dbname['partner_client'].count_documents( + {'_id': ObjectId(str(local_Insc_retval['employeur_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(local_Insc_retval['partner_owner_recid'])}) + + if (valide_employeur_count == 1): + employeur_id = local_Insc_retval['employeur_id'] + + my_retrun_dict['employeur_id'] = employeur_id + + categorie_id = "" + if ("categorie_id" in local_Insc_retval.keys() and local_Insc_retval['categorie_id']): + valide_categorie_count = MYSY_GV.dbname['categorie_apprenant'].count_documents( + {'_id': ObjectId(str(local_Insc_retval['categorie_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(local_Insc_retval['partner_owner_recid'])}) + + if (valide_categorie_count == 1): + categorie_id = local_Insc_retval['categorie_id'] + + my_retrun_dict['categorie_id'] = categorie_id + + # ------- + + + local_telephone = "" + if ("telephone" in local_Insc_retval.keys()): + local_telephone = local_Insc_retval['telephone'] + my_retrun_dict['telephone'] = local_telephone + + local_email = "" + if ("email" in local_Insc_retval.keys()): + local_email = local_Insc_retval['email'] + my_retrun_dict['email'] = local_email + + local_modefinancement = "" + if ("modefinancement" in local_Insc_retval.keys()): + local_modefinancement = local_Insc_retval['modefinancement'] + my_retrun_dict['modefinancement'] = local_modefinancement + + local_opco = "" + if ("opco" in local_Insc_retval.keys()): + local_opco = local_Insc_retval['opco'] + my_retrun_dict['opco'] = local_opco + + local_class_internal_url = "" + if ("class_internal_url" in local_Insc_retval.keys()): + local_class_internal_url = local_Insc_retval['class_internal_url'] + my_retrun_dict['class_internal_url'] = local_class_internal_url + + local_status = "" + if ("status" in local_Insc_retval.keys()): + local_status = local_Insc_retval['status'] + my_retrun_dict['status'] = local_status + + + if ("is_droit_image" in local_Insc_retval.keys()): + my_retrun_dict['is_droit_image'] = local_Insc_retval['is_droit_image'] + else: + my_retrun_dict['is_droit_image'] = "0" + + + if ("is_handicap" in local_Insc_retval.keys()): + my_retrun_dict['is_handicap'] = local_Insc_retval['is_handicap'] + else: + my_retrun_dict['is_handicap'] = "0" + + if ("is_rgpd" in local_Insc_retval.keys()): + my_retrun_dict['is_rgpd'] = local_Insc_retval['is_rgpd'] + else: + my_retrun_dict['is_rgpd'] = "0" + + if ("naissance_departement" in local_Insc_retval.keys()): + my_retrun_dict['naissance_departement'] = local_Insc_retval['naissance_departement'] + else: + my_retrun_dict['naissance_departement'] = "" + + + if ("naissance_departement" in local_Insc_retval.keys()): + my_retrun_dict['naissance_departement'] = local_Insc_retval['naissance_departement'] + else: + my_retrun_dict['naissance_departement'] = "" + + + if ("naissance_lieu" in local_Insc_retval.keys()): + my_retrun_dict['naissance_lieu'] = local_Insc_retval['naissance_lieu'] + else: + my_retrun_dict['naissance_lieu'] = "" + + + if ("naissance_pays" in local_Insc_retval.keys()): + my_retrun_dict['naissance_pays'] = local_Insc_retval['naissance_pays'] + else: + my_retrun_dict['naissance_pays'] = "" + + if ("nationalite" in local_Insc_retval.keys()): + my_retrun_dict['nationalite'] = local_Insc_retval['nationalite'] + else: + my_retrun_dict['nationalite'] = "" + + + if ("num_secu" in local_Insc_retval.keys()): + my_retrun_dict['num_secu'] = local_Insc_retval['num_secu'] + else: + my_retrun_dict['num_secu'] = "" + + if ("piece_identite_num" in local_Insc_retval.keys()): + my_retrun_dict['piece_identite_num'] = local_Insc_retval['piece_identite_num'] + else: + my_retrun_dict['piece_identite_num'] = "" + + if ("situation_famille" in local_Insc_retval.keys()): + my_retrun_dict['situation_famille'] = local_Insc_retval['situation_famille'] + else: + my_retrun_dict['situation_famille'] = "" + + if ("telephone_bis" in local_Insc_retval.keys()): + my_retrun_dict['telephone_bis'] = local_Insc_retval['telephone_bis'] + else: + my_retrun_dict['telephone_bis'] = "" + + + if ("type_mobilite" in local_Insc_retval.keys()): + my_retrun_dict['type_mobilite'] = local_Insc_retval['type_mobilite'] + else: + my_retrun_dict['type_mobilite'] = "" + + + + + if ("archive" not in local_Insc_retval.keys()): + my_retrun_dict['archive'] = "0" + + + local_price = "" + if ("price" in local_Insc_retval.keys()): + local_price = local_Insc_retval['price'] + my_retrun_dict['price'] = local_price + + local_inscription_validation_date = "" + if ("inscription_validation_date" in local_Insc_retval.keys()): + local_inscription_validation_date = local_Insc_retval['inscription_validation_date'] + my_retrun_dict['inscription_validation_date'] = local_inscription_validation_date + + if ("eval_eval" in local_Insc_retval.keys()): + if (str(local_Insc_retval['eval_eval'])): + my_retrun_dict['eval_eval'] = local_Insc_retval['eval_eval'] + + if ("eval_note" in local_Insc_retval.keys()): + if (str(local_Insc_retval['eval_note'])): + my_retrun_dict['eval_note'] = local_Insc_retval['eval_note'] + + if ("eval_pedagogie" in local_Insc_retval.keys()): + if (str(local_Insc_retval['eval_pedagogie'])): + my_retrun_dict['eval_pedagogie'] = local_Insc_retval['eval_pedagogie'] + + if ("eval_date" in local_Insc_retval.keys()): + if (str(local_Insc_retval['eval_date'])): + my_retrun_dict['eval_date'] = str(local_Insc_retval['eval_date'])[0:10] + + client_rattachement_id = "" + client_rattachement_nom = "" + if ("client_rattachement_id" in local_Insc_retval.keys()): + if( local_Insc_retval['client_rattachement_id'] and str(local_Insc_retval['client_rattachement_id']) != 'undefined' ): + local_client_retval_data = MYSY_GV.dbname['partner_client'].find_one({'_id': ObjectId(str(local_Insc_retval['client_rattachement_id'])), + 'valide': '1', 'locked': '0'}, {'_id':1, 'nom':1}) + + if( local_client_retval_data is not None): + client_rattachement_id = local_client_retval_data['_id'] + client_rattachement_nom = local_client_retval_data['nom'] + + my_retrun_dict['client_rattachement_id'] = client_rattachement_id + my_retrun_dict['client_rattachement_nom'] = client_rattachement_nom + + # ---- + financeur_rattachement_id = "" + financeur_rattachement_nom = "" + if ("financeur_rattachement_id" in local_Insc_retval.keys()): + if (local_Insc_retval['financeur_rattachement_id'] and str( + local_Insc_retval['financeur_rattachement_id']) != 'undefined'): + local_client_retval_data = MYSY_GV.dbname['partner_client'].find_one( + {'_id': ObjectId(str(local_Insc_retval['financeur_rattachement_id'])), + 'valide': '1', 'locked': '0'}, {'_id': 1, 'nom': 1}) + + if (local_client_retval_data is not None): + financeur_rattachement_id = local_client_retval_data['_id'] + financeur_rattachement_nom = local_client_retval_data['nom'] + + my_retrun_dict['financeur_rattachement_id'] = financeur_rattachement_id + my_retrun_dict['financeur_rattachement_nom'] = financeur_rattachement_nom + + if ("facture_client_rattachement_id" in local_Insc_retval.keys()): + my_retrun_dict['facture_client_rattachement_id'] = local_Insc_retval[ + 'facture_client_rattachement_id'] + else: + my_retrun_dict['facture_client_rattachement_id'] = "" + + v = local_Insc_retval['_id'].generation_time + my_retrun_dict['creation_date'] = str(v.strftime("%d/%m/%Y")) + + # Recuperation des informations de la formation + local_formation = MYSY_GV.dbname['myclass'].find_one({'internal_url':str(local_Insc_retval['class_internal_url'])}) + + if local_formation is None or local_formation['_id'] is None: + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer les informations de la formation ") + return False, " Impossible de récupérer les informations de la formation" + + my_retrun_dict['class_title'] = local_formation['title'] + if ("is_ftion_initiale" in local_formation.keys()): + my_retrun_dict['is_ftion_initiale'] = local_formation['is_ftion_initiale'] + else: + my_retrun_dict['is_ftion_initiale'] = "0" + + RetObject.append(mycommon.JSONEncoder().encode(my_retrun_dict)) + + + return True, RetObject + + + except Exception as e: + 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 récupérer les informations detaillées" + + +""" +Mise à jour des tuteurs +""" + +def UpdateStagiairetoClass_Tuteurs(diction): + try: + + return_message = "" + field_list = ['token', '_id', + 'tuteur1_nom', 'tuteur1_prenom', 'tuteur1_email', 'tuteur1_telephone', 'tuteur1_adresse', + 'tuteur1_cp', 'tuteur1_ville', 'tuteur1_pays', 'tuteur1_include_com', + 'tuteur2_nom', 'tuteur2_prenom', 'tuteur2_email', 'tuteur2_telephone', 'tuteur2_adresse', + 'tuteur2_cp', 'tuteur2_ville', 'tuteur2_pays', 'tuteur2_include_com', 'tuteur1_civilite', + 'tuteur2_civilite' + ] + + 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, "Impossible de mettre à jour stagiaire. Toutes les informations fournies ne sont pas valables" + + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', '_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, "Impossible de mettre à jour stagiaire, Toutes les informations necessaires n'ont pas été fournies" + + query_key = {} + mytoken = "" + if ("token" in diction.keys()): + if diction['token']: + mytoken = str(diction['token']).strip() + # query_key['token'] = diction['token'] + + + if( "tuteur1_email" in diction.keys() and diction['tuteur1_email']): + if( mycommon.isEmailValide ( str(diction['tuteur1_email'])) is False ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'adresse email '"+str(diction['tuteur1_email'])+"' est invalide ") + return False, "L'adresse email '"+str(diction['tuteur1_email'])+"' est invalide" + + if ("tuteur2_email" in diction.keys() and diction['tuteur2_email'] ): + if (mycommon.isEmailValide(str(diction['tuteur2_email'])) is False): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'adresse email '" + str( + diction['tuteur2_email']) + "' est invalide ") + return False, "L'adresse email '" + str(diction['tuteur2_email']) + "' est invalide" + + + local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data({'token': mytoken}) + if (local_status is not True): + return local_status, my_partner + + data_update = diction + + my_id = str(diction['_id']) + del data_update['token'] + del data_update['_id'] + data_update['update_date'] = str(datetime.now()) + data_update['update_by'] = str(my_partner['_id']) + + + + if ("tuteur1_civilite" in data_update.keys() ): + if (data_update['tuteur1_civilite'] not in MYSY_GV.CIVILITE or str(data_update['tuteur1_civilite']).strip() == "" ): + # la civilité n'est pas une de celle autorisée, alors je renvoie vide + data_update['tuteur1_civilite'] = "neutre" + + + + if ("tuteur2_civilite" in data_update.keys() ): + if (data_update['tuteur2_civilite'] not in MYSY_GV.CIVILITE or str(data_update['tuteur2_civilite']).strip() == ""): + # la civilité n'est pas une de celle autorisée, alors je renvoie vide + data_update['tuteur2_civilite'] = "neutre" + + + result = MYSY_GV.dbname['inscription'].find_one_and_update( + {'_id':ObjectId(str(my_id)), + 'partner_owner_recid':str(my_partner['recid'])}, + {"$set": data_update}, + upsert=False, + return_document=ReturnDocument.AFTER + ) + + if (result is None or "_id" not in result.keys()): + mycommon.myprint( + " Impossible de mettre à jour le tuteur (2) ") + return False, " Impossible de mettre à jour le tuteur (2) " + + return True, " Le tuteur 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 tuteur " + + +""" +Cette fonction recupere les differentes types de convention de stagiaire + +On accepte plusieurs vesions du meme doc +""" +def Get_List_Conventions_Stagiaire(diction): + try: + 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" + + 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 + + RetObject = [] + val_tmp = 0 + + """ + # Recuperation des documents (collection : courrier_template) de ce partenaire avec 'ref_interne' = 'CONVENTION_STAGIAIRE' + 1 - On regarde le partenaire à des conventions qui sont personnalisées, si non + 2 - On va sortir les conventions par defaut de MySy. + + Important : : On ne melange pas les 2. c'est l'un ou l'autre + """ + for retval in MYSY_GV.dbname['courrier_template'].find({'ref_interne':'CONVENTION_STAGIAIRE', + 'valide':'1', + 'locked':'0', + 'partner_owner_recid':str(my_partner['recid'])}): + user = retval + val_tmp = val_tmp + 1 + RetObject.append(mycommon.JSONEncoder().encode(user)) + + # Si aucune convention personnalisée, on va chercher les conventions mysy + if( val_tmp == 0 ): + for retval in MYSY_GV.dbname['courrier_template'].find({'ref_interne': 'CONVENTION_STAGIAIRE', + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': 'default'}): + user = retval + val_tmp = val_tmp + 1 + RetObject.append(mycommon.JSONEncoder().encode(user)) + + return True, RetObject + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible de récupérer la liste des conventions" + + +""" +Cette fonction recupere les differentes types de convention de stagiaire avec des option comme : +- ref_interne +- nom +- type_doc + +On accepte plusieurs versions du meme doc +""" + +def Get_List_Conventions_Stagiaire_With_Filter(diction): + try: + + field_list = ['token', 'ref_interne','nom', 'type_doc', 'courrier_template_type_document_ref_interne' ] + + 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 autorisé" + + + + 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" + + 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 + + + # Recuperation des option de filter + filt_type_doc = {} + if ("type_doc" in diction.keys()): + filt_type_doc = {'type_doc': str(diction['type_doc'])} + + filt_nom = {} + if ("nom" in diction.keys()): + filt_nom = {'nom': str(diction['nom'])} + + filt_ref_interne = {} + if ("ref_interne" in diction.keys()): + filt_ref_interne = {'ref_interne': str(diction['ref_interne'])} + + filt_courrier_template_type_document_ref_interne = {} + if ("courrier_template_type_document_ref_interne" in diction.keys()): + filt_courrier_template_type_document_ref_interne = {'courrier_template_type_document_ref_interne': str(diction['courrier_template_type_document_ref_interne'])} + + RetObject = [] + val_tmp = 0 + + """ + # Recuperation des documents (collection : courrier_template) de ce partenaire avec 'ref_interne' = 'CONVENTION_STAGIAIRE' + 1 - On regarde le partenaire à des conventions qui sont personnalisées, si non + 2 - On va sortir les conventions par defaut de MySy. + + Important : : On ne melange pas les 2. c'est l'un ou l'autre + """ + + + for retval in MYSY_GV.dbname['courrier_template'].find({'$and': [{'ref_interne': 'CONVENTION_STAGIAIRE', + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}, filt_courrier_template_type_document_ref_interne, filt_type_doc, filt_nom, filt_ref_interne ]}): + user = retval + val_tmp = val_tmp + 1 + RetObject.append(mycommon.JSONEncoder().encode(user)) + + # Si aucune convention personnalisée, on va chercher les conventions mysy + if (val_tmp == 0): + for retval in MYSY_GV.dbname['courrier_template'].find({'$and': [{'ref_interne': 'CONVENTION_STAGIAIRE', + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': 'default'}, filt_courrier_template_type_document_ref_interne, filt_type_doc, filt_nom, filt_ref_interne ]}): + user = retval + val_tmp = val_tmp + 1 + RetObject.append(mycommon.JSONEncoder().encode(user)) + + return True, RetObject + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible de récupérer la liste des conventions" + + + +""" +Cette fonction recupere les differentes types de conVOCAtion de stagiaire avec des option comme : +- ref_interne +- nom +- type_doc + +On accepte plusieurs versions du meme doc +""" + +def Get_List_Convocations_Stagiaire_With_Filter(diction): + try: + + field_list = ['token', 'ref_interne','nom', 'type_doc', 'courrier_template_type_document_ref_interne' ] + + 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 autorisé" + + + + 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" + + 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 + + + # Recuperation des option de filter + filt_type_doc = {} + if ("type_doc" in diction.keys()): + filt_type_doc = {'type_doc': str(diction['type_doc'])} + + filt_nom = {} + if ("nom" in diction.keys()): + filt_nom = {'nom': str(diction['nom'])} + + filt_ref_interne = {} + if ("ref_interne" in diction.keys()): + filt_ref_interne = {'ref_interne': str(diction['ref_interne'])} + + filt_courrier_template_type_document_ref_interne = {} + if ("courrier_template_type_document_ref_interne" in diction.keys()): + filt_courrier_template_type_document_ref_interne = {'courrier_template_type_document_ref_interne': str(diction['courrier_template_type_document_ref_interne'])} + + RetObject = [] + val_tmp = 0 + + """ + # Recuperation des documents (collection : courrier_template) de ce partenaire avec 'ref_interne' = 'CONVENTION_STAGIAIRE' + 1 - On regarde le partenaire à des conventions qui sont personnalisées, si non + 2 - On va sortir les conventions par defaut de MySy. + + Important : : On ne melange pas les 2. c'est l'un ou l'autre + """ + + qry = {'$and': [{'ref_interne': 'CONVOCATION_STAGIAIRE', + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}, filt_courrier_template_type_document_ref_interne, + filt_type_doc, filt_nom, filt_ref_interne ]} + + + + for retval in MYSY_GV.dbname['courrier_template'].find({'$and': [{'ref_interne': 'CONVOCATION_STAGIAIRE', + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}, filt_courrier_template_type_document_ref_interne, + filt_type_doc, filt_nom, filt_ref_interne ]}): + user = retval + val_tmp = val_tmp + 1 + RetObject.append(mycommon.JSONEncoder().encode(user)) + + # Si aucune convention personnalisée, on va chercher les conventions mysy + if (val_tmp == 0): + for retval in MYSY_GV.dbname['courrier_template'].find({'$and': [{'ref_interne': 'CONVOCATION_STAGIAIRE', + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': 'default'}, filt_courrier_template_type_document_ref_interne, filt_type_doc, filt_nom, filt_ref_interne ]}): + user = retval + val_tmp = val_tmp + 1 + RetObject.append(mycommon.JSONEncoder().encode(user)) + + #print(" ### Get_List_Convocations_Stagiaire_With_Filter RetObject = ", RetObject) + return True, RetObject + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible de récupérer la liste des convocations" + + + +""" +Cette fonction recupere les differentes modele de courrier d'emargement + de stagiaire avec des option comme : +- ref_interne +- nom +- type_doc + +On accepte plusieurs versions du meme doc +""" + +def Get_List_Emargement_With_Filter(diction): + try: + + field_list = ['token', 'type_doc' ] + + 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 autorisé" + + + + 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" + + 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 + + + # Recuperation des option de filter + filt_type_doc = {} + if ("type_doc" in diction.keys()): + filt_type_doc = {'type_doc': str(diction['type_doc'])} + + + RetObject = [] + val_tmp = 0 + + """ + # Recuperation des documents (collection : courrier_template) de ce partenaire avec 'ref_interne' = 'EMARGEMENT' + 1 - On regarde le partenaire à des conventions qui sont personnalisées, si non + 2 - On va sortir les conventions par defaut de MySy. + + Important : : On ne melange pas les 2. c'est l'un ou l'autre + """ + + qry = {'$and': [{'ref_interne': 'EMARGEMENT', + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}, + filt_type_doc ]} + + + + for retval in MYSY_GV.dbname['courrier_template'].find({'$and': [{'ref_interne': 'EMARGEMENT', + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}, + filt_type_doc ]}): + user = retval + val_tmp = val_tmp + 1 + RetObject.append(mycommon.JSONEncoder().encode(user)) + + # Si aucune convention personnalisée, on va chercher les conventions mysy + if (val_tmp == 0): + for retval in MYSY_GV.dbname['courrier_template'].find({'$and': [{'ref_interne': 'EMARGEMENT', + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': 'default'}, filt_type_doc]}): + user = retval + val_tmp = val_tmp + 1 + RetObject.append(mycommon.JSONEncoder().encode(user)) + + #print(" ### Get_List_Convocations_Stagiaire_With_Filter RetObject = ", RetObject) + return True, RetObject + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible de récupérer la liste des emargements" + + + +""" +Recuperatin des convention SEULEMENT Individuelles +""" + + +def Get_List_Conventions_Stagiaire_Individuelles(diction): + try: + 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" + + 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 + + RetObject = [] + val_tmp = 0 + + """ + # Recuperation des documents (collection : courrier_template) de ce partenaire avec 'ref_interne' = 'CONVENTION_STAGIAIRE' + 1 - On regarde le partenaire à des conventions qui sont personnalisées, si non + 2 - On va sortir les conventions par defaut de MySy. + + Important : : On ne melange pas les 2. c'est l'un ou l'autre + """ + for retval in MYSY_GV.dbname['courrier_template'].find({"$or": [ + { + 'ref_interne': 'CONVENTION_STAGIAIRE', + 'valide': '1', + 'locked': '0', + 'edit_by_client':'0', + 'partner_owner_recid': str(my_partner['recid']) + }, + { + 'ref_interne': 'CONVENTION_STAGIAIRE', + 'valide': '1', + 'locked': '0', + 'edit_by_client': {'$exists': False}, + 'partner_owner_recid': str(my_partner['recid']) + + } + ]}): + user = retval + val_tmp = val_tmp + 1 + RetObject.append(mycommon.JSONEncoder().encode(user)) + + # Si aucune convention personnalisée, on va chercher les conventions mysy + if (val_tmp == 0): + for retval in MYSY_GV.dbname['courrier_template'].find({"$or": [ + {'ref_interne': 'CONVENTION_STAGIAIRE', + 'valide': '1', + 'locked': '0', + 'edit_by_client': '0', + 'partner_owner_recid': 'default'}, + {'ref_interne': 'CONVENTION_STAGIAIRE', + 'valide': '1', + 'locked': '0', + 'edit_by_client': {'$exists': False}, + 'partner_owner_recid': 'default' + }]}): + user = retval + val_tmp = val_tmp + 1 + RetObject.append(mycommon.JSONEncoder().encode(user)) + + return True, RetObject + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible de récupérer la liste des conventions" + + +""" +Cette fonction envoie une convention de stage par email +elle prend : +- courrier_template_id +- inscription_id. + +Dans le cas ou l'utilisateur a modifier l'email du destinataire ou il a donné une +adresse email de test, on accepte en non obligatoire +- email_test +- email_production + +Important : : Regle de gestion : + +1) Si le modele de courrier est 'edit_by_client', alors le mail est envoyé au contact de communication +du client rattaché au stagiaire. + +Si le stagiaire n'a pas de client rattacher, le système retourne un message d'erreur. + +2) Règle d'utilisation des emails destinantaire +Si 'email_test' est rempli, on envoie l'email de test si non +Si 'email_production' on prend cette liste d'adresse si non +On va chercher les adresse de communication par defaut de l'apprenant + +""" +def Sent_Convention_Stagiaire_By_Email(tab_files, Folder, diction): + try: + + field_list_obligatoire = [ 'token', 'inscription_id', 'courrier_template_id', 'email_test', 'email_production' ] + + 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 + + """ + 20/03/2024 : Creation du E-Document à signer + On verifier si le partenaire dispose de l'option "signature_digital" dans la collection base_partner_setup + + ET SI DEPUIS LE FRONT, L'UTILISATEUR DECIDE DE L'UTILISER + """ + is_partner_digital_signature = "" + if ("request_digital_signature" in diction.keys() and diction['request_digital_signature'] == "1"): + + is_signature_digital_count = MYSY_GV.dbname['base_partner_setup'].count_documents( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'signature_digital', + 'valide': '1', + 'locked': '0', + 'config_value': '1'}) + if (is_signature_digital_count == 1): + is_partner_digital_signature = "1" + + # Verifier que le stagiaire est bien inscrit. Le statut de l'inscription doit etre "1" + is_inscription_valide = MYSY_GV.dbname['inscription'].count_documents({'_id':ObjectId(str(diction['inscription_id'])), + 'status':'1', + 'partner_owner_recid':str(my_partner['recid'])}) + + if( is_inscription_valide != 1 ): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de l'inscription est invalide ") + return False, " L'identifiant de l'inscription est invalide " + + + # Traitement de l'eventuel fichier joint + tab_files_to_attache_to_mail = [] + + for saved_file in tab_files : + + """ + status, saved_file = mycommon.Upload_Save_PDF_IMG_File(file, Folder) + if (status is False): + mycommon.myprint("Impossible de récupérer correctement le fichier à importer") + return False, "Impossible de récupérer correctement le fichier à importer" + """ + + + + 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) + + + + + # Verification de la validité des adresses email_recu + """ + Important : : Si l'email de test est repli, alors on considere que c'est un test, on ne prend pas en compte l'email de email_production. + Ceci pour forcer les utilisateur à ne remplir que l'email de prod s'il veulent l'envoyer en prod. + + Si l'adresse email_prodution = "defaul", cela veut dire qu'on envoie la convention à : + - l'adresse email du stagiaire et ses tuteurs (si les tuteurs on cochés la case 'inclu com' + + """ + + + 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 + # On va chercher les adresse email de communication du + local_dict = {'token':str(diction['token']), '_id':str(diction['inscription_id'])} + + local_status, tab_apprenant_contact = Get_Statgiaire_Communication_Contact(local_dict) + if( local_status is False ): + return local_status, tab_apprenant_contact + + tmp_tab = [] + #print(" ### tab_apprenant_contact = ", tab_apprenant_contact) + + for tmp in tab_apprenant_contact : + if("email" in tmp.keys() ): + tab_emails_destinataire.append((tmp['email'])) + + + + if(len(tab_emails_destinataire) <= 0 ): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " Aucune adresse email n'a pas été fournie.02 ") + return False, " Aucune adresse email n'a pas été fournie. 02" + + + #print(" ### tab_emails_destinataire = ", tab_emails_destinataire) + + # Verifier que le 'courrier_template_id' est valide + # Ici le template doit etre un email + is_courrier_template_id_valide = MYSY_GV.dbname['courrier_template'].count_documents({'_id':ObjectId(str(diction['courrier_template_id'])), + 'valide':'1', + 'type_doc': 'email', + 'locked':'0', + 'partner_owner_recid': str(my_partner['recid'])} + ) + + if( is_courrier_template_id_valide != 1 ): + 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 " + + + + + + # Recupération des données du modèle de document + courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one( + {'_id': ObjectId(str(diction['courrier_template_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])} + ) + + + # 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(courrier_template_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 + + #print(" ### file stocké = ", local_retval) + + # 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) + + # Recuperation des données du stagaire + inscription_data = MYSY_GV.dbname['inscription'].find_one({'_id': ObjectId(str(diction['inscription_id'])), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + + + # Verifier si le modele de courrier est 'edit_by_client', au quel cas on verifie que l'apprenant est bien lié à un client + if ("edit_by_client" in courrier_template_data.keys() and str(courrier_template_data['edit_by_client']) == "1"): + stagiaire_client_id = "" + if( "client_rattachement_id" in inscription_data.keys() ): + stagiaire_client_id = str(inscription_data['client_rattachement_id']) + + if( str(stagiaire_client_id).strip() == "" ): + mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible d'envoyer un document édité par client à un stagiaire qui n'est pas rattaché à un client. L'email de l'apprenant est "+str(inscription_data['email'])+" ") + return False, " Impossible d'envoyer un document édité par client à un stagiaire qui n'est pas rattaché à un client. L'email de l'apprenant est "+str(inscription_data['email'])+" " + + + + tab_participant = [] + tab_participant.append(inscription_data['_id']) + + #Recuperations des info de la session de formation + session_data = MYSY_GV.dbname['session_formation'].find_one({'_id': ObjectId(str(inscription_data['session_id'])),'valide': '1', 'partner_owner_recid':str(my_partner['recid'])}) + + tab_session = [] + tab_session.append(session_data['_id']) + + """ + update du 30/01/2024 + si le participant à un apprenant_id, alors on recupere la valeur de l'apprenant id. On doit travailler sur cette dernier. + En general, avant d'envoyer une convocation ou convention, l'inscription est validée et donc le dossier apprenant existe. + Du coup si tout se passe bien, dans cette fonction, on travaillera tjrs avec l'apprenant_id + """ + tab_apprenant = [] + if ("apprenant_id" in inscription_data.keys() and inscription_data['apprenant_id']): + tab_apprenant.append(ObjectId(str(inscription_data['apprenant_id']))) + + + # Recuperation du titre de la formation + class_data = MYSY_GV.dbname['myclass'].find_one({'internal_url': str(session_data['class_internal_url']),'valide': '1', + 'partner_owner_recid':str(my_partner['recid']), 'locked':'0'}) + + tab_class = [] + tab_class.append(class_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'] = tab_participant + new_diction['list_session_id'] = tab_session + new_diction['list_class_id'] = tab_class + new_diction['list_client_id'] = [] + new_diction['list_apprenant_id'] = tab_apprenant + + 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 + + if( "company_data" in local_retval.keys() and "societe_nom" in local_retval['company_data'].keys() ): + company_name = local_retval['company_data']['societe_nom'] + + body = { + "params": convention_dictionnary_data, + } + + orig_file_name = "" + outputFilename = "" + + # Verifier s'il s'agit d'un document à envoyer avec une version de pièce jointe. + if ("joint_pdf" in courrier_template_data.keys() and str(courrier_template_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(courrier_template_data['contenu_doc'])) + + sourceHtml = contenu_doc_Template.render(params=body["params"]) + + """ + new_model_courrier_with_code_tag = str( + sourceHtml) + "

Signature manuscrite
 


" \ + "

 

" + """ + new_model_courrier_with_code_tag = "
" \ + "
" \ + " " \ + "
" + \ + str(sourceHtml) + "
" \ + " Signature manuscrite

" \ + "
" + + + todays_date = str(date.today().strftime("%d/%m/%Y")) + ts = datetime.now().timestamp() + ts = str(ts).replace(".", "").replace(",", "")[-5:] + + orig_file_name = "Convent_" + 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(courrier_template_data['corps_mail'])) + + sourceHtml = corps_mail_Template.render(params=body["params"]) + + html_mime = MIMEText(sourceHtml, 'html') + + # Creation de l'email à enoyer + msg = MIMEMultipart("alternative") + + """ + 20/03/2024 : la convention pdf a été créée. + Si le partenaire a l'option de signature digitale, alors on créé le e-document + """ + if (is_partner_digital_signature == "1"): + new_e_document_diction = {} + new_e_document_diction['token'] = diction['token'] + new_e_document_diction['file_name'] = outputFilename + toaddrs = ",".join(tab_emails_destinataire) + new_e_document_diction['email_destinataire'] = str(toaddrs) + new_e_document_diction['source_document'] = new_model_courrier_with_code_tag + + new_e_document_diction['related_collection'] = "inscription" + new_e_document_diction['related_collection_id'] = str(inscription_data['_id']) + + new_e_document_diction['class_id'] = str(session_data['class_id']) + new_e_document_diction['session_d'] = str(session_data['_id']) + + + todays_date = str(date.today().strftime("%d/%m/%Y")) + ts = datetime.now().timestamp() + ts = str(ts).replace(".", "").replace(",", "")[-2:] + + cononic_name = "Convent_" + str(todays_date) + "_" + str(ts) + new_e_document_diction['file_cononical_name'] = cononic_name + new_e_document_diction['type'] = "convention" + + #print(" ### 022 new_e_document_diction = ", new_e_document_diction) + + local_status_e_doc, local_retval_e_doc = E_Sign_Document.Create_E_Document(new_e_document_diction) + + if (local_status_e_doc is False): + return local_status_e_doc, local_retval_e_doc + + """ + Apres la creation du document electronique, on envoie la demande de validation + Important : on envoie le mail à chaque destinataire + """ + + for email in tab_emails_destinataire: + print(" ### traitement du mail : ", email) + new_send_e_document_diction = {} + new_send_e_document_diction['token'] = diction['token'] + new_send_e_document_diction['e_doc_id'] = str(local_retval_e_doc) + new_send_e_document_diction['user_email'] = str(email) + + local_status_send_e_doc, local_send_retval_e_doc = E_Sign_Document.Sent_E_Document_Signature_Request( + new_send_e_document_diction) + if (local_status_send_e_doc is False): + return local_status_send_e_doc, local_send_retval_e_doc + + else: + # Il s'agit d'une simple email + + ## Creation du mail au format email + + contenu_doc_Template = jinja2.Template(str(courrier_template_data['contenu_doc'])) + + sourceHtml = contenu_doc_Template.render(params=body["params"]) + + + html_mime = MIMEText(sourceHtml, 'html') + + # Creation de l'email à enoyer + msg = MIMEMultipart("alternative") + + + """ + Recuperation des parametre SMTP du partner si le client a decidé d'utiliser son propre smpt + """ + partner_own_smtp_value = "0" + partner_own_smtp = MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'partner_smtp', + 'valide': '1', + 'locked': '0'}) + + if (partner_own_smtp and "config_value" in partner_own_smtp.keys()): + partner_own_smtp_value = partner_own_smtp['config_value'] + + if (str(partner_own_smtp_value) == "1"): + partner_SMTP_COUNT_password = str(MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'smtp_user_pwd', + 'valide': '1', + 'locked': '0'}, {'config_value': 1})['config_value']) + + partner_SMTP_COUNT_smtpsrv = str(MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'smtp_server', + 'valide': '1', + 'locked': '0'}, {'config_value': 1})['config_value']) + + partner_SMTP_COUNT_user = str(MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'smtp_user', + 'valide': '1', + 'locked': '0'}, {'config_value': 1})['config_value']) + + partner_SMTP_COUNT_From_User = str(MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'smtp_count_from_name', + 'valide': '1', + 'locked': '0'}, {'config_value': 1})['config_value']) + + partner_SMTP_COUNT_port = str(MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'smtp_count_port', + 'valide': '1', + 'locked': '0'}, {'config_value': 1})['config_value']) + + if (str(partner_own_smtp_value) == "1"): + smtpserver = smtplib.SMTP(partner_SMTP_COUNT_smtpsrv, partner_SMTP_COUNT_port) + else: + smtpserver = smtplib.SMTP(MYSY_GV.O365_SMTP_COUNT_smtpsrv, MYSY_GV.O365_SMTP_COUNT_port) + + if (str(partner_own_smtp_value) == "1"): + msg.attach(html_mime) + msg['From'] = partner_SMTP_COUNT_From_User + msg['Bcc'] = 'contact@mysy-training.com' + msg['Subject'] = courrier_template_data['sujet'] + #msg['to'] = "billardman01@hotmail.com" + toaddrs = ",".join(tab_emails_destinataire) + msg['to'] = str(toaddrs) + + # Attacher l'eventuelle pièces jointes + for myfile in tab_files_to_attache_to_mail: + msg.attach(myfile['attached_file']) + + smtpserver.ehlo() + smtpserver.starttls() + smtpserver.login(partner_SMTP_COUNT_user, partner_SMTP_COUNT_password) + + else: + msg.attach(html_mime) + if( company_name): + msg['From'] = str(company_name)+" <"+str(MYSY_GV.O365_SMTP_COUNT_From_User)+">" + else: + msg['From'] = str(MYSY_GV.O365_SMTP_COUNT_From_User) + + #print(" ### FROM = ", str(msg['From']) ) + + msg['Bcc'] = 'contact@mysy-training.com' + msg['Subject'] = courrier_template_data['sujet'] + #msg['to'] = "billardman01@hotmail.com" + toaddrs = ",".join(tab_emails_destinataire) + msg['to'] = str(toaddrs) + + + for myfile in tab_files_to_attache_to_mail: + msg.attach(myfile['attached_file']) + + + 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)) + + """ + 11/04/2026 - Gestion des emails via mail_queu et internal email/ + """ + + # Traitement du sujet du mail + #sujet_mail_Template = jinja2.Template(courrier_template_data['sujet']) + sujetHtml = courrier_template_data['sujet'] + + # Recuperation des donnes smtp + (local_stpm_status, local_SMTP_COUNT_smtpsrv, local_own_smtp_value, local_SMTP_COUNT_password, + local_SMTP_COUNT_user, local_SMTP_COUNT_From_User, + local_SMTP_COUNT_port) = mycommon.Get_Partner_SMTP_Param(str(my_partner['recid'])) + + if (local_stpm_status is False): + return local_stpm_status, local_SMTP_COUNT_smtpsrv + + tab_email_bcc = [] + tab_email_bcc.append("contact@mysy-training.com") + + """ + IMPORTANT : Cette section sera utilisée une fois que le module de Queu de message est ok + """ + queue_mail_diction = {} + queue_mail_diction['token'] = diction['token'] + queue_mail_diction['tab_email_cc'] = [] + queue_mail_diction['tab_email_bcc'] = tab_email_bcc + if (sujetHtml): + queue_mail_diction['email_sujet'] = sujetHtml + else: + queue_mail_diction['email_sujet'] = '[MySy Training]: Convention individuelle de formation' + + corps_mail_Template = jinja2.Template(str(courrier_template_data['corps_mail'])) + + sourceHtml = corps_mail_Template.render(params=body["params"]) + queue_mail_diction['message'] = sourceHtml + + queue_mail_diction['smtp_account_password'] = local_SMTP_COUNT_password + queue_mail_diction['smtp_account_smtpsrv'] = local_SMTP_COUNT_smtpsrv + queue_mail_diction['smtp_account_user'] = local_SMTP_COUNT_user + queue_mail_diction['smtp_account_From_User'] = local_SMTP_COUNT_From_User + queue_mail_diction['smtp_account_port'] = local_SMTP_COUNT_port + + queue_mail_diction['tab_files_to_attache_to_mail'] = [] + + toaddrs = ",".join(tab_emails_destinataire) + queue_mail_diction['email_to'] = str(toaddrs) + + #print(" ### convention dans queu mail queue_mail_diction = ", queue_mail_diction) + + queue_and_internal_mail_status, queue_and_internal_mail_status = email_mgt.Individual_Mail_Store_Queu_And_Internal_Mail( + queue_mail_diction) + if (queue_and_internal_mail_status is False): + print(" ## WARNING queue_mail_retval = ", queue_and_internal_mail_status) + + """ + 25/01/2024 : pour loger une action dans la collection ==> courrier_template_tracking_history + """ + local_status, local_retval = module_editique.Editic_Log_History_Action(my_partner, courrier_template_data, + str(diction['session_id']), + "inscription", + str(diction['inscription_id'])) + + + """ + # Ajout de l'evenement dans l'historique + """ + + # L'action n'est loggué pour les envois reels (en prod) + if( send_in_production == 1): + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + history_event_dict = {} + history_event_dict['token'] = diction['token'] + history_event_dict['related_collection'] = "inscription" + history_event_dict['related_collection_recid'] = str(diction['inscription_id']) + history_event_dict['action_date'] = str(now) + + local_session_info = "" + if ("code_session" in session_data.keys()): + local_session_info = local_session_info + ", " + session_data["code_session"] + else: + local_session_info = "Id Session : " + str(session_data['_id']) + + history_event_dict['action_description'] = "Convention envoyée par email à la liste : "+str(tab_emails_destinataire)+" pour la session "+str(local_session_info) + 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)) + + # Pour la session + history_event_dict = {} + history_event_dict['token'] = diction['token'] + history_event_dict['related_collection'] = "session_formation" + history_event_dict['related_collection_recid'] = str(session_data['_id']) + history_event_dict['action_date'] = str(now) + + local_inscrit_info = "Id Inscrit : " + str(inscription_data['_id']) + if ("email" in inscription_data.keys()): + local_inscrit_info = local_inscrit_info + ", " + inscription_data["email"] + + if ("nom" in inscription_data.keys()): + local_inscrit_info = local_inscrit_info + ", " + inscription_data["nom"] + + if ("prenom" in inscription_data.keys()): + local_inscrit_info = local_inscrit_info + ", " + inscription_data["prenom"] + + + history_event_dict['action_description'] = "Convention envoyée par email à la liste : " + str( + tab_emails_destinataire)+" Pour l'inscrit "+str(local_inscrit_info) + 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)) + + if (orig_file_name and outputFilename): + new_file = {} + new_file['token'] = diction['token'] + type_document = "Convention" + + new_file['file_business_object'] = str(orig_file_name) + + new_file['file_name'] = str(orig_file_name) + new_file['status'] = "1" + new_file['type_document'] = str(type_document) + + new_file['object_owner_collection'] = "inscription" + new_file['object_owner_id'] = str(diction['inscription_id']) + + new_file['file_name_to_store'] = outputFilename + + tab_key_word = "convention," + str(class_data['external_code']) + "," + str( + session_data['code_session']) + new_file['tab_key_word'] = tab_key_word + + tab_related_collection = [] + if (class_data): + node_class = {} + node_class['related_collection'] = 'myclass' + node_class['related_collection_id'] = str(class_data['_id']) + tab_related_collection.append(node_class) + + if (session_data): + node_session = {} + node_session['related_collection'] = 'session_formation' + node_session['related_collection_id'] = str(session_data['_id']) + tab_related_collection.append(node_session) + + + # print(" ### new_file new_file = ", new_file) + local_status, local_retval = attached_file_mgt.Internal_Usage_Store_User_Downloaded_File( + MYSY_GV.upload_folder, new_file, tab_related_collection) + + if (local_status is False): + print(" ## WARINNGGG Impossible de stocker le fichier de Convocation ") + + 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 la convention par email " + + +""" +Comme la fonction plus haut (Sent_Convention_Stagiaire_By_Email) cette fonction est un clone +qui envoie uniquement et exclusivement les conventions individuelles. + +Je les ai separé vu la complexité de la fonction et eviter des effets de bors/ + +""" + + +def Sent_Convention_Individuelle_Stagiaire_By_Email(tab_files, Folder, diction): + try: + + field_list_obligatoire = ['token', 'inscription_id', 'courrier_template_id', 'email_test', 'email_production'] + + 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 + + # Verifier que le stagiaire est bien inscrit. Le statut de l'inscription doit etre "1" et qu'il n'est rattaché à aucun client + is_inscription_valide = MYSY_GV.dbname['inscription'].count_documents( + {'$or': [ + {'_id': ObjectId(str(diction['inscription_id'])), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid']), + 'client_rattachement_id': ''}, + {'_id': ObjectId(str(diction['inscription_id'])), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid']), + 'client_rattachement_id': {'$exists': False} + }]}) + + if (is_inscription_valide != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de l'inscription est invalide ") + return False, " L'identifiant de l'inscription est invalide " + + # Recuperation des données du stagaire + inscription_data = MYSY_GV.dbname['inscription'].find_one({'_id': ObjectId(str(diction['inscription_id'])), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + # Recupérer la liste des participants concernés + tab_participant = [] + tab_participant.append(inscription_data['_id']) + + """ + update du 30/01/2024 + si le participant à un apprenant_id, alors on recupere la valeur de l'apprenant id. On doit travailler sur cette dernier. + En general, avant d'envoyer une convocation ou convention, l'inscription est validée et donc le dossier apprenant existe. + Du coup si tout se passe bien, dans cette fonction, on travaillera tjrs avec l'apprenant_id + """ + tab_apprenant = [] + if ("apprenant_id" in inscription_data.keys() and inscription_data['apprenant_id']): + tab_apprenant.append(ObjectId(str(inscription_data['apprenant_id']))) + + + # Traitement de l'eventuel fichier joint + tab_files_to_attache_to_mail = [] + + # Sauvegarde des fichiers joints depuis le front + tab_saved_file_full_path = [] + for file in tab_files: + status, saved_file_full_path = mycommon.Upload_Save_PDF_IMG_File(file, Folder) + if (status is False): + mycommon.myprint("Impossible de récupérer correctement le fichier à importer") + return False, "Impossible de récupérer correctement le fichier à importer" + + tab_saved_file_full_path.append(saved_file_full_path) + + for saved_file in tab_saved_file_full_path: + """ + status, saved_file = mycommon.Upload_Save_PDF_IMG_File(file, Folder) + if (status is False): + mycommon.myprint("Impossible de récupérer correctement le fichier à importer") + return False, "Impossible de récupérer correctement le fichier à importer" + """ + + 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) + + # Verification de la validité des adresses email_recu + """ + Important : : Si l'email de test est repli, alors on considere que c'est un test, on ne prend pas en compte l'email de email_production. + Ceci pour forcer les utilisateur à ne remplir que l'email de prod s'il veulent l'envoyer en prod. + + Si l'adresse email_prodution = "defaul", cela veut dire qu'on envoie la convention à : + - l'adresse email du stagiaire et ses tuteurs (si les tuteurs on cochés la case 'inclu com' + + """ + + 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 + # On va chercher les adresse email de communication du + local_dict = {'token': str(diction['token']), '_id': str(diction['inscription_id'])} + + local_status, tab_apprenant_contact = Get_Statgiaire_Communication_Contact(local_dict) + if (local_status is False): + return local_status, tab_apprenant_contact + + tmp_tab = [] + #print(" ### tab_apprenant_contact = ", tab_apprenant_contact) + + for tmp in tab_apprenant_contact: + if ("email" in tmp.keys()): + tab_emails_destinataire.append((tmp['email'])) + + if (len(tab_emails_destinataire) <= 0): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " Aucune adresse email n'a pas été fournie. 01 ") + return False, " Aucune adresse email n'a pas été fournie. 01 " + + # print(" ### tab_emails_destinataire = ", tab_emails_destinataire) + + # Verifier que le 'courrier_template_id' est valide + # Ici le template doit etre un email + courrier_template_data = None + if (str(diction['courrier_template_id']) == "default_mail"): + """ + # Verifier qu'il y a bien un modele de courrier de convention individuelle par defaut + - ref_interne = CONVENTION_STAGIAIRE + - default_version = 1 + - edit_by_client = '0' ou n'existe pas + - type_doc = email + """ + + is_courrier_template_id_valide = MYSY_GV.dbname['courrier_template'].count_documents({"$or": [ + {'valide': '1', + 'locked': '0', + 'type_doc': 'email', + 'partner_owner_recid': str(my_partner['recid']), + 'ref_interne': 'CONVENTION_STAGIAIRE', + 'default_version': '1', + 'edit_by_client': '0' + }, + {'valide': '1', + 'locked': '0', + 'type_doc': 'email', + 'partner_owner_recid': str(my_partner['recid']), + 'ref_interne': 'CONVENTION_STAGIAIRE', + 'default_version': '1', + 'edit_by_client': {'$exists': False} + } + ]}) + + if (is_courrier_template_id_valide != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " Aucun modèle de courrier PDF par defaut pour les conventions individuelles ") + return False, " Aucun modèle de courrier PDF par defaut pour les conventions individuelles " + + # Recupération des données du modèle de document + courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one({"$or": [ + {'valide': '1', + 'locked': '0', + 'type_doc': 'email', + 'partner_owner_recid': str(my_partner['recid']), + 'ref_interne': 'CONVENTION_STAGIAIRE', + 'default_version': '1', + 'edit_by_client': '0' + }, + {'valide': '1', + 'locked': '0', + 'type_doc': 'email', + 'partner_owner_recid': str(my_partner['recid']), + 'ref_interne': 'CONVENTION_STAGIAIRE', + 'default_version': '1', + 'edit_by_client': {'$exists': False} + } + ]}) + + else: + # Verifier que le 'courrier_template_id' est valide. il doit etre de type PDF + qry = {'_id': ObjectId(str(diction['courrier_template_id'])), + 'valide': '1', + 'locked': '0', + 'type_doc': 'email', + 'partner_owner_recid': str(my_partner['recid'])} + + is_courrier_template_id_valide = MYSY_GV.dbname['courrier_template'].count_documents( + {'_id': ObjectId(str(diction['courrier_template_id'])), + 'valide': '1', + 'locked': '0', + 'type_doc': 'email', + 'partner_owner_recid': str(my_partner['recid'])} + ) + + if (is_courrier_template_id_valide != 1): + 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 " + + # Recupération des données du modèle de document + courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one( + {'_id': ObjectId(str(diction['courrier_template_id'])), + 'valide': '1', + 'locked': '0', + 'type_doc': 'email', + 'partner_owner_recid': str(my_partner['recid'])} + ) + + if (courrier_template_data is None): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " Impossile d'identifier le modèle de courrier ") + return False, " Impossile d'identifier le modèle de courrier " + + + + # 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(courrier_template_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 + + # print(" ### file stocké = ", local_retval) + + # 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) + + + + # Recuperations des info de la session de formation + session_data = MYSY_GV.dbname['session_formation'].find_one( + {'_id': ObjectId(str(inscription_data['session_id'])), 'valide': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + tab_session = [] + tab_session.append(session_data['_id']) + + # Recuperation du titre de la formation + class_data = MYSY_GV.dbname['myclass'].find_one( + {'internal_url': str(session_data['class_internal_url']), 'valide': '1', + 'partner_owner_recid': str(my_partner['recid']), 'locked': '0'}) + + tab_class = [] + tab_class.append(class_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'] = tab_participant + new_diction['list_session_id'] = tab_session + new_diction['list_class_id'] = tab_class + new_diction['list_client_id'] = [] + new_diction['list_apprenant_id'] = tab_apprenant + + 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 + + if ("company_data" in local_retval.keys() and "societe_nom" in local_retval['company_data'].keys()): + company_name = local_retval['company_data']['societe_nom'] + + body = { + "params": convention_dictionnary_data, + } + + # Verifier s'il s'agit d'un document à envoyer avec une version de pièce jointe. + if ("joint_pdf" in courrier_template_data.keys() and str(courrier_template_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(courrier_template_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 = "Convent_" + 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(courrier_template_data['corps_mail'])) + + sourceHtml = corps_mail_Template.render(params=body["params"]) + + html_mime = MIMEText(sourceHtml, 'html') + + # Creation de l'email à enoyer + msg = MIMEMultipart("alternative") + + else: + # Il s'agit d'une simple email + + ## Creation du mail au format email + + contenu_doc_Template = jinja2.Template(str(courrier_template_data['contenu_doc'])) + + sourceHtml = contenu_doc_Template.render(params=body["params"]) + + html_mime = MIMEText(sourceHtml, 'html') + + # Creation de l'email à enoyer + msg = MIMEMultipart("alternative") + + """ + Recuperation des parametre SMTP du partner si le client a decidé d'utiliser son propre smpt + """ + partner_own_smtp_value = "0" + partner_own_smtp = MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'partner_smtp', + 'valide': '1', + 'locked': '0'}) + + if (partner_own_smtp and "config_value" in partner_own_smtp.keys()): + partner_own_smtp_value = partner_own_smtp['config_value'] + + if (str(partner_own_smtp_value) == "1"): + partner_SMTP_COUNT_password = str(MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'smtp_user_pwd', + 'valide': '1', + 'locked': '0'}, {'config_value': 1})['config_value']) + + partner_SMTP_COUNT_smtpsrv = str(MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'smtp_server', + 'valide': '1', + 'locked': '0'}, {'config_value': 1})['config_value']) + + partner_SMTP_COUNT_user = str(MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'smtp_user', + 'valide': '1', + 'locked': '0'}, {'config_value': 1})['config_value']) + + partner_SMTP_COUNT_From_User = str(MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'smtp_count_from_name', + 'valide': '1', + 'locked': '0'}, {'config_value': 1})['config_value']) + + partner_SMTP_COUNT_port = str(MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'smtp_count_port', + 'valide': '1', + 'locked': '0'}, {'config_value': 1})['config_value']) + + if (str(partner_own_smtp_value) == "1"): + smtpserver = smtplib.SMTP(partner_SMTP_COUNT_smtpsrv, partner_SMTP_COUNT_port) + else: + smtpserver = smtplib.SMTP(MYSY_GV.O365_SMTP_COUNT_smtpsrv, MYSY_GV.O365_SMTP_COUNT_port) + + if (str(partner_own_smtp_value) == "1"): + msg.attach(html_mime) + msg['From'] = partner_SMTP_COUNT_From_User + msg['Bcc'] = 'contact@mysy-training.com' + msg['Subject'] = courrier_template_data['sujet'] + # msg['to'] = "billardman01@hotmail.com" + toaddrs = ",".join(tab_emails_destinataire) + msg['to'] = str(toaddrs) + + # Attacher l'eventuelle pièces jointes + for myfile in tab_files_to_attache_to_mail: + msg.attach(myfile['attached_file']) + + smtpserver.ehlo() + smtpserver.starttls() + smtpserver.login(partner_SMTP_COUNT_user, partner_SMTP_COUNT_password) + + else: + msg.attach(html_mime) + #msg['From'] = MYSY_GV.O365_SMTP_COUNT_From_User + if (company_name): + msg['From'] = str(company_name) + " <" + str(MYSY_GV.O365_SMTP_COUNT_From_User) + ">" + else: + msg['From'] = str(MYSY_GV.O365_SMTP_COUNT_From_User) + + msg['Bcc'] = 'contact@mysy-training.com' + msg['Subject'] = courrier_template_data['sujet'] + # msg['to'] = "billardman01@hotmail.com" + toaddrs = ",".join(tab_emails_destinataire) + msg['to'] = str(toaddrs) + + for myfile in tab_files_to_attache_to_mail: + msg.attach(myfile['attached_file']) + + 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)) + + """ + # Ajout de l'evenement dans l'historique + """ + + # L'action n'est loggué pour les envois reels (en prod) + if (send_in_production == 1): + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + history_event_dict = {} + history_event_dict['token'] = diction['token'] + history_event_dict['related_collection'] = "inscription" + history_event_dict['related_collection_recid'] = str(diction['inscription_id']) + history_event_dict['action_date'] = str(now) + + local_session_info = "" + if ("code_session" in session_data.keys()): + local_session_info = local_session_info + ", " + session_data["code_session"] + else: + local_session_info = "Id Session : " + str(session_data['_id']) + + + history_event_dict['action_description'] = "Convention envoyée par email à la liste : " + str( + tab_emails_destinataire) + " pour la session " + str(local_session_info) + + 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)) + + # Pour la session + history_event_dict = {} + history_event_dict['token'] = diction['token'] + history_event_dict['related_collection'] = "session_formation" + history_event_dict['related_collection_recid'] = str(session_data['_id']) + history_event_dict['action_date'] = str(now) + + local_inscrit_info = "Id Inscrit : " + str(inscription_data['_id']) + if ("email" in inscription_data.keys()): + local_inscrit_info = local_inscrit_info + ", " + inscription_data["email"] + + if ("nom" in inscription_data.keys()): + local_inscrit_info = local_inscrit_info + ", " + inscription_data["nom"] + + if ("prenom" in inscription_data.keys()): + local_inscrit_info = local_inscrit_info + ", " + inscription_data["prenom"] + + history_event_dict['action_description'] = "Convention envoyée par email à la liste : " + str( + tab_emails_destinataire) + " Pour l'inscrit " + str(local_inscrit_info) + 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, "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 la convention par email " + + + + +""" +Cette fonction envoie les convention en masse +Dans cette fonction, les adresse emails de destination sont recuperé dans la fonction. +Ce n'est l'utilisateur qui envoie le fonction +""" + + +def Sent_Convention_Stagiaire_By_Email_mass(tab_files, Folder, diction): + try: + field_list_obligatoire = ['token', 'tab_inscription_id', 'courrier_template_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 + + + + # Verifier que le 'courrier_template_id' est valide + # Ici le template doit etre un email + is_courrier_template_id_valide = MYSY_GV.dbname['courrier_template'].count_documents( + {'_id': ObjectId(str(diction['courrier_template_id'])), + 'valide': '1', + 'type_doc': 'email', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])} + ) + + if (is_courrier_template_id_valide != 1): + 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 " + + + tab_new_diction = [] + tab_inscription_id = str(diction['tab_inscription_id']).split(",") + for inscription_id in tab_inscription_id: + # Verifier que le stagiaire est bien inscrit. Le statut de l'inscription doit etre "1" + + is_inscription_valide = MYSY_GV.dbname['inscription'].count_documents( + {'_id': ObjectId(str(inscription_id)), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_inscription_valide != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de l'inscription est invalide ") + return False, " L'identifiant de l'inscription est invalide " + + # Récuperation des emails de communication de cette inscription + local_status, local_list_mail = Get_Stagiaire_Communication_List_Email({'token':diction['token'], 'inscription_id':str(inscription_id)}) + if( local_status is False ): + return local_status, local_list_mail + + + tab_liste_mail = [] + liste_mail_string = "" + for email in local_list_mail: + email_JSON = ast.literal_eval(email) + if( 'email' in email_JSON.keys() ): + tab_liste_mail.append(email_JSON['email']) + + liste_mail_string = ', '.join(tab_liste_mail) + + new_node = {} + new_node['token'] = str(diction['token']) + new_node['inscription_id'] = str(inscription_id) + new_node['courrier_template_id'] = str(diction['courrier_template_id']) + new_node['email_production'] = str(liste_mail_string) + new_node['email_test'] = "" + + tab_new_diction.append(new_node) + + nb_convocation_send = 0 + warning_msg = " WARNING : Convocation(s) envoyée(s) avec les erreurs suivantes : \n : " + is_warning_msg = False + for new_diction in tab_new_diction: + local_status, local_retval = Sent_Convention_Stagiaire_By_Email(tab_files, Folder, new_diction) + if( local_status is False): + warning_msg = warning_msg + " Impossible d'envoyer les convocation à l'apprenant avec ayant la liste de communication : "+str(new_diction['email_production']) +" \n " + is_warning_msg = True + else: + nb_convocation_send = nb_convocation_send + 1 + + if( is_warning_msg ): + return True, str(warning_msg) + else: + return True, str(nb_convocation_send)+" convocation(s) envoyée(s) " + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible d'envoyer la convention par email " + + + + + +""" +Creation d'un fichie zip de pdf +""" + +def Download_zip_PDF(): + try: + + files = ['./temp_direct/pdf1.pdf', './temp_direct/pdf3.pdf', './temp_direct/pdf3.pdf'] + + # Create a ZipFile Object + with ZipFile('./temp_direct/mysy.zip', 'w') as zip_object: + # Adding files that need to be zipped + zip_object.write('./temp_direct/pdf1.pdf') + zip_object.write('./temp_direct/pdf3.pdf') + zip_object.write('./temp_direct/pdf3.pdf') + + # Check to see if the zip file is created + if os.path.exists('./temp_direct/mysy.zip'): + print("ZIP file created") + else: + print("ZIP file not created") + + if os.path.exists("./temp_direct/mysy.zip"): + # print(" ### ok os.path.exists(outputFilename) "+str(outputFilename)) + return True, send_file("./temp_direct/mysy.zip", as_attachment=True) + + return False, " Impossible de générer le fichier PDF (2) " + + + 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 générer le fichier PDF (2) " + +""" +Impression de la convocation en mode PDF +""" + +def Download_Convention_Stagiaire_PDF(diction): + try: + field_list_obligatoire = ['token', 'inscription_id', 'courrier_template_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 + + # Verifier que le stagiaire est bien inscrit. Le statut de l'inscription doit etre "1" + is_inscription_valide = MYSY_GV.dbname['inscription'].count_documents( + {'_id': ObjectId(str(diction['inscription_id'])), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_inscription_valide != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de l'inscription est invalide ") + return False, " L'identifiant de l'inscription est invalide " + + + courrier_template_data = None + if( str(diction['courrier_template_id']) == "default_pdf"): + """ + # Verifier qu'il y a bien un modele de courrier de convention individuelle par defaut + - ref_interne = CONVENTION_STAGIAIRE + - default_version = 1 + - edit_by_client = '0' ou n'existe pas + - type_doc = pdf + """ + + is_courrier_template_id_valide = MYSY_GV.dbname['courrier_template'].count_documents({"$or": [ + {'valide': '1', + 'locked': '0', + 'type_doc': 'pdf', + 'partner_owner_recid': str(my_partner['recid']), + 'ref_interne': 'CONVENTION_STAGIAIRE', + 'default_version': '1', + 'edit_by_client': '0' + }, + {'valide': '1', + 'locked': '0', + 'type_doc': 'pdf', + 'partner_owner_recid': str(my_partner['recid']), + 'ref_interne': 'CONVENTION_STAGIAIRE', + 'default_version': '1', + 'edit_by_client': {'$exists': False} + } + ]}) + + if (is_courrier_template_id_valide != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " Aucun modèle de courrier PDF par defaut pour les conventions individuelles ") + return False, " Aucun modèle de courrier PDF par defaut pour les conventions individuelles " + + # Recupération des données du modèle de document + courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one({"$or": [ + {'valide': '1', + 'locked': '0', + 'type_doc': 'pdf', + 'partner_owner_recid': str(my_partner['recid']), + 'ref_interne': 'CONVENTION_STAGIAIRE', + 'default_version': '1', + 'edit_by_client': '0' + }, + {'valide': '1', + 'locked': '0', + 'type_doc': 'pdf', + 'partner_owner_recid': str(my_partner['recid']), + 'ref_interne': 'CONVENTION_STAGIAIRE', + 'default_version': '1', + 'edit_by_client': {'$exists': False} + } + ]}) + + else: + # Verifier que le 'courrier_template_id' est valide. il doit etre de type PDF + qry = {'_id': ObjectId(str(diction['courrier_template_id'])), + 'valide': '1', + 'locked': '0', + 'type_doc': 'pdf', + 'partner_owner_recid': str(my_partner['recid'])} + + is_courrier_template_id_valide = MYSY_GV.dbname['courrier_template'].count_documents( + {'_id': ObjectId(str(diction['courrier_template_id'])), + 'valide': '1', + 'locked': '0', + 'type_doc': 'pdf', + 'partner_owner_recid': str(my_partner['recid'])} + ) + + if (is_courrier_template_id_valide != 1): + 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 " + + # Recupération des données du modèle de document + courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one( + {'_id': ObjectId(str(diction['courrier_template_id'])), + 'valide': '1', + 'locked': '0', + 'type_doc': 'pdf', + 'partner_owner_recid': str(my_partner['recid'])} + ) + + if( courrier_template_data is None ): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " Impossile d'identifier le modèle de courrier ") + return False, " Impossile d'identifier le modèle de courrier " + + # Recuperation des données du stagaire + inscription_data = MYSY_GV.dbname['inscription'].find_one({'_id': ObjectId(str(diction['inscription_id'])), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + # Recuperation des données du partenaire associé à l'utilisateur connecté + local_status, local_retval = mycommon.Get_Connected_User_Partner_Data_From_RecID(my_partner['recid']) + if (local_status is False): + return local_status, local_retval + + company_data = local_retval + + + # Recuperations des info de la session de formation + tab_session = [] + session_data = MYSY_GV.dbname['session_formation'].find_one( + {'_id': ObjectId(str(inscription_data['session_id'])), 'valide': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + tab_session.append(session_data['_id']) + + + # Recupérer la liste des participant pour une eventuelle à afficher pour les conventions d'entreprise + tab_participant = [] + tab_apprenant = [] + list_participants_session = MYSY_GV.dbname['inscription'].find({'session_id':str(session_data['_id']), 'status':'1', + 'partner_owner_recid':str(my_partner['recid'])}, + {'email':1, 'nom':1, 'prenom':1, '_id':1}).sort([("nom", pymongo.DESCENDING)]) + + for val in list_participants_session: + tab_participant.append(val['_id']) + + """ + update du 30/01/2024 + si le participant à un apprenant_id, alors on recupere la valeur de l'apprenant id. On doit travailler sur cette dernier. + En general, avant d'envoyer une convocation ou convention, l'inscription est validée et donc le dossier apprenant existe. + Du coup si tout se passe bien, dans cette fonction, on travaillera tjrs avec l'apprenant_id + """ + + if ("apprenant_id" in val.keys() and val['apprenant_id']): + tab_apprenant.append(ObjectId(str(val['apprenant_id']))) + + + # Recuperation du titre de la formation + class_data = MYSY_GV.dbname['myclass'].find_one( + {'internal_url': str(session_data['class_internal_url']), 'valide': '1', + 'partner_owner_recid': str(my_partner['recid']), 'locked': '0'}) + + tab_class = [] + tab_class.append(class_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'] = tab_participant + new_diction['list_session_id'] = tab_session + new_diction['list_class_id'] = tab_class + new_diction['list_client_id'] = [] + new_diction['list_apprenant_id'] = tab_apprenant + + 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 + + + #print(" ### convention_dictionnary_data = ", convention_dictionnary_data) + + body = { + "params": convention_dictionnary_data, + } + + json_formatted_str = json.dumps(body, indent=2) + + print(json_formatted_str) + + ## Creation du PDF + + contenu_doc_Template = jinja2.Template(str(courrier_template_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 = "Convent_" + 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() + + if os.path.exists(outputFilename): + #print(" ### ok os.path.exists(outputFilename) "+str(outputFilename)) + return True, send_file(outputFilename, as_attachment=True) + + return False, " Impossible de générer le fichier PDF (2) " + + + 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 générer le fichier PDF (2) " + + +""" +Impression d'une convention individuelle en pdf +""" +def Download_Convention_Individuelle_Stagiaire_PDF(diction): + try: + field_list_obligatoire = ['token', 'inscription_id', 'courrier_template_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 + + # Verifier que le stagiaire est bien inscrit. Le statut de l'inscription doit etre "1" et qu'il n'est pas rattaché à un client + is_inscription_valide = MYSY_GV.dbname['inscription'].count_documents({'$or':[ + {'_id': ObjectId(str(diction['inscription_id'])), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid']), + 'client_rattachement_id':''}, + {'_id': ObjectId(str(diction['inscription_id'])), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid']), + 'client_rattachement_id': {'$exists': False} + }]} ) + + + + if (is_inscription_valide != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de l'inscription est invalide ") + return False, " L'identifiant de l'inscription est invalide " + + + courrier_template_data = None + if( str(diction['courrier_template_id']) == "default_pdf"): + """ + # Verifier qu'il y a bien un modele de courrier de convention individuelle par defaut + - ref_interne = CONVENTION_STAGIAIRE + - default_version = 1 + - edit_by_client = '0' ou n'existe pas + - type_doc = pdf + """ + + is_courrier_template_id_valide = MYSY_GV.dbname['courrier_template'].count_documents({"$or": [ + {'valide': '1', + 'locked': '0', + 'type_doc': 'pdf', + 'partner_owner_recid': str(my_partner['recid']), + 'ref_interne': 'CONVENTION_STAGIAIRE', + 'default_version': '1', + 'edit_by_client': '0' + }, + {'valide': '1', + 'locked': '0', + 'type_doc': 'pdf', + 'partner_owner_recid': str(my_partner['recid']), + 'ref_interne': 'CONVENTION_STAGIAIRE', + 'default_version': '1', + 'edit_by_client': {'$exists': False} + } + ]}) + + if (is_courrier_template_id_valide != 1): + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " Aucun modèle de courrier PDF par defaut pour les conventions individuelles ") + return False, " Aucun modèle de courrier PDF par defaut pour les conventions individuelles " + + # Recupération des données du modèle de document + courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one({"$or": [ + {'valide': '1', + 'locked': '0', + 'type_doc': 'pdf', + 'partner_owner_recid': str(my_partner['recid']), + 'ref_interne': 'CONVENTION_STAGIAIRE', + 'default_version': '1', + 'edit_by_client': '0' + }, + {'valide': '1', + 'locked': '0', + 'type_doc': 'pdf', + 'partner_owner_recid': str(my_partner['recid']), + 'ref_interne': 'CONVENTION_STAGIAIRE', + 'default_version': '1', + 'edit_by_client': {'$exists': False} + } + ]}) + + else: + # Verifier que le 'courrier_template_id' est valide. il doit etre de type PDF + qry = {'_id': ObjectId(str(diction['courrier_template_id'])), + 'valide': '1', + 'locked': '0', + 'type_doc': 'pdf', + 'partner_owner_recid': str(my_partner['recid'])} + + is_courrier_template_id_valide = MYSY_GV.dbname['courrier_template'].count_documents( + {'_id': ObjectId(str(diction['courrier_template_id'])), + 'valide': '1', + 'locked': '0', + 'type_doc': 'pdf', + 'partner_owner_recid': str(my_partner['recid'])} + ) + + if (is_courrier_template_id_valide != 1): + 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 " + + # Recupération des données du modèle de document + courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one( + {'_id': ObjectId(str(diction['courrier_template_id'])), + 'valide': '1', + 'locked': '0', + 'type_doc': 'pdf', + 'partner_owner_recid': str(my_partner['recid'])} + ) + + if( courrier_template_data is None ): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " Impossile d'identifier le modèle de courrier ") + return False, " Impossile d'identifier le modèle de courrier " + + # Recuperation des données du stagaire + inscription_data = MYSY_GV.dbname['inscription'].find_one({'_id': ObjectId(str(diction['inscription_id'])), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + tab_participant = [] + tab_participant.append(inscription_data['_id']) + + """ + update du 30/01/2024 + si le participant à un apprenant_id, alors on recupere la valeur de l'apprenant id. On doit travailler sur cette dernier. + En general, avant d'envoyer une convocation ou convention, l'inscription est validée et donc le dossier apprenant existe. + Du coup si tout se passe bien, dans cette fonction, on travaillera tjrs avec l'apprenant_id + """ + tab_apprenant = [] + if ("apprenant_id" in inscription_data.keys() and inscription_data['apprenant_id']): + tab_apprenant.append(ObjectId(str(inscription_data['apprenant_id']))) + + # Recuperation des données du partenaire associé à l'utilisateur connecté + local_status, local_retval = mycommon.Get_Connected_User_Partner_Data_From_RecID(my_partner['recid']) + if (local_status is False): + return local_status, local_retval + + company_data = local_retval + + + # Recuperations des info de la session de formation + tab_session = [] + session_data = MYSY_GV.dbname['session_formation'].find_one( + {'_id': ObjectId(str(inscription_data['session_id'])), 'valide': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + tab_session.append(session_data['_id']) + + + # Recuperation du titre de la formation + class_data = MYSY_GV.dbname['myclass'].find_one( + {'internal_url': str(session_data['class_internal_url']), 'valide': '1', + 'partner_owner_recid': str(my_partner['recid']), 'locked': '0'}) + + tab_class = [] + tab_class.append(class_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'] = tab_participant + new_diction['list_session_id'] = tab_session + new_diction['list_class_id'] = tab_class + new_diction['list_client_id'] = [] + new_diction['list_apprenant_id'] = tab_apprenant + + 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 + + + #print(" ### convention_dictionnary_data = ", convention_dictionnary_data) + + body = { + "params": convention_dictionnary_data, + } + + json_formatted_str = json.dumps(body, indent=2) + + #print(json_formatted_str) + + ## Creation du PDF + + contenu_doc_Template = jinja2.Template(str(courrier_template_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 = "Convent_" + 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() + + if os.path.exists(outputFilename): + #print(" ### ok os.path.exists(outputFilename) "+str(outputFilename)) + return True, send_file(outputFilename, as_attachment=True) + + return False, " Impossible de générer le fichier PDF (2) " + + + 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 générer le fichier PDF (2) " + + + + + + +""" +Pour les statgiaires rattaché à un client, edite les convetions pour le client +donc avec la liste des participants +""" +def Download_Convention_Stagiaire_PDF_By_Partner_client(diction): + try: + field_list_obligatoire = ['token', 'courrier_template_id', 'partner_client_id', '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, " 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 + + + + # Verifier que la session est valide + is_session_id_valide = MYSY_GV.dbname['session_formation'].count_documents({'_id':ObjectId(str(diction['session_id'])), + 'valide':'1', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_session_id_valide != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de la session est invalide ") + return False, " L'identifiant de la session est invalide " + + + + # Verifier que ce client a bien des inscriptions valide pour cette session + is_valide_inscription_pr_client = MYSY_GV.dbname['inscription'].count_documents({'client_rattachement_id':str(diction['partner_client_id']), + 'session_id':str(diction['session_id']), + 'partner_owner_recid':str(my_partner['recid']), + 'status':'1'}) + + + if (is_valide_inscription_pr_client <= 0): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " Aucune inscription valide pour ce client pour cette session ") + return False, " Aucune inscription valide pour ce client pour cette session " + + partner_client_id_data = MYSY_GV.dbname['partner_client'].find_one({'_id':ObjectId(str(diction['partner_client_id'])), + 'valide':'1', + 'locked':'0', + 'partner_owner_recid':str(my_partner['recid'])}) + + tab_client = [] + tab_client.append(partner_client_id_data['_id']) + + # Verifier que le 'courrier_template_id' est valide. il doit etre de type PDF + is_courrier_template_id_valide = MYSY_GV.dbname['courrier_template'].count_documents( + {'_id': ObjectId(str(diction['courrier_template_id'])), + 'valide': '1', + 'locked': '0', + 'type_doc': 'pdf', + 'partner_owner_recid': str(my_partner['recid'])} + ) + + if (is_courrier_template_id_valide != 1): + 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 données du partenaire associé à l'utilisateur connecté + local_status, local_retval = mycommon.Get_Connected_User_Partner_Data_From_RecID(my_partner['recid']) + if (local_status is False): + return local_status, local_retval + + company_data = local_retval + + # Recupération des données du modèle de document + courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one( + {'_id': ObjectId(str(diction['courrier_template_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])} + ) + + # Recuperations des info de la session de formation + session_data = MYSY_GV.dbname['session_formation'].find_one( + {'_id': ObjectId(str(diction['session_id'])), 'valide': '1', + 'partner_owner_recid': str(my_partner['recid'])}, {'_id':1, 'class_internal_url':1}) + + + tab_session = [session_data['_id']] + print(" tab_session = ", tab_session) + + tab_apprenant = [] + tab_participant = [] + # Recupérer la liste des participant pour une eventuelle à afficher pour les conventions d'entreprise + for participant in MYSY_GV.dbname['inscription'].find({'session_id':str(session_data['_id']), 'status':'1', + 'partner_owner_recid':str(my_partner['recid'])}, + {'_id':1}): + tab_participant.append(participant['_id']) + + """ + update du 30/01/2024 + si le participant à un apprenant_id, alors on recupere la valeur de l'apprenant id. On doit travailler sur cette dernier. + En general, avant d'envoyer une convocation ou convention, l'inscription est validée et donc le dossier apprenant existe. + Du coup si tout se passe bien, dans cette fonction, on travaillera tjrs avec l'apprenant_id + """ + + if ("apprenant_id" in participant.keys() and participant['apprenant_id']): + tab_apprenant.append(ObjectId(str(participant['apprenant_id']))) + + + print(" tab_participant = ", tab_participant) + + + # Recuperation du titre de la formation + tab_class = [] + for class_data in MYSY_GV.dbname['myclass'].find( + {'internal_url': str(session_data['class_internal_url']), 'valide': '1', + 'partner_owner_recid': str(my_partner['recid']), 'locked': '0'}, {'_id':1}): + tab_class.append(class_data['_id']) + + + print(" tab_class = ", tab_class) + + + new_diction = {} + new_diction['token'] = diction['token'] + new_diction['list_stagiaire_id'] = tab_participant + new_diction['list_session_id'] = tab_session + new_diction['list_class_id'] = tab_class + new_diction['list_client_id'] = tab_client + new_diction['list_apprenant_id'] = tab_apprenant + + + 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 + + # Creation du dictionnaire d'information à utiliser pour la creation du doc + + #print(" ### convention_dictionnary_data = ") + + #json_object = ast.literal_eval(convention_dictionnary_data) + + json_formatted_str = json.dumps(convention_dictionnary_data, indent=2) + + print(json_formatted_str) + + + body = { + "params": convention_dictionnary_data, + } + + ## Creation du PDF + + contenu_doc_Template = jinja2.Template(str(courrier_template_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 = "Convent_" + 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() + + if os.path.exists(outputFilename): + #print(" ### ok os.path.exists(outputFilename) "+str(outputFilename)) + return True, send_file(outputFilename, as_attachment=True) + + return False, " Impossible de générer le fichier PDF (2) " + + + 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 générer le fichier PDF (2) " + + + + + + +""" +Envoie par email pour les stagiaires rattachés à un client + +important : +si le champ 'email_test' est rempli, alors il s'agit d'un email de test. +donc on n'envoie pas l'email à l'adresss de prod ou contact du client +""" +def Sent_Convention_Stagiaire_By_Email_By_Partner_client(tab_files_name_full_path, Folder, diction): + try: + + field_list_obligatoire = ['token', 'courrier_template_id', 'email_test', 'email_production', 'partner_client_id', 'session_id', + 'request_digital_signature'] + + 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 + + + """ + 20/03/2024 : Creation du E-Document à signer + On verifier si le partenaire dispose de l'option "signature_digital" dans la collection base_partner_setup + + ET SI DEPUIS LE FRONT, L'UTILISATEUR DECIDE DE L'UTILISER + """ + is_partner_digital_signature = "" + if( "request_digital_signature" in diction.keys() and diction['request_digital_signature'] == "1"): + + is_signature_digital_count = MYSY_GV.dbname['base_partner_setup'].count_documents( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'signature_digital', + 'valide': '1', + 'locked': '0', + 'config_value': '1'}) + if (is_signature_digital_count == 1): + is_partner_digital_signature = "1" + + # Verifier que la session est valide + is_session_id_valide = MYSY_GV.dbname['session_formation'].count_documents( + {'_id': ObjectId(str(diction['session_id'])), + 'valide': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_session_id_valide != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de la session est invalide ") + return False, " L'identifiant de la session est invalide " + + # Verifier que ce client a bien des inscriptions valide pour cette session + is_valide_inscription_pr_client = MYSY_GV.dbname['inscription'].count_documents( + {'client_rattachement_id': str(diction['partner_client_id']), + 'session_id': str(diction['session_id']), + 'partner_owner_recid': str(my_partner['recid']), + 'status': '1'}) + + if (is_valide_inscription_pr_client <= 0): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " Aucune inscription valide pour ce client pour cette session ") + return False, " Aucune inscription valide pour ce client pour cette session " + + partner_client_id_data = MYSY_GV.dbname['partner_client'].find_one( + {'_id': ObjectId(str(diction['partner_client_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])}) + + + # Traitement de l'eventuel fichier joint + tab_files_to_attache_to_mail = [] + + tab_list_file_for_queu_mail_and_internal_mail = [] + + for file_name_full_path in tab_files_name_full_path: + """status, saved_file = mycommon.Upload_Save_PDF_IMG_File(file, Folder) + if (status is False): + mycommon.myprint("Impossible de récupérer correctement le fichier à importer") + return False, "Impossible de récupérer correctement le fichier à importer" + """ + + file_to_attache_to_mail = MIMEBase('application', "octet-stream") + file_to_attache_to_mail.set_payload(open(file_name_full_path, "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(file_name_full_path))) + + new_node = {"attached_file": file_to_attache_to_mail} + tab_files_to_attache_to_mail.append(new_node) + tab_list_file_for_queu_mail_and_internal_mail.append(file_name_full_path) + + # Verification de la validité des adresses email_recu + """ + Important : : Si l'email de test est repli, alors on considere que c'est un test, on ne prend pas en compte l'email de email_production. + Ceci pour forcer les utilisateur à ne remplir que l'email de prod s'il veulent l'envoyer en prod. + + Si l'adresse email_prodution = "defaul", cela veut dire qu'on envoie la convention à : + - l'adresse email du stagiaire et ses tuteurs (si les tuteurs on cochés la case 'inclu com' + + """ + + send_in_production = 0 + + tab_emails_destinataire = [] + if ("email_test" in diction.keys() and diction['email_test']): + 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: + tab_email_prod = "default" + + + else: + 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. " + + + #print(" ## laaa : tab_emails_destinataire lalala = ", tab_emails_destinataire) + + # Verifier que le 'courrier_template_id' est valide + # Ici le template doit etre un email + is_courrier_template_id_valide = MYSY_GV.dbname['courrier_template'].count_documents( + {'_id': ObjectId(str(diction['courrier_template_id'])), + 'valide': '1', + 'type_doc': 'email', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])} + ) + + if (is_courrier_template_id_valide != 1): + 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 " + + # Recupération des données du modèle de document + courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one( + {'_id': ObjectId(str(diction['courrier_template_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(my_partner['recid'])} + ) + + # 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(courrier_template_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 + + # print(" ### file stocké = ", local_retval) + + # 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) + tab_list_file_for_queu_mail_and_internal_mail.append(saved_file) + + # Recuperation des données du stagiaire + inscription_data = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid']), + 'client_rattachement_id':str(diction['partner_client_id'])}) + tab_apprenant = [] + tab_participant = [] + for val in inscription_data: + tab_participant.append(val['_id']) + + """ + update du 30/01/2024 + si le participant à un apprenant_id, alors on recupere la valeur de l'apprenant id. On doit travailler sur cette dernier. + En general, avant d'envoyer une convocation ou convention, l'inscription est validée et donc le dossier apprenant existe. + Du coup si tout se passe bien, dans cette fonction, on travaillera tjrs avec l'apprenant_id + """ + + if ("apprenant_id" in val.keys() and val['apprenant_id']): + tab_apprenant.append(ObjectId(str(val['apprenant_id']))) + + + #print(" ### tab_participant = ", tab_participant) + + # Recuperations des info de la session de formation + session_data = MYSY_GV.dbname['session_formation'].find_one({'_id': ObjectId(str(diction['session_id']))}) + + tab_session = [] + tab_session.append(session_data['_id']) + + + # Recuperation du titre de la formation + class_data = MYSY_GV.dbname['myclass'].find_one({'internal_url': str(session_data['class_internal_url']), + 'valide': '1', + 'partner_owner_recid': str(my_partner['recid']), + 'locked': '0'}) + + tab_class = [] + if class_data: + tab_class.append(class_data['_id']) + + # Recuperer les données du client + client_data = MYSY_GV.dbname['partner_client'].find_one({'_id':ObjectId(str(diction['partner_client_id'])), + 'valide':'1', + 'locked':'0', + 'partner_owner_recid': str(my_partner['recid']), + }) + + + tab_client = [] + tab_client.append(client_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'] = tab_participant + new_diction['list_session_id'] = tab_session + new_diction['list_class_id'] = tab_class + new_diction['list_client_id'] = tab_client + + 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 + + if ("company_data" in local_retval.keys() and "societe_nom" in local_retval['company_data'].keys()): + company_name = local_retval['company_data']['societe_nom'] + + ## Creation du PDF + + body = { + "params": convention_dictionnary_data, + } + + outputFilename = "" + orig_file_name = "" + # --- + sujetHtml = "" + # Verifier s'il s'agit d'un document à envoyer avec une version de pièce jointe. + if ("joint_pdf" in courrier_template_data.keys() and str(courrier_template_data['joint_pdf']) == "1"): + # Il s'agit bien d'un envoie avec 'contenu_doc' en pièce jointe PDF + """ + 1 - Creation du PDF + """ + + # Traitement du sujet du mail + sujet_mail_Template = jinja2.Template(str(courrier_template_data['sujet'])) + sujetHtml = sujet_mail_Template.render(params=body["params"]) + + + contenu_doc_Template = jinja2.Template(str(courrier_template_data['contenu_doc'])) + sourceHtml = contenu_doc_Template.render(params=body["params"]) + + """ + new_model_courrier_with_code_tag = str(sourceHtml) + "

Signature manuscrite
 


" \ + "

 

" + """ + new_model_courrier_with_code_tag = "
" \ + "
" \ + " " \ + "
" + \ + str(sourceHtml)+ "
" \ + " Signature manuscrite

" \ + "
" + + todays_date = str(date.today().strftime("%d/%m/%Y")) + ts = datetime.now().timestamp() + ts = str(ts).replace(".", "").replace(",", "")[-5:] + + orig_file_name = "Convent_" + 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) + tab_list_file_for_queu_mail_and_internal_mail.append(outputFilename) + + ## Creation du mail au format email + + corps_mail_Template = jinja2.Template(str(courrier_template_data['corps_mail'])) + + sourceHtml = corps_mail_Template.render(params=body["params"]) + + html_mime = MIMEText(sourceHtml, 'html') + + # Creation de l'email à enoyer + msg = MIMEMultipart("alternative") + + """ + 20/03/2024 : la convention pdf a été créée. + Si le partenaire a l'option de signature digitale, alors on créé le e-document + """ + if( is_partner_digital_signature == "1"): + new_e_document_diction = {} + new_e_document_diction['token'] = diction['token'] + new_e_document_diction['file_name'] = outputFilename + toaddrs = ",".join(tab_emails_destinataire) + new_e_document_diction['email_destinataire'] = str(toaddrs) + new_e_document_diction['source_document'] = new_model_courrier_with_code_tag + + new_e_document_diction['related_collection'] = "partner_client" + new_e_document_diction['related_collection_id'] = str(client_data['_id']) + + new_e_document_diction['class_id'] = str(session_data['class_id']) + new_e_document_diction['session_d'] = str(session_data['_id']) + + todays_date = str(date.today().strftime("%d/%m/%Y")) + ts = datetime.now().timestamp() + ts = str(ts).replace(".", "").replace(",", "")[-2:] + + cononic_name = "Convent_" + str(todays_date) + "_" + str(ts) + new_e_document_diction['file_cononical_name'] = cononic_name + new_e_document_diction['type'] = "convention" + + print(" ### 011 new_e_document_diction = ", new_e_document_diction) + local_status_e_doc, local_retval_e_doc = E_Sign_Document.Create_E_Document(new_e_document_diction) + + if(local_status_e_doc is False ): + return local_status_e_doc, local_retval_e_doc + + """ + Apres la creation du document electronique, on envoie la demande de validation + Important : on envoie le mail à chaque destinataire + """ + + for email in tab_emails_destinataire : + #print(" ### traitement du mail : ", email) + new_send_e_document_diction = {} + new_send_e_document_diction['token'] = diction['token'] + new_send_e_document_diction['e_doc_id'] = str(local_retval_e_doc) + new_send_e_document_diction['user_email'] = str(email) + + + local_status_send_e_doc, local_send_retval_e_doc = E_Sign_Document.Sent_E_Document_Signature_Request(new_send_e_document_diction) + if( local_status_send_e_doc is False ): + return local_status_send_e_doc, local_send_retval_e_doc + + + else: + # Il s'agit d'une simple email + + # Traitement du sujet du mail + sujet_mail_Template = jinja2.Template(str(courrier_template_data['sujet'])) + sujetHtml = sujet_mail_Template.render(params=body["params"]) + + ## Creation du mail au format email + contenu_doc_Template = jinja2.Template(str(courrier_template_data['contenu_doc'])) + sourceHtml = contenu_doc_Template.render(params=body["params"]) + + html_mime = MIMEText(sourceHtml, 'html') + + # Creation de l'email à enoyer + msg = MIMEMultipart("alternative") + + # --- + + """ + ## Creation du PDF + + contenu_doc_Template = jinja2.Template(str(courrier_template_data['contenu_doc'])) + + sourceHtml = contenu_doc_Template.render(params=body["params"]) + + html_mime = MIMEText(sourceHtml, 'html') + + # Creation de l'email à enoyer + msg = MIMEMultipart("alternative") + """ + """ + Recuperation des parametre SMTP du partner si le client a decidé d'utiliser son propre smpt + """ + partner_own_smtp_value = "0" + partner_own_smtp = MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'partner_smtp', + 'valide': '1', + 'locked': '0'}) + + if (partner_own_smtp and "config_value" in partner_own_smtp.keys()): + partner_own_smtp_value = partner_own_smtp['config_value'] + + if (str(partner_own_smtp_value) == "1"): + partner_SMTP_COUNT_password = str(MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'smtp_user_pwd', + 'valide': '1', + 'locked': '0'}, {'config_value': 1})['config_value']) + + partner_SMTP_COUNT_smtpsrv = str(MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'smtp_server', + 'valide': '1', + 'locked': '0'}, {'config_value': 1})['config_value']) + + partner_SMTP_COUNT_user = str(MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'smtp_user', + 'valide': '1', + 'locked': '0'}, {'config_value': 1})['config_value']) + + partner_SMTP_COUNT_From_User = str(MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'smtp_count_from_name', + 'valide': '1', + 'locked': '0'}, {'config_value': 1})['config_value']) + + partner_SMTP_COUNT_port = str(MYSY_GV.dbname['base_partner_setup'].find_one( + {'partner_owner_recid': str(my_partner['recid']), + 'config_name': 'smtp_count_port', + 'valide': '1', + 'locked': '0'}, {'config_value': 1})['config_value']) + + if (str(partner_own_smtp_value) == "1"): + smtpserver = smtplib.SMTP(partner_SMTP_COUNT_smtpsrv, partner_SMTP_COUNT_port) + else: + smtpserver = smtplib.SMTP(MYSY_GV.O365_SMTP_COUNT_smtpsrv, MYSY_GV.O365_SMTP_COUNT_port) + + if (str(partner_own_smtp_value) == "1"): + msg.attach(html_mime) + msg['From'] = partner_SMTP_COUNT_From_User + msg['Bcc'] = 'contact@mysy-training.com' + msg['Subject'] = courrier_template_data['sujet'] + # msg['to'] = "billardman01@hotmail.com" + toaddrs = ",".join(tab_emails_destinataire) + msg['to'] = str(toaddrs) + + # Attacher l'eventuelle pièces jointes + for myfile in tab_files_to_attache_to_mail: + msg.attach(myfile['attached_file']) + + smtpserver.ehlo() + smtpserver.starttls() + smtpserver.login(partner_SMTP_COUNT_user, partner_SMTP_COUNT_password) + + else: + msg.attach(html_mime) + #msg['From'] = MYSY_GV.O365_SMTP_COUNT_From_User + if (company_name): + msg['From'] = str(company_name) + " <" + str(MYSY_GV.O365_SMTP_COUNT_From_User) + ">" + else: + msg['From'] = str(MYSY_GV.O365_SMTP_COUNT_From_User) + msg['Bcc'] = 'contact@mysy-training.com' + msg['Subject'] = courrier_template_data['sujet'] + # msg['to'] = "billardman01@hotmail.com" + toaddrs = ",".join(tab_emails_destinataire) + msg['to'] = str(toaddrs) + + for myfile in tab_files_to_attache_to_mail: + msg.attach(myfile['attached_file']) + + 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)) + + + """ + 25/01/2024 : pour loger une action dans la collection ==> courrier_template_tracking_history + """ + # Recuperation des données du stagiaire + inscription_data = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid']), + 'client_rattachement_id': str( + diction['partner_client_id'])}) + + for inscription in inscription_data: + + local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne( + my_partner, "CONVENTION_STAGIAIRE_ENTREPRISE", str(diction['session_id']), 'inscription', + str(inscription['_id']), str(courrier_template_data['_id'])) + + #print(" local_status = ", local_status) + + + """ + # Ajout de l'evenement dans l'historique + """ + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + # L'action n'est loggué pour les envois reels (en prod) + if (send_in_production == 1): + + history_event_dict = {} + history_event_dict['token'] = diction['token'] + history_event_dict['related_collection'] = "partner_client" + history_event_dict['related_collection_recid'] = str(diction['partner_client_id']) + history_event_dict['action_date'] = str(now) + history_event_dict['action_description'] = "Convention envoyée par email à la liste : " + str( + tab_emails_destinataire) + 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)) + + # Recuperation des données du stagiaire + inscription_data = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid']), + 'client_rattachement_id': str( + diction['partner_client_id'])}) + + for inscription in inscription_data: + # Pour la collection inscription + history_event_dict = {} + history_event_dict['token'] = diction['token'] + history_event_dict['related_collection'] = "inscription" + history_event_dict['related_collection_recid'] = str(inscription['_id']) + history_event_dict['action_date'] = str(now) + + local_session_info = "" + if ("code_session" in session_data.keys()): + local_session_info = local_session_info + ", " + session_data["code_session"] + else: + local_session_info = "Id Session : " + str(session_data['_id']) + + + history_event_dict['action_description'] = "Convention envoyée par email à la liste : " + str( + tab_emails_destinataire)+" pour la session "+str(local_session_info) + 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)) + + # Pour la collection session_formation + history_event_dict = {} + history_event_dict['token'] = diction['token'] + history_event_dict['related_collection'] = "session_formation" + history_event_dict['related_collection_recid'] = str(session_data['_id']) + history_event_dict['action_date'] = str(now) + + local_inscrit_info = "Id Inscrit : " + str(inscription['_id']) + if ("email" in inscription.keys()): + local_inscrit_info = local_inscrit_info + ", " + inscription["email"] + + if ("nom" in inscription.keys()): + local_inscrit_info = local_inscrit_info + ", " + inscription["nom"] + + if ("prenom" in inscription.keys()): + local_inscrit_info = local_inscrit_info + ", " + inscription["prenom"] + + history_event_dict['action_description'] = "Convention envoyée par email à la liste : " + str( + tab_emails_destinataire) + " pour l'inscrit " + str(local_inscrit_info) + + 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)) + + + """ + On va aller stocker le document + """ + # Recuperation des données du stagiaire + inscription_data = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid']), + 'client_rattachement_id': str( + diction['partner_client_id'])}) + + if (orig_file_name and outputFilename): + new_file = {} + new_file['token'] = diction['token'] + type_document = "Convention" + + new_file['file_business_object'] = str(orig_file_name) + + new_file['file_name'] = str(orig_file_name) + new_file['status'] = "1" + new_file['type_document'] = str(type_document) + + new_file['object_owner_collection'] = "partner_client" + new_file['object_owner_id'] = str(diction['partner_client_id']) + + new_file['file_name_to_store'] = outputFilename + + tab_key_word = "convention," + str(class_data['external_code']) + "," + str( + session_data['code_session']) + new_file['tab_key_word'] = tab_key_word + + tab_related_collection = [] + if (class_data): + node_class = {} + node_class['related_collection'] = 'myclass' + node_class['related_collection_id'] = str(class_data['_id']) + tab_related_collection.append(node_class) + + if (session_data): + node_session = {} + node_session['related_collection'] = 'session_formation' + node_session['related_collection_id'] = str(session_data['_id']) + tab_related_collection.append(node_session) + + if (inscription_data): + node_inscrit = {} + node_inscrit['related_collection'] = 'inscription' + + tab_inscrit = [] + for local_inscrit in inscription_data: + tab_inscrit.append(str(local_inscrit['_id'])) + + node_inscrit['related_collection_id'] = tab_inscrit + tab_related_collection.append(node_inscrit) + + # print(" ### new_file new_file = ", new_file) + local_status, local_retval = attached_file_mgt.Internal_Usage_Store_User_Downloaded_File( + MYSY_GV.upload_folder, new_file, tab_related_collection) + + if (local_status is False): + print(" ## WARINNGGG Impossible de stocker le fichier de Convocation ") + + + """ + Gestion des emails via mail_queu et internal email + """ + # Recuperation des donnes smtp + (local_stpm_status, local_SMTP_COUNT_smtpsrv, local_own_smtp_value, local_SMTP_COUNT_password, + local_SMTP_COUNT_user, local_SMTP_COUNT_From_User, + local_SMTP_COUNT_port) = mycommon.Get_Partner_SMTP_Param(str(my_partner['recid'])) + + if (local_stpm_status is False): + return local_stpm_status, local_SMTP_COUNT_smtpsrv + + tab_email_bcc = [] + tab_email_bcc.append("contact@mysy-training.com") + + """ + IMPORTANT : Cette section sera utilisée une fois que le module de Queu de message est ok + """ + queue_mail_diction = {} + queue_mail_diction['token'] = diction['token'] + queue_mail_diction['tab_email_cc'] = [] + queue_mail_diction['tab_email_bcc'] = tab_email_bcc + if (sujetHtml): + queue_mail_diction['email_sujet'] = sujetHtml + else: + queue_mail_diction['email_sujet'] = '[MySy Training]: Convocation session de formation' + + queue_mail_diction['message'] = sourceHtml + + queue_mail_diction['smtp_account_password'] = local_SMTP_COUNT_password + queue_mail_diction['smtp_account_smtpsrv'] = local_SMTP_COUNT_smtpsrv + queue_mail_diction['smtp_account_user'] = local_SMTP_COUNT_user + queue_mail_diction['smtp_account_From_User'] = local_SMTP_COUNT_From_User + queue_mail_diction['smtp_account_port'] = local_SMTP_COUNT_port + + queue_mail_diction['tab_files_to_attache_to_mail'] = [] + for myfile in tab_list_file_for_queu_mail_and_internal_mail: + queue_mail_diction['tab_files_to_attache_to_mail'].append(myfile) + + for destinataire in tab_emails_destinataire: + queue_mail_diction['email_to'] = str(destinataire) + + queue_and_internal_mail_status, queue_and_internal_mail_status = email_mgt.Individual_Mail_Store_Queu_And_Internal_Mail( + queue_mail_diction) + if (queue_and_internal_mail_status is False): + print(" ## WARNING queue_mail_retval = ", queue_and_internal_mail_status) + + 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 la convention par email " + + +""" +Cette fonction retourne la liste des adresses emails de communication +d'un Inscrit. +(apprenant et tuteurs) selon les parametrage +""" +def Get_Stagiaire_Communication_List_Email_OLD(diction): + try: + field_list_obligatoire = ['token', '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 + + # Verifier que le stagiaire est bien inscrit. Le statut de l'inscription doit etre "1" + + is_inscription_valide = MYSY_GV.dbname['inscription'].count_documents( + {'_id': ObjectId(str(diction['inscription_id'])), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_inscription_valide != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de l'inscription est invalide ") + return False, " L'identifiant de l'inscription est invalide " + + is_inscription_data = MYSY_GV.dbname['inscription'].find_one( + {'_id': ObjectId(str(diction['inscription_id'])), + 'status': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + RetObject = [] + val_tmp = 0 + + if( "email" in is_inscription_data.keys()): + node = {"email":str(is_inscription_data['email'])} + RetObject.append(mycommon.JSONEncoder().encode(node)) + + + if( "tuteur1_include_com" in is_inscription_data.keys() and str(is_inscription_data['tuteur1_include_com']) == "1" + and "tuteur1_email" in is_inscription_data.keys() and is_inscription_data['tuteur1_email']): + node = {"email": str(is_inscription_data['tuteur1_email'])} + RetObject.append(mycommon.JSONEncoder().encode(node)) + + if ("tuteur2_include_com" in is_inscription_data.keys() and str( + is_inscription_data['tuteur2_include_com']) == "1" + and "tuteur2_email" in is_inscription_data.keys() and is_inscription_data['tuteur2_email']): + node = {"email": str(is_inscription_data['tuteur2_email'])} + RetObject.append(mycommon.JSONEncoder().encode(node)) + + 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 emails de communication " + + +""" +On recupere l'adresse email de communication du tuteur + +L'adresse email de l'inscrit +""" +def Get_Stagiaire_Communication_List_Email(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'inscription_id'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ") + return False, " Les informations fournies sont incorrectes", + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', '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, " 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 + + is_inscription_valide = MYSY_GV.dbname['inscription'].count_documents( + {'_id': ObjectId(str(diction['inscription_id'])), + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_inscription_valide != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de l'inscription est invalide ") + return False, " L'identifiant de l'inscription est invalide " + + RetObject = [] + val_tmp = 0 + + collected_email = [] + + is_inscription_data = MYSY_GV.dbname['inscription'].find_one( + {'_id': ObjectId(str(diction['inscription_id'])), + 'partner_owner_recid': str(my_partner['recid'])}) + + if ("email" in is_inscription_data.keys()): + + if( str(is_inscription_data['email']) not in collected_email): + collected_email.append(str(is_inscription_data['email'])) + node = {"email": str(is_inscription_data['email'])} + RetObject.append(mycommon.JSONEncoder().encode(node)) + + + """ + Recup du mail du tuteur + """ + tab_email = [] + for retval in MYSY_GV.dbname['ressource_humaine'].find({'partner_recid': my_partner['recid'], + 'tab_inscription_id.inscription_id':str(diction['inscription_id']), + 'tab_inscription_id.include_com': "1" } ): + + + for insc_tutore_data in retval["tab_inscription_id"]: + if(str(insc_tutore_data['inscription_id']) == str(diction['inscription_id']) and + str(insc_tutore_data['include_com']) == "1"): + + if (str(is_inscription_data['email']) not in collected_email): + collected_email.append(str(is_inscription_data['email'])) + node = {"email": str(retval['email'])} + RetObject.append(mycommon.JSONEncoder().encode(node)) + + print(" ### collected_email = ", collected_email) + print(" ### RetObject = ", RetObject) + + return True, RetObject + + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible les emails des tuteur de communication " + + + + + + +""" +Cette fonction permet de recuperer les contacts de communication d'un stagiaire. +(apprenant et tuteurs) + +""" +def Get_Statgiaire_Communication_Contact_OLD(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token','_id'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ") + return False, " Les informations fournies sont incorrectes", + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token','_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é du client + is_stagiaire_exist_valide = MYSY_GV.dbname['inscription'].count_documents({"_id":ObjectId(str(diction['_id'])), + 'partner_owner_recid':str(my_partner['recid'])}) + + if( is_stagiaire_exist_valide <= 0 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " - L'identifiant du stagiaire est invalide ") + return False, " L'identifiant du stagiaire est invalide ", + + # Verifier la validité du client + stagiaire_data = MYSY_GV.dbname['inscription'].find_one( + {"_id": ObjectId(str(diction['_id'])), + 'partner_owner_recid': str(my_partner['recid'])}) + + tab_stagiaire_contact_communication = [] + + # Ajout des datas du stagiaire + new_node = {} + if ("nom" in stagiaire_data.keys()): + new_node['nom'] = stagiaire_data['nom'] + else: + new_node['nom'] = "" + + if ("prenom" in stagiaire_data.keys()): + new_node['prenom'] = stagiaire_data['prenom'] + else: + new_node['prenom'] = "" + + if ("adresse" in stagiaire_data.keys()): + new_node['adresse'] = stagiaire_data['adresse'] + else: + new_node['adresse'] = "" + + if ("code_postal" in stagiaire_data.keys()): + new_node['code_postal'] = stagiaire_data['code_postal'] + else: + new_node['code_postal'] = "" + + if ("ville" in stagiaire_data.keys()): + new_node['ville'] = stagiaire_data['ville'] + else: + new_node['ville'] = "" + + if ("pays" in stagiaire_data.keys()): + new_node['pays'] = stagiaire_data['pays'] + else: + new_node['pays'] = "" + + if ("email" in stagiaire_data.keys()): + new_node['email'] = stagiaire_data['email'] + else: + new_node['email'] = "" + + if ("telephone" in stagiaire_data.keys()): + new_node['telephone'] = stagiaire_data['telephone'] + else: + new_node['telephone'] = "" + + tab_stagiaire_contact_communication.append(new_node) + + + # Ajout des datas du tuteur 1 s'il est autorisé + if( stagiaire_data and "tuteur1_include_com" in stagiaire_data.keys() and str(stagiaire_data['tuteur1_include_com']) == "1" ): + new_node = {} + if( "tuteur1_nom" in stagiaire_data.keys()): + new_node['nom'] = stagiaire_data['tuteur1_nom'] + else: + new_node['nom'] = "" + + if ("tuteur1_prenom" in stagiaire_data.keys()): + new_node['prenom'] = stagiaire_data['tuteur1_prenom'] + else: + new_node['prenom'] = "" + + if ("tuteur1_adresse" in stagiaire_data.keys()): + new_node['adresse'] = stagiaire_data['tuteur1_adresse'] + else: + new_node['adresse'] = "" + + if ("tuteur1_cp" in stagiaire_data.keys()): + new_node['code_postal'] = stagiaire_data['tuteur1_cp'] + else: + new_node['code_postal'] = "" + + if ("tuteur1_ville" in stagiaire_data.keys()): + new_node['ville'] = stagiaire_data['tuteur1_ville'] + else: + new_node['ville'] = "" + + if ("tuteur1_pays" in stagiaire_data.keys()): + new_node['pays'] = stagiaire_data['tuteur1_pays'] + else: + new_node['pays'] = "" + + if ("tuteur1_email" in stagiaire_data.keys()): + new_node['email'] = stagiaire_data['tuteur1_email'] + else: + new_node['email'] = "" + + if ("tuteur1_telephone" in stagiaire_data.keys()): + new_node['telephone'] = stagiaire_data['tuteur1_telephone'] + else: + new_node['telephone'] = "" + + + tab_stagiaire_contact_communication.append(new_node) + + + # Ajout des datas du tuteur 2 s'il est autorisé + if (stagiaire_data and "tuteur2_include_com" in stagiaire_data.keys() and str( stagiaire_data['tuteur2_include_com']) == "1"): + new_node = {} + if ("tuteur2_nom" in stagiaire_data.keys()): + new_node['nom'] = stagiaire_data['tuteur2_nom'] + else: + new_node['nom'] = "" + + if ("tuteur2_prenom" in stagiaire_data.keys()): + new_node['prenom'] = stagiaire_data['tuteur2_prenom'] + else: + new_node['prenom'] = "" + + if ("tuteur2_adresse" in stagiaire_data.keys()): + new_node['adresse'] = stagiaire_data['tuteur2_adresse'] + else: + new_node['adresse'] = "" + + if ("tuteur2_cp" in stagiaire_data.keys()): + new_node['code_postal'] = stagiaire_data['tuteur2_cp'] + else: + new_node['code_postal'] = "" + + if ("tuteur2_ville" in stagiaire_data.keys()): + new_node['ville'] = stagiaire_data['tuteur2_ville'] + else: + new_node['ville'] = "" + + if ("tuteur2_pays" in stagiaire_data.keys()): + new_node['pays'] = stagiaire_data['tuteur2_pays'] + else: + new_node['pays'] = "" + + if ("tuteur2_email" in stagiaire_data.keys()): + new_node['email'] = stagiaire_data['tuteur2_email'] + else: + new_node['email'] = "" + + if ("tuteur2_telephone" in stagiaire_data.keys()): + new_node['telephone'] = stagiaire_data['tuteur2_telephone'] + else: + new_node['telephone'] = "" + + tab_stagiaire_contact_communication.append(new_node) + + print(" ## RETTT OLDDDDD = ", tab_stagiaire_contact_communication) + return True, tab_stagiaire_contact_communication + + 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 contacts du stagiaire " + + +""" +Cette fonction pemet recuperer les tuteurs d'un inscrit +""" +def Get_Statgiaire_Communication_Contact(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', '_id'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ") + return False, " Les informations fournies sont incorrectes", + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', '_id'] + for val in field_list_obligatoire: + if val not in diction: + mycommon.myprint( + str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ") + return False, " Les informations fournies sont incorrectes", + + """ + Verification de l'identité et autorisation de l'entité qui + appelle cette API + """ + token = "" + if ("token" in diction.keys()): + if diction['token']: + token = diction['token'] + + + local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) + if (local_status is not True): + return local_status, my_partner + + RetObject = [] + val_tmp = 0 + + stagiaire_data = MYSY_GV.dbname['inscription'].find_one( + {'_id': ObjectId(str(diction['_id'])), + 'partner_owner_recid': str(my_partner['recid'])}) + + # Ajout des datas du stagiaire + new_node = {} + if ("nom" in stagiaire_data.keys()): + new_node['nom'] = stagiaire_data['nom'] + else: + new_node['nom'] = "" + + if ("prenom" in stagiaire_data.keys()): + new_node['prenom'] = stagiaire_data['prenom'] + else: + new_node['prenom'] = "" + + if ("adresse" in stagiaire_data.keys()): + new_node['adresse'] = stagiaire_data['adresse'] + else: + new_node['adresse'] = "" + + if ("code_postal" in stagiaire_data.keys()): + new_node['code_postal'] = stagiaire_data['code_postal'] + else: + new_node['code_postal'] = "" + + if ("ville" in stagiaire_data.keys()): + new_node['ville'] = stagiaire_data['ville'] + else: + new_node['ville'] = "" + + if ("pays" in stagiaire_data.keys()): + new_node['pays'] = stagiaire_data['pays'] + else: + new_node['pays'] = "" + + if ("email" in stagiaire_data.keys()): + new_node['email'] = stagiaire_data['email'] + else: + new_node['email'] = "" + + if ("telephone" in stagiaire_data.keys()): + new_node['telephone'] = stagiaire_data['telephone'] + else: + new_node['telephone'] = "" + + RetObject.append(new_node) + + + + + for retval in MYSY_GV.dbname['ressource_humaine'].find({'partner_recid': my_partner['recid'], + 'tab_inscription_id': { + '$elemMatch': { + 'inscription_id': str(diction['_id']), + 'include_com': "1", + + } + } + } + ): + + node_rh_tuteur = {} + node_rh_tuteur['_id'] = str(retval['_id']) + node_rh_tuteur['id'] = str(val_tmp) + val_tmp = val_tmp + 1 + + + if( "nom" in retval.keys()): + node_rh_tuteur['nom'] = str(retval['nom']) + else: + node_rh_tuteur['nom'] = "" + + if ("prenom" in retval.keys()): + node_rh_tuteur['prenom'] = str(retval['prenom']) + else: + node_rh_tuteur['prenom'] = "" + + if ("email" in retval.keys()): + node_rh_tuteur['email'] = str(retval['email']) + else: + node_rh_tuteur['email'] = "" + + if ("telephone" in retval.keys()): + node_rh_tuteur['telephone'] = str(retval['telephone']) + else: + node_rh_tuteur['telephone'] = "" + + if ("telephone_mobile" in retval.keys()): + node_rh_tuteur['telephone_mobile'] = str(retval['telephone_mobile']) + else: + node_rh_tuteur['telephone_mobile'] = "" + + if ("adr_adresse" in retval.keys()): + node_rh_tuteur['adr_adresse'] = str(retval['adr_adresse']) + else: + node_rh_tuteur['adr_adresse'] = "" + + if ("adr_code_postal" in retval.keys()): + node_rh_tuteur['adr_code_postal'] = str(retval['adr_code_postal']) + else: + node_rh_tuteur['adr_code_postal'] = "" + + + if ("adr_ville" in retval.keys()): + node_rh_tuteur['adr_ville'] = str(retval['adr_ville']) + else: + node_rh_tuteur['adr_ville'] = "" + + if ("adr_pays" in retval.keys()): + node_rh_tuteur['adr_pays'] = str(retval['adr_pays']) + else: + node_rh_tuteur['adr_pays'] = "" + + if ("civilite" in retval.keys()): + node_rh_tuteur['civilite'] = str(retval['civilite']) + else: + node_rh_tuteur['civilite'] = "" + + if ("date_naissance" in retval.keys()): + node_rh_tuteur['date_naissance'] = str(retval['date_naissance']) + else: + node_rh_tuteur['date_naissance'] = "" + + for insc_tutore_data in retval["tab_inscription_id"]: + if(str(insc_tutore_data['inscription_id']) == str(diction['_id']) ): + + if ("role" in insc_tutore_data.keys()): + node_rh_tuteur['role'] = str(insc_tutore_data['role']) + tuteur_label = "" + if( str(insc_tutore_data['role']) == "0"): + tuteur_label = "Parent" + elif( str(insc_tutore_data['role']) == "1"): + tuteur_label = "Tuteur légal" + elif (str(insc_tutore_data['role']) == "2"): + tuteur_label = "Tuteur scolaire" + elif (str(insc_tutore_data['role']) == "3"): + tuteur_label = "Autre" + + node_rh_tuteur['tuteur_role_label'] = tuteur_label + + else: + node_rh_tuteur['role'] = "" + node_rh_tuteur['tuteur_role_label'] = "" + + if ("include_com" in insc_tutore_data.keys() and str(insc_tutore_data['include_com']) in ['0', '1']): + node_rh_tuteur['include_com'] = str(insc_tutore_data['include_com']) + else: + node_rh_tuteur['include_com'] = "0" + + if ("comment" in insc_tutore_data.keys()): + node_rh_tuteur['comment'] = str(insc_tutore_data['comment']) + else: + node_rh_tuteur['comment'] = "" + + + + RetObject.append(node_rh_tuteur) + + + 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 tuteurs " + + + + + + +""" +Fonction permet d'exporter des inscription dans un fichier excel +""" +def Export_Inscription_To_Excel_From_from_List_Id(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'tab_id'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ") + return False, " Les informations fournies sont incorrectes", + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', 'tab_id'] + for val in field_list_obligatoire: + if val not in diction: + mycommon.myprint( + str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ") + return False, " Les informations fournies sont incorrectes", + + """ + Verification de l'identité et autorisation de l'entité qui + appelle cette API + """ + token = "" + if ("token" in diction.keys()): + if diction['token']: + token = diction['token'] + + local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) + if (local_status is not True): + return local_status, my_partner + + tab_id = [] + tab_id_tmp = str(diction['tab_id']).split(",") + for val in tab_id_tmp: + tab_id.append(ObjectId(str(val))) + + qery_match = {'_id': {'$in': tab_id}, 'partner_owner_recid': str(my_partner['recid']), 'valide': '1', + 'locked': '0'} + + + list_class_datas = MYSY_GV.dbname['myclass'].find({'_id': {'$in': tab_id}, + 'partner_owner_recid': str(my_partner['recid']), + }, {'_id': 0, + 'valide': 0, 'locked': 0}) + + pipe_qry = ([ + {'$match': qery_match}, + {'$project': {'_id': 0, 'valide': 0, 'locked': 0, }}, + {'$lookup': { + 'from': 'partner_client', + "let": {'client_rattachement_id': "$client_rattachement_id", + 'partner_owner_recid': '$partner_owner_recid'}, + 'pipeline': [ + {'$match': + {'$expr': + {'$and': + [ + + {'$eq': ["$_id", {'$convert': { + 'input': "$$client_rattachement_id", + 'to': "objectId", + 'onError': {'error': 'true'}, + 'onNull': {'isnull': 'true'} + }}]}, + + {'$eq': ["$valide", "1"]}, + {'$eq': ["$partner_recid", '$$partner_owner_recid']} + + ] + } + } + }, + {'$project': {'nom': 1, 'raison_sociale': 1, '_id': 0}}, + + ], + 'as': 'partner_client' + } + }, + {'$lookup': + { + 'from': 'session_formation', + 'let': {'session_id': "$session_id", 'class_internal_url': '$class_internal_url', + 'partner_owner_recid': '$partner_owner_recid'}, + + 'pipeline': [ + {'$match': + {'$expr': + {'$and': + [ + {'$eq': ['$_id', {'$toObjectId': '$$session_id'}]}, + {'$eq': ["$valide", "1"]}, + {'$eq': ["$partner_owner_recid", '$$partner_owner_recid']} + ] + } + } + }, + {'$project': { '_id': 0, 'testdate':0}}, + + ], + 'as': 'session_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'} + }}]}, + + ]}}}, + {'$project': {'_id': 0}}, + ], 'as': 'apprenant_collection'}} + + ]) + + print(" #### pipe_qry_inscrit = ", pipe_qry) + list_class_datas = MYSY_GV.dbname['inscription'].aggregate(pipe_qry) + + # print(" ### list_class_datas = ", str(list_class_datas)) + todays_date = str(datetime.today().strftime("%d/%m/%Y")) + ts = datetime.now().timestamp() + ts = str(ts).replace(".", "").replace(",", "")[-5:] + + orig_file_name = "Export_Inscription_csv_" + str(my_partner['recid']) + "_" + str(ts) + ".xlsx" + outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name) + + tab_exported_fields_header = ["apprenant_id", "nom", "email", "prenom", "civilite", "date_naissance", "telephone", "employeur", "client_rattachement_id", "adresse", "code_postal", "ville", "pays", "tuteur1_nom", "tuteur1_prenom", + "tuteur1_email", "tuteur1_telephone", "tuteur2_nom", "tuteur2_prenom", "tuteur2_email", "tuteur2_telephone", "opco", "comment", "tuteur1_adresse", "tuteur1_cp", "tuteur1_ville", "tuteur1_pays", + "tuteur1_include_com", "tuteur2_adresse", "tuteur2_cp", "tuteur2_ville", "tuteur2_pays", "tuteur2_include_com", + "client_nom", "client_raison_sociale", "Session_titre", "code_session", "session_date_debut", "session_date_fin", "memo"] + + + tab_exported_fields = ["nom", "email", "prenom", "civilite", "date_naissance", "telephone", "employeur", "client_rattachement_id", "adresse", "code_postal", "ville", "pays", "tuteur1_nom", "tuteur1_prenom", + "tuteur1_email", "tuteur1_telephone", "tuteur2_nom", "tuteur2_prenom", "tuteur2_email", "tuteur2_telephone", "opco", "comment", "tuteur1_adresse", "tuteur1_cp", "tuteur1_ville", "tuteur1_pays", + "tuteur1_include_com", "tuteur2_adresse", "tuteur2_cp", "tuteur2_ville", "tuteur2_pays", "tuteur2_include_com", "memo"] + + # Create a workbook and add a worksheet. + workbook = xlsxwriter.Workbook(outputFilename) + worksheet = workbook.add_worksheet() + + row = 0 + column = 0 + + for header_item in tab_exported_fields_header: + worksheet.write(row, column, header_item) + column += 1 + + for class_data in list_class_datas: + column = 0 + row = row + 1 + """ + for local_fiels in tab_exported_fields: + print(" #### class_data = ", class_data) + answers_record_JSON = ast.literal_eval(str(class_data)) + if (str(local_fiels) in answers_record_JSON.keys()): + local_status, local_retval = mycommon.IsFloat(str(answers_record_JSON[str(local_fiels)]).strip()) + if (local_status is True): + no_html = answers_record_JSON[str(local_fiels)] + else: + no_html = mycommon.cleanhtml(answers_record_JSON[str(local_fiels)]) + else: + no_html = "" + + worksheet.write(row, column, no_html) + column += 1 + + """ + if ("apprenant_id" in class_data.keys() and str(class_data['apprenant_id']).strip() != "" and + "apprenant_collection" in class_data.keys() and len(class_data['apprenant_collection']) > 0): + + worksheet.write(row, column, str(class_data['apprenant_id'])) + column += 1 + + #print(" ### str(class_data['apprenant_id']) = ", str(class_data['apprenant_id']) ) + answers_record_JSON = ast.literal_eval(str(class_data['apprenant_collection'][0])) + #print(" ### answers_record_JSON = ", answers_record_JSON) + for local_fiels in tab_exported_fields: + if (str(local_fiels) in answers_record_JSON.keys()): + local_status, local_retval = mycommon.IsFloat( + str(answers_record_JSON[str(local_fiels)]).strip()) + if (local_status is True): + no_html = answers_record_JSON[str(local_fiels)] + else: + no_html = mycommon.cleanhtml(answers_record_JSON[str(local_fiels)]) + else: + no_html = "" + + worksheet.write(row, column, no_html) + column += 1 + + + elif ( "apprenant_id" not in class_data.keys() or str(class_data['apprenant_id']).strip() == ""): + worksheet.write(row, column, "--") + column += 1 + + for local_fiels in tab_exported_fields: + #print(" #### class_data = ", class_data) + answers_record_JSON = ast.literal_eval(str(class_data)) + if (str(local_fiels) in answers_record_JSON.keys()): + local_status, local_retval = mycommon.IsFloat( + str(answers_record_JSON[str(local_fiels)]).strip()) + if (local_status is True): + no_html = answers_record_JSON[str(local_fiels)] + else: + no_html = mycommon.cleanhtml(answers_record_JSON[str(local_fiels)]) + else: + no_html = "" + + worksheet.write(row, column, no_html) + column += 1 + + + # Récuperation des données du client de rattachement + if ("partner_client" in class_data.keys() and len(class_data['partner_client']) > 0): + if ("nom" in class_data['partner_client'][0].keys()): + no_html_formateur_nom = class_data['partner_client'][0]['nom'] + worksheet.write(row, column, no_html_formateur_nom) + column += 1 + else: + worksheet.write(row, column, "") + column += 1 + + if ("raison_sociale" in class_data['partner_client'][0].keys()): + no_html_formateur_raison_sociale = class_data['partner_client'][0]['raison_sociale'] + worksheet.write(row, column, no_html_formateur_raison_sociale) + column += 1 + else: + worksheet.write(row, column, "") + column += 1 + else: + worksheet.write(row, column, "") + column += 1 + worksheet.write(row, column, "") + column += 1 + + # Récuperation des données de la session de formation + if ("session_collection" in class_data.keys() and len(class_data['session_collection']) > 0): + if ("titre" in class_data['session_collection'][0].keys()): + no_html_session_titre = class_data['session_collection'][0]['titre'] + worksheet.write(row, column, no_html_session_titre) + column += 1 + else: + worksheet.write(row, column, "") + column += 1 + + if ("code_session" in class_data['session_collection'][0].keys()): + no_html_code_session = class_data['session_collection'][0]['code_session'] + worksheet.write(row, column, no_html_code_session) + column += 1 + else: + worksheet.write(row, column, "") + column += 1 + + + + if ("date_debut" in class_data['session_collection'][0].keys()): + no_html_session_debut = class_data['session_collection'][0]['date_debut'] + worksheet.write(row, column, no_html_session_debut) + column += 1 + else: + worksheet.write(row, column, "") + column += 1 + + if ("date_fin" in class_data['session_collection'][0].keys()): + no_html_session_date_fin = class_data['session_collection'][0]['date_fin'] + worksheet.write(row, column, no_html_session_date_fin) + column += 1 + else: + worksheet.write(row, column, "") + column += 1 + + + workbook.close() + if os.path.exists(outputFilename): + # print(" ### ok os.path.exists(outputFilename) "+str(outputFilename)) + return True, send_file(outputFilename, as_attachment=True) + + return False, "Impossible de générer l'export csv des inscrits (2) " + + 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'exporter les inscrits " + + + +""" +Dans le cadre de la modification des inscription +cette fonction permet de recuperer les données des inscrit (on ne va pas chercher les données de l'apprenant). + +Ici l'inscription n'est pas validée encore +""" + + +def Get_Statgaire_List_Partner_with_filter_FOR_ONLY_INSCRIPTION_NO_TOKEN(diction): + try: + field_list = ['partner_owner_recid', 'class_internal_url', 'status', 'email', 'nom', + 'class_title', 'code_session', 'client_nom', 'client_rattachement_id', + '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'est pas autorisé, Creation partenaire annulée") + return False, "Toutes les informations fournies ne sont pas valables", "" + + + # Recuperation du recid du partner + mydata = {} + mytoken = "" + if ("token" in diction.keys()): + if diction['token']: + mytoken = diction['token'] + + + partner_recid = diction['partner_owner_recid'] + + """ + 07/03/2025 : + Etape 0 : Verifier si ceci concerne une demande stockée dans la collection 'client_preinsc_update_request'. + Si oui, alors cela conerne le cas un client doit créer lui la liste des tous preinscrit en respectant le nombre + max. + """ + max_presinscrit = "0" + is_client_preinsc_update_request = "" + is_client_preinsc_update_request_data = MYSY_GV.dbname['client_preinsc_update_request'].find_one({'partner_owner_recid': str(partner_recid), + 'valide': '1', + 'locked': '0', + 'client_id': str(diction['client_rattachement_id']), + 'session_id': str(diction['session_id'])}) + + if( is_client_preinsc_update_request_data and "max_presinscrit" in is_client_preinsc_update_request_data.keys()): + max_presinscrit = str(is_client_preinsc_update_request_data['max_presinscrit']) + is_client_preinsc_update_request = "1" + + + #print(" #### is_client_preinsc_update_request_data = ", is_client_preinsc_update_request_data) + """ + 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_id = {} + 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)}]} + + # 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_id = {'session_id': {'$in': list_session_id, }} + + filt_class_title = {} + if ("class_title" in diction.keys()): + filt_class_title = {'title': {'$regex': str(diction['class_title']), "$options": "i"}} + + filt_class_internal_url = {} + if ("class_internal_url" in diction.keys()): + filt_class_internal_url = { + 'class_internal_url': {'$regex': str(diction['class_internal_url']), "$options": "i"}} + + filt_email = {} + if ("email" in diction.keys()): + filt_email = {'email': {'$regex': str(diction['email']), "$options": "i"}} + + filt_nom = {} + if ("nom" in diction.keys()): + filt_nom = {'nom': {'$regex': str(diction['nom']), "$options": "i"}} + + filt_class_partner_recid = {'partner_owner_recid': str(partner_recid)} + + filt_client_rattachement_id = {} + if ("client_rattachement_id" in diction.keys()): + filt_client_rattachement_id = {'client_rattachement_id': str(diction['client_rattachement_id'])} + + filt_session_id = {} + if ("session_id" in diction.keys()): + filt_session_id = {'session_id': str(diction['session_id'])} + + # ----- + + filt_client_nom = {} + sub_filt_client_nom = {} + Lists_partner_client_id = [] + if ("client_nom" in diction.keys()): + sub_filt_client_nom = {'nom': {'$regex': str(diction['client_nom']), "$options": "i"}, + 'partner_owner_recid': str(partner_recid), 'valide': '1', 'locked': '0'} + # Recuperation des '_id' des clients dont le nom match en regexp + # print(" ### sub_filt_client_nom = ", sub_filt_client_nom) + for List_Client_Data in MYSY_GV.dbname['partner_client'].find(sub_filt_client_nom, {'_id': 1}): + Lists_partner_client_id.append(str(List_Client_Data['_id'])) + + filt_client_nom = {'client_rattachement_id': {'$in': Lists_partner_client_id, }} + # print(' ### filt_client_nom = ', filt_client_nom) + + # ---- + + query = [{'$match': {'$and': [filt_class_internal_url, filt_session_id, filt_email, filt_nom, filt_client_nom, + filt_client_rattachement_id, + filt_session_id, {'partner_owner_recid': str(partner_recid)}]}}, + {'$sort': {'_id': -1}}, + {'$lookup': + { + 'from': 'myclass', + 'localField': 'class_internal_url', + 'foreignField': 'internal_url', + 'pipeline': [{'$match': {'$and': [filt_class_title, filt_class_partner_recid]}}, + {'$project': {'title': 1, 'domaine': 1, + 'duration': 1, + 'duration_unit': 1}}], + 'as': 'myclass_collection' + } + }, + + ] + #print("#### Get_Statgaire_List_Partner_with_filter_ONLY_INSCRIPTION 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): + if ('myclass_collection' in retVal.keys() and len(retVal['myclass_collection']) > 0): + + 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'] + + ### + modefinancement_code = "" + modefinancement_id = "" + if ("modefinancement_id" in retVal.keys() and retVal['modefinancement_id']): + modefinancement_data = MYSY_GV.dbname['financement_mode'].find_one( + {'_id': ObjectId(str(retVal['modefinancement_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(retVal['partner_owner_recid'])}) + + if (modefinancement_data and "code" in modefinancement_data.keys()): + modefinancement_code = str(modefinancement_data['code']) + modefinancement_id = str(modefinancement_data['_id']) + + val['modefinancement_code'] = modefinancement_code + val['modefinancement_id'] = modefinancement_id + + type_apprenant_code = "" + type_apprenant_id = "" + if ("type_apprenant_id" in retVal.keys() and retVal['type_apprenant_id']): + type_apprenant_data = MYSY_GV.dbname['type_apprenant'].find_one( + {'_id': ObjectId(str(retVal['type_apprenant_id'])), + 'valide': '1', + 'locked': '0', + 'partner_owner_recid': str(retVal['partner_owner_recid'])}) + + if (type_apprenant_id and "code" in type_apprenant_id.keys()): + type_apprenant_code = str(type_apprenant_data['code']) + type_apprenant_id = str(type_apprenant_data['_id']) + + val['type_apprenant_code'] = type_apprenant_code + val['type_apprenant_id'] = type_apprenant_id + + ### + + if ("civilite" in retVal.keys()): + val['civilite'] = str(retVal['civilite']).lower() + else: + val['civilite'] = "" + + if (str(val['civilite']) not in MYSY_GV.CIVILITE or str(val['civilite']).strip() == ""): + val['civilite'] = "neutre" + + if ("modefinancement" in retVal.keys()): + val['modefinancement'] = retVal['modefinancement'] + else: + val['modefinancement'] = "" + + 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()): + 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['title'] = retVal['myclass_collection'][0]['title'] + if ("domaine" in retVal['myclass_collection'][0].keys()): + val['domaine'] = retVal['myclass_collection'][0]['domaine'] + else: + val['domaine'] = "" + + # 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) + + 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 + + # ---- + + 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 ("titre" in session_retval.keys()): + val['session_titre'] = str(session_retval['titre']) + else: + val['session_titre'] = "" + + + 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" + + RetObject.append(mycommon.JSONEncoder().encode(val)) + + + """ + S'il n'y aucune personne déjà inscrite et que 'is_client_preinsc_update_request' == 1 , j'initialise le table + 'RetObject' avec une seule ligne vide + + """ + if( cpt == 0 and is_client_preinsc_update_request == "1"): + + + session_data = MYSY_GV.dbname['session_formation'].find_one({'_id':ObjectId(str(diction['session_id'])), + 'partner_owner_recid': str(partner_recid)}) + + class_data = MYSY_GV.dbname['myclass'].find_one({'internal_url':str(session_data['class_internal_url'])}) + + val = {} + val['id'] = str(cpt) + cpt = cpt + 1 + val['_id'] = "new" + val['session_id'] = diction['session_id'] + val['class_internal_url'] = session_data['class_internal_url'] + val['nom'] = "new_nom" + val['partner_owner_recid'] = session_data['partner_owner_recid'] + val['prenom'] = "new_prenom" + val['email'] = "new_email@email.com" + val['civilite'] = "neutre" + val['modefinancement'] = "" + val['opco'] = "" + + val['employeur'] = "" + val['telephone'] = "" + val['date_naissance'] = "" + + val['adresse'] = "" + val['code_postal'] = "" + val['ville'] = "" + val['pays'] = "" + val['status'] = "0" + + val['title'] = class_data['title'] + if ("domaine" in class_data.keys()): + val['domaine'] = class_data['domaine'] + else: + val['domaine'] = "" + + + if ("code_session" in session_data.keys()): + val['code_session'] = str(session_data['code_session']) + else: + val['code_session'] = "" + + if ("titre" in session_data.keys()): + val['session_titre'] = str(session_data['titre']) + else: + val['session_titre'] = "" + + if ("date_debut" in session_data.keys()): + val['date_du'] = str(session_data['date_debut'])[0:10] + else: + val['date_du'] = "" + + if ("date_fin" in session_data.keys()): + val['date_au'] = str(session_data['date_fin'])[0:10] + else: + val['date_au'] = "" + + if ("code_postal" in session_data.keys()): + val['code_postal'] = session_data['code_postal'] + else: + val['code_postal'] = "" + + if ("prix_session" in session_data.keys()): + val['price'] = session_data['prix_session'] + else: + val['price'] = "" + + if ("presentiel" in session_data.keys()): + val['presentiel'] = session_data['presentiel'] + else: + val['presentiel'] = "0" + + if ("distantiel" in session_data.keys()): + val['distantiel'] = session_data['distantiel'] + else: + val['distantiel'] = "0" + + if ("session_ondemande" in session_data.keys()): + val['session_ondemande'] = session_data['session_ondemande'] + else: + val['session_ondemande'] = "0" + + RetObject.append(mycommon.JSONEncoder().encode(val)) + + + + + RetObject_global_data = [] + # Gestion du cas le client peut ajouter lui meme des preinscrits + val_global_data = {} + val_global_data['max_presinscrit'] = str(max_presinscrit) + val_global_data['is_client_preinsc_update_request'] = str(is_client_preinsc_update_request) + RetObject_global_data.append(mycommon.JSONEncoder().encode(val_global_data)) + + return True, RetObject, RetObject_global_data + + 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", "" + + + +""" +Cette fonction prend l'_id d'une session et retourne les inscriptions qui sont valide +avec un nombre de champs limité +""" +def Get_Accepted_Insription_From_Session_id_Reduice_Fields(diction): + try: + 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'est pas autorisé, Creation partenaire annulée") + return False, "de récupérer la liste des stagiaires . Toutes les informations fournies ne sont pas valables" + + """ + Verification de la liste 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, "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'] + + # Verifier la validité du token + retval = mycommon.check_partner_token_validity("", mytoken) + if retval is False: + return "Err_Connexion", " La session de connexion n'est pas valide" + + + partner_recid = mycommon.get_parnter_recid_from_token(mytoken) + if (partner_recid is False): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer la liste des stagiaires, ") + return False, "Impossible de récupérer la liste des stagiaires, Les informations d'identification sont incorrectes " + + class_internal_url = "" + if ("class_internal_url" in diction.keys()): + if diction['class_internal_url']: + class_internal_url = diction['class_internal_url'] + + session_id = "" + if ("session_id" in diction.keys()): + if diction['session_id']: + session_id = diction['session_id'] + + + + ## Recuperation de toutes les stagiaire rattaché à cette session + coll_session = MYSY_GV.dbname['inscription'] + myquery = {} + myquery['session_id'] = session_id + myquery['status'] = "1" + myquery['valide'] = "1" + + + RetObject = [] + val_tmp = 0 + + #print(" #### myquery 01111 = "+str(myquery)) + + + for retval in coll_session.find(myquery, + {'_id':1, 'email':1, + 'session_id':1, + 'apprenant_id':1, + 'nom': 1, + 'prenom': 1, + + }).sort([("_id", pymongo.DESCENDING), ]): + val_tmp = val_tmp + 1 + user = retval + user['id'] = str(val_tmp) + + apprenant_nom = str(retval['nom']) + apprenant_prenom = str(retval['prenom']) + apprenant_email = str(retval['email']) + + # Si il a un apprenant_id + # print(" ### retVal = ", retVal ) + if ("apprenant_id" in retval.keys()): + if (retval['apprenant_id'] and str(retval['apprenant_id']) != 'undefined'): + apprenant_retval = MYSY_GV.dbname['apprenant'].find_one( + {'_id': ObjectId(retval['apprenant_id']), + 'valide': '1', 'locked': '0'}) + + if (apprenant_retval is not None): + apprenant_nom = apprenant_retval['nom'] + apprenant_prenom = apprenant_retval['prenom'] + apprenant_email = apprenant_retval['email'] + + user['apprenant_nom'] = apprenant_nom + user['apprenant_prenom'] = apprenant_prenom + user['apprenant_email'] = apprenant_email + + user['groupe'] = "" + + + 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) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno)) + return False, "Impossible de récupérer la liste des stagiaires de la formation" + + + + + + + + +""" +Cette fonction prend l'_id d'une session et retourne les inscriptions qui sont validé et celle en cours de validation +(statut IN [0, 1, 2] +avec un nombre de champs limité +""" +def Get_Insription_From_Session_id_Reduice_Fields_With_Filter(diction): + try: + field_list = ['token', 'session_id', 'tab_statut_ids'] + 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, "de récupérer la liste des stagiaires . Toutes les informations fournies ne sont pas valables" + + """ + Verification de la liste 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, "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'] + + # Verifier la validité du token + retval = mycommon.check_partner_token_validity("", mytoken) + if retval is False: + return "Err_Connexion", " La session de connexion n'est pas valide" + + + partner_recid = mycommon.get_parnter_recid_from_token(mytoken) + if (partner_recid is False): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer la liste des stagiaires, ") + return False, "Impossible de récupérer la liste des stagiaires, Les informations d'identification sont incorrectes " + + class_internal_url = "" + if ("class_internal_url" in diction.keys()): + if diction['class_internal_url']: + class_internal_url = diction['class_internal_url'] + + session_id = "" + if ("session_id" in diction.keys()): + if diction['session_id']: + session_id = diction['session_id'] + + tab_statut_ids = "" + tab_statut_ids_filter = {} + if ("tab_statut_ids" in diction.keys()): + if diction['tab_statut_ids']: + tab_statut_ids = diction['tab_statut_ids'] + + tab_statut_ids_splited = [] + tab_statut_ids_splited_work = str(tab_statut_ids).split(",") + for tmp in tab_statut_ids_splited_work: + if( tmp ): + tab_statut_ids_splited.append(tmp) + + + ## Recuperation de toutes les stagiaire rattaché à cette session + + myquery = {} + myquery['session_id'] = session_id + myquery['status'] = "1" + myquery['valide'] = "1" + + if (len(tab_statut_ids_splited) > 0): + myquery['status'] = {'$in': tab_statut_ids_splited} + + + RetObject = [] + val_tmp = 0 + + #print(" #### myquery 01111 = "+str(myquery)) + + + for retval in MYSY_GV.dbname['inscription'].find(myquery, + {'_id':1, 'email':1, + 'session_id':1, + 'apprenant_id':1, + 'nom':1, + 'prenom':1, + + }).sort([("_id", pymongo.DESCENDING), ]): + val_tmp = val_tmp + 1 + user = retval + user['id'] = str(val_tmp) + + apprenant_nom = str(retval['nom']) + apprenant_prenom = str(retval['prenom']) + apprenant_email = str(retval['email']) + + # Si il a un apprenant_id + # print(" ### retVal = ", retVal ) + if ("apprenant_id" in retval.keys()): + if (retval['apprenant_id'] and str(retval['apprenant_id']) != 'undefined'): + apprenant_retval = MYSY_GV.dbname['apprenant'].find_one( + {'_id': ObjectId(retval['apprenant_id']), + 'valide': '1', 'locked': '0'}) + + if (apprenant_retval is not None): + apprenant_nom = apprenant_retval['nom'] + apprenant_prenom = apprenant_retval['prenom'] + apprenant_email = apprenant_retval['email'] + + user['apprenant_nom'] = apprenant_nom + user['apprenant_prenom'] = apprenant_prenom + user['apprenant_email'] = apprenant_email + + user['groupe'] = "" + + + 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) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno)) + return False, "Impossible de récupérer la liste des stagiaires de la formation" + + + +""" +Cette fonction prend l'_id d'une session et retourne les inscriptions qui sont validé et celle en cours de validation +(statut IN [0, 1, 2] +avec un nombre de champs limité ET SURTOUT pour qui il reste des paiement à faire +(inscription.invoiced != 1) +""" +def Get_Insription_From_Session_id_Reduice_Fields_With_Filter_With_To_Paie(diction): + try: + field_list = ['token', 'session_id', 'tab_statut_ids', 'client_rattachement_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é, Creation partenaire annulée") + return False, "de récupérer la liste des stagiaires . Toutes les informations fournies ne sont pas valables" + + """ + Verification de la liste 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, "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'] + + # Verifier la validité du token + retval = mycommon.check_partner_token_validity("", mytoken) + if retval is False: + return "Err_Connexion", " La session de connexion n'est pas valide" + + + partner_recid = mycommon.get_parnter_recid_from_token(mytoken) + if (partner_recid is False): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer la liste des stagiaires, ") + return False, "Impossible de récupérer la liste des stagiaires, Les informations d'identification sont incorrectes " + + class_internal_url = "" + if ("class_internal_url" in diction.keys()): + if diction['class_internal_url']: + class_internal_url = diction['class_internal_url'] + + session_id = "" + if ("session_id" in diction.keys()): + if diction['session_id']: + session_id = diction['session_id'] + + tab_statut_ids = "" + tab_statut_ids_filter = {} + if ("tab_statut_ids" in diction.keys()): + if diction['tab_statut_ids']: + tab_statut_ids = diction['tab_statut_ids'] + + tab_statut_ids_splited = [] + tab_statut_ids_splited_work = str(tab_statut_ids).split(",") + for tmp in tab_statut_ids_splited_work: + if( tmp ): + tab_statut_ids_splited.append(tmp) + + filt_client_rattachement_id = {} + if ("client_rattachement_id" in diction.keys()): + filt_client_rattachement_id = {'client_rattachement_id': str(diction['client_rattachement_id'])} + + ## Recuperation de toutes les stagiaire rattaché à cette session + + myquery = {} + myquery['session_id'] = session_id + myquery['status'] = "1" + myquery['valide'] = "1" + myquery['invoiced'] = {'$ne':'1'} + if ("client_rattachement_id" in diction.keys()): + myquery['client_rattachement_id'] = str(diction['client_rattachement_id']) + + print(" ## myquerymyquery = ", myquery) + + RetObject = [] + val_tmp = 0 + + #print(" #### myquery 01111 = "+str(myquery)) + + + for retval in MYSY_GV.dbname['inscription'].find(myquery, + {'_id':1, 'email':1, + 'session_id':1, + 'apprenant_id':1, + 'nom':1, + 'prenom':1, + + }).sort([("_id", pymongo.DESCENDING), ]): + val_tmp = val_tmp + 1 + user = retval + user['id'] = str(val_tmp) + + apprenant_nom = str(retval['nom']) + apprenant_prenom = str(retval['prenom']) + apprenant_email = str(retval['email']) + + # Si il a un apprenant_id + # print(" ### retVal = ", retVal ) + if ("apprenant_id" in retval.keys()): + if (retval['apprenant_id'] and str(retval['apprenant_id']) != 'undefined'): + apprenant_retval = MYSY_GV.dbname['apprenant'].find_one( + {'_id': ObjectId(retval['apprenant_id']), + 'valide': '1', 'locked': '0'}) + + if (apprenant_retval is not None): + apprenant_nom = apprenant_retval['nom'] + apprenant_prenom = apprenant_retval['prenom'] + apprenant_email = apprenant_retval['email'] + + user['apprenant_nom'] = apprenant_nom + user['apprenant_prenom'] = apprenant_prenom + user['apprenant_email'] = apprenant_email + + user['groupe'] = "" + + 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) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno)) + return False, "Impossible de récupérer la liste des stagiaires de la formation" + + +""" +Cette fonction retourne le nombre de lignes completement +facturée sur une session / promo +""" +def Get_Nb_Insription_From_Session_Full_Invoiced(diction): + try: + 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'est pas autorisé, Creation partenaire annulée") + return False, "de récupérer la liste des stagiaires . Toutes les informations fournies ne sont pas valables" + + """ + Verification de la liste 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, "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'] + + # Verifier la validité du token + retval = mycommon.check_partner_token_validity("", mytoken) + if retval is False: + return "Err_Connexion", " La session de connexion n'est pas valide" + + + partner_recid = mycommon.get_parnter_recid_from_token(mytoken) + if (partner_recid is False): + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer la liste des stagiaires, ") + return False, "Impossible de récupérer la liste des stagiaires, Les informations d'identification sont incorrectes " + + + + ## Recuperation de toutes les stagiaire rattaché à cette session + + myquery = {} + myquery['session_id'] = str(diction['session_id']) + myquery['status'] = "1" + myquery['valide'] = "1" + myquery['invoiced'] = '1' + + + RetObject = [] + val_tmp = 0 + + #print(" #### myquery 01111 = "+str(myquery)) + + nb_fully_invoiced_inscrit = MYSY_GV.dbname['inscription'].count_documents(myquery) + + + myquery_nb_inscrit = {} + myquery_nb_inscrit['session_id'] = str(diction['session_id']) + myquery_nb_inscrit['status'] = "1" + myquery_nb_inscrit['valide'] = "1" + + RetObject = [] + val_tmp = 0 + + # print(" #### myquery 01111 = "+str(myquery)) + + session_nb_inscrit = MYSY_GV.dbname['inscription'].count_documents(myquery_nb_inscrit) + user = {"nb_fully_invoiced_inscrit":str(nb_fully_invoiced_inscrit), "session_nb_inscrit": str(session_nb_inscrit)} + + 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) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno)) + return False, "Impossible de récupérer le nombre d'inscription facturé " + + + +""" +Cette fonction retourne la liste des UE aux quelles un apprenant est inscrit +""" +def Get_Inscrit_List_EU(diction): + try: + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', '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, " Les informations fournies ne sont pas correctes" + + 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 + + formation_initiale = "0" + if ("formation_initiale" in my_partner.keys()): + formation_initiale = my_partner['formation_initiale'] + + if (formation_initiale != "1"): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Il ne s'agit pas d'un formation initiale ") + return True, [] + + """ + Verifier que l'inscription est valide + """ + is_valide_inscription_count = MYSY_GV.dbname['inscription'].count_documents( + {'_id': ObjectId(diction['inscription_id']), + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1'}) + + if (is_valide_inscription_count != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de l'inscrit est invalide ") + return False, " L'identifiant de l'inscrit est invalide " + + + RetObject = [] + val_tmp = 0 + + + qery_match = {'inscription_id': str(diction['inscription_id']), 'partner_owner_recid': str(my_partner['recid']), 'valide': '1', + 'locked': '0'} + + pipe_qry = ([ + {'$match': qery_match}, + {'$lookup': { + 'from': 'unite_enseignement', + "let": {'class_eu_id': "$class_eu_id", + 'partner_owner_recid': '$partner_owner_recid'}, + 'pipeline': [ + {'$match': + {'$expr': + {'$and': + [ + + {'$eq': ["$_id", {'$convert': { + 'input': "$$class_eu_id", + 'to': "objectId", + 'onError': {'error': 'true'}, + 'onNull': {'isnull': 'true'} + }}]}, + + {'$eq': ["$valide", "1"]}, + {'$eq': ["$partner_owner_recid", '$$partner_owner_recid']} + + ] + } + } + }, + ], + 'as': 'collection_unite_enseignement' + } + }, + { + '$unwind': '$collection_unite_enseignement' + } + + ]) + + for val in MYSY_GV.dbname['inscription_liste_ue'].aggregate(pipe_qry): + user = {} + main_field = ['_id', 'class_eu_id', 'class_id', 'inscription_id', ] + second_field = ['_id', 'code', 'titre'] + + for tmp in main_field : + if( str(tmp) in val.keys() ): + user[str(tmp)] = val[str(tmp)] + + for tmp in second_field: + if (str(tmp) in val['collection_unite_enseignement'].keys()): + user["ue_"+str(tmp)] = val['collection_unite_enseignement'][str(tmp)] + + RetObject.append(mycommon.JSONEncoder().encode(user)) + + return True, RetObject + + except Exception as e: + 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 les UE associées à l'inscription" + + +""" +Cette fonction permet de recuperer la liste des types d'evaluation pour un inscrit +exemple : Pour l'UE xxxx, il est inscrit pour les 'PROJETS' seulement +""" +def Get_Inscrit_List_EU_Type_Evaluation(diction): + try: + """ + Verification de la liste des champs obligatoires + """ + field_list_obligatoire = ['token', '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, " Les informations fournies ne sont pas correctes" + + 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 + + formation_initiale = "0" + if ("formation_initiale" in my_partner.keys()): + formation_initiale = my_partner['formation_initiale'] + + if (formation_initiale != "1"): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Il ne s'agit pas d'un formation initiale ") + return True, [] + + """ + Verifier que l'inscription est valide + """ + is_valide_inscription_count = MYSY_GV.dbname['inscription'].count_documents( + {'_id': ObjectId(diction['inscription_id']), + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1'}) + + if (is_valide_inscription_count != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de l'inscrit est invalide ") + return False, " L'identifiant de l'inscrit est invalide " + + + RetObject = [] + val_tmp = 0 + + + qery_match = {'inscription_id': str(diction['inscription_id']), 'partner_owner_recid': str(my_partner['recid']), 'valide': '1', + 'locked': '0'} + + pipe_qry = ([ + {'$match': qery_match}, + {'$lookup': { + 'from': 'type_evaluation', + "let": {'type_evaluation_id': '$type_evaluation_id', + 'partner_owner_recid': '$partner_owner_recid'}, + 'pipeline': [ + {'$match': + {'$expr': + {'$and': + [ + + {'$eq': ["$_id", {'$convert': { + 'input': "$$type_evaluation_id", + 'to': "objectId", + 'onError': {'error': 'true'}, + 'onNull': {'isnull': 'true'} + }}]}, + + {'$eq': ["$valide", "1"]}, + {'$eq': ["$partner_owner_recid", '$$partner_owner_recid']} + + ] + } + } + }, + ], + 'as': 'collection_type_evaluation' + } + }, + { + '$unwind': '$collection_type_evaluation' + } + + ]) + + print(" ### Get_Inscrit_List_EU_Type_Evaluation pipe_qry = ", pipe_qry) + + for val in MYSY_GV.dbname['inscription_liste_ue_type_evalution'].aggregate(pipe_qry): + user = {} + main_field = ['_id', 'class_eu_id', 'class_id', 'inscription_id', 'type_evaluation_id'] + second_field = ['_id', 'code', 'nom'] + + for tmp in main_field : + if( str(tmp) in val.keys() ): + user[str(tmp)] = val[str(tmp)] + + class_eu_code = "" + if( "class_eu_id" in val.keys() ): + class_eu_id_data = MYSY_GV.dbname['unite_enseignement'].find_one({'_id':ObjectId(str(val['class_eu_id'])), + 'valide':'1', + 'locked':'0', + 'partner_owner_recid':str(my_partner['recid'])}) + + if( class_eu_id_data and 'code' in class_eu_id_data.keys() ): + class_eu_code = class_eu_id_data['code'] + + user['class_eu_code'] = class_eu_code + + for tmp in second_field: + if (str(tmp) in val['collection_type_evaluation'].keys()): + user["type_eval_"+str(tmp)] = val['collection_type_evaluation'][str(tmp)] + + RetObject.append(mycommon.JSONEncoder().encode(user)) + + + print(" ### Get_Inscrit_List_EU_Type_Evaluation RetObject = ", RetObject) + return True, RetObject + + except Exception as e: + 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 évaluation par UE " + + +""" +Cette fonction retourne la liste des inscrits à +une UE et un type d'evaluation donnée. + +sont données en option : +- Liste UE, +- Liste Type evaluation + +use case : +Avec cette fonction on peut recuperer la liste des personnes inscrite à +- ue : ue1, ue2, etc +- type eval : TP, Projet, etc + +""" + +def Get_List_Inscrit_OF_UE_And_Type_Evaluation_with_filter(diction): + try: + field_list = ['token', 'class_id', 'tab_session_id', 'tab_ue_id', 'tab_type_eval_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é, 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', 'class_id', 'tab_session_id', 'tab_ue_id', 'tab_type_eval_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, "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 + + # Verification de la validité de toutes les session dans tab_session_id + tab_session_id = str(diction['tab_session_id']).split(',') + for session_id in tab_session_id: + if (MYSY_GV.dbname['session_formation'].count_documents({'_id': ObjectId(str(session_id)), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " La session_id :" + str(session_id) + " n'est pas valide ") + return False, " La session_id :" + str(session_id) + " n'est pas valide " + + # Verification de la validité de la formation + if (MYSY_GV.dbname['myclass'].count_documents({'_id': ObjectId(str(diction['class_id'])), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " La formation :" + str(diction['class_id']) + " n'est pas valide ") + return False, " La formation :" + str(diction['class_id']) + " n'est pas valide " + + + # Verification de la validité de toutes les ue_id dans tab_ue_id + tab_ue_id = str(diction['tab_ue_id']).split(',') + for ue_id in tab_ue_id: + if (MYSY_GV.dbname['unite_enseignement'].count_documents({'_id': ObjectId(str(ue_id)), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'UE :" + str(session_id) + " n'est pas valide ") + return False, " L'UE :" + str(session_id) + " n'est pas valide " + + # Verification de la validité de toutes les type_eval_id dans tab_type_eval_id + tab_type_eval_id = str(diction['tab_type_eval_id']).split(',') + for type_eval_id in tab_type_eval_id: + if (MYSY_GV.dbname['unite_enseignement'].count_documents({'_id': ObjectId(str(type_eval_id)), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le type d'évaluation :" + str(type_eval_id) + " n'est pas valide ") + return False, " Le type d'évaluation :" + str(type_eval_id) + " n'est pas valide " + + + + RetObject = [] + cpt = 0 + + qry = {'partner_owner_recid':str(my_partner['recid']), + 'valide':'1', + 'locked':'0', + 'class_id': {'$in': str(diction['class_id']) }, + 'class_eu_id': {'$in': tab_ue_id}, + 'type_evaluation_id': {'$in': tab_type_eval_id}, + } + + + + for retval in MYSY_GV.dbname['inscription_liste_ue_type_evalution'].find( qry ).sort([("_id", pymongo.DESCENDING), ]): + user = {} + # Recuperation des données de l'inscrit et de l'apprenant + if( "inscription_id" in retval.keys() ): + inscrit_data = MYSY_GV.dbname['inscription'].find_one({'partner_owner_recid':str(my_partner['recid']), + 'valide':'1', + 'locked':'0', + '_id':ObjectId(str(retval['inscription_id']))}) + + + local_new_dict = {} + local_new_dict['token'] = diction['token'] + local_new_dict['inscrit_id'] = retval['inscription_id'] + + local_inscrit_data_status, local_inscrit_data_retval = mycommon.Get_Inscrit_And_Apprenant_Data(local_new_dict) + if( local_inscrit_data_status is False ): + return local_inscrit_data_status, local_inscrit_data_retval + + if( "inscrit_data" in local_inscrit_data_retval.keys() ): + user['inscrit_data'] = local_inscrit_data_retval['inscrit_data'] + + if ("apprenant_data" in local_inscrit_data_retval.keys()): + user['apprenant_data'] = local_inscrit_data_retval['apprenant_data'] + + if ("class_eu_id" in retval.keys()): + class_eu_data = MYSY_GV.dbname['unite_enseignement'].find_one({'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked': '0', + '_id': ObjectId(str(retval['class_eu_id']))}) + + if( class_eu_data and 'id' in class_eu_data.keys() ): + user['class_eu_data'] = class_eu_data + else: + user['class_eu_data'] = {} + + if ("type_evaluation_id" in retval.keys()): + type_evaluation_data = MYSY_GV.dbname['type_evaluation'].find_one({'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked': '0', + '_id': ObjectId(str(retval['type_evaluation_id']))}) + + if( type_evaluation_data and 'id' in type_evaluation_data.keys() ): + user['type_evaluation_data'] = type_evaluation_data + else: + user['type_evaluation_data'] = {} + + + 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 inscrits" + + + +""" +22/06/2024 - nouvelle methode pour envoyer les demandes +d'emargement de manière securisée, à l'image de la gestion des QR code +""" +""" +Cette fonction prends une liste d'emargement et une session +pui créer un QR pour l'emargement +""" + +def Create_Emargement_Send_Email_From_Inscription(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'session_id', 'tab_emargement_ids'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé") + return False, " Les informations fournies sont incorrectes" + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', 'session_id', 'tab_emargement_ids'] + + 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 que la session est valide + is_session_id_valide = MYSY_GV.dbname['session_formation'].count_documents( + {'_id': ObjectId(str(diction['session_id'])), + 'valide': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_session_id_valide != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de la session est invalide ") + return False, " L'identifiant de la session est invalide " + + """ + Recuperation du modèle de courrier pour la demande d'emargement + """ + local_diction = {} + local_diction['ref_interne'] = "EMARGEMENT_FORMATION" + local_diction['type_doc'] = "email" + local_diction['partner_owner_recid'] = str(my_partner['recid']) + + courrier_data_status, courrier_data_retval = mycommon.Get_Courrier_Template_Include_Default_Data(local_diction) + if (courrier_data_status is False): + return courrier_data_status, courrier_data_retval + + + # Recuperation des donnes smtp + 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( + my_partner['recid']) + + if (local_stpm_status is False): + return local_stpm_status, partner_SMTP_COUNT_smtpsrv + + """print(" ### local_stpm_status = ", local_stpm_status) + print(" ### partner_SMTP_COUNT_smtpsrv = ", partner_SMTP_COUNT_smtpsrv) + print(" ### partner_SMTP_COUNT_password = ", partner_SMTP_COUNT_password) + print(" ### partner_SMTP_COUNT_user = ", partner_SMTP_COUNT_user) + print(" ### partner_SMTP_COUNT_From_User = ", partner_SMTP_COUNT_From_User) + print(" ### partner_SMTP_COUNT_port = ", partner_SMTP_COUNT_port)""" + + + # Verifier que les inscriptions sont valides + my_emargement_ids = "" + if ("tab_emargement_ids" in diction.keys()): + if diction['tab_emargement_ids']: + my_emargement_ids = diction['tab_emargement_ids'] + + + tab_my_emargement_ids = str(my_emargement_ids).split(",") + if(len(tab_my_emargement_ids) <= 0 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Aucune Séquence ") + return False, " Aucun Séquence " + + + for my_emargement_id in tab_my_emargement_ids: + + # Verifier qui la formation n'a pas deja été evaluée + tmp_count = MYSY_GV.dbname['emargement'].count_documents({'session_id': str(diction['session_id']), + '_id': ObjectId(str(my_emargement_id)), + 'partner_owner_recid': str(my_partner['recid']), + }) + + + + if (tmp_count != 1): + mycommon.myprint(str(inspect.stack()[0][3]) + " L'identifiant de l'émargement "+str(my_emargement_id)+" est invalide ") + return False, " L'identifiant de l'émargement "+str(my_emargement_id)+" est invalide " + + # Creation d'une clé securisé + my_safe_token = mycommon.create_user_recid() + + """ + Mettre à jour l'inscription avec la clé + """ + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + tab_my_emargement_ids = str(my_emargement_ids).split(",") + for my_emargement_id in tab_my_emargement_ids: + ret_val2 = MYSY_GV.dbname['emargement'].find_one_and_update( + {'session_id': str(diction['session_id']), + '_id': ObjectId(str(my_emargement_id)), + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked': '0' + }, + {"$set": {'emargement_qr_safe_token':str(my_safe_token), 'statut':'1', + 'date_envoi':str(now), 'update_by':str(my_partner['_id']), + 'date_dernier_relance_auto':str(datetime.now().strftime("%d/%m/%Y")), + 'mode_envoi':'email'}}, + return_document=ReturnDocument.AFTER, + upsert=False, + ) + + url_for_qr_code = str(MYSY_GV.CLIENT_URL_BASE)+"qr_emargement/"+str(diction['session_id'])+"/"+str(my_partner['recid'])+"/"+str(my_safe_token)+"/" + ts = datetime.now().timestamp() + ts = str(ts).replace(".", "").replace(",", "")[-3:] + qr_code_img_file = str(MYSY_GV.TEMPORARY_DIRECTORY_V2) + "qr_code_" + str(ts) + ".png" + + qrcode = segno.make_qr(str(url_for_qr_code)) + qrcode.save( + qr_code_img_file, + scale=5, + dark="darkblue", + ) + + """ + 25/01/2024 : Apres l'envoi de la demande + d'emargement, on log une action dans la collection ==> courrier_template_tracking_history + """ + tab_my_emargement_ids = str(my_emargement_ids).split(",") + for my_emargement_id in tab_my_emargement_ids: + + + val_emarge = MYSY_GV.dbname['emargement'].find_one({'_id':ObjectId(str(my_emargement_id)), 'valide':'1', 'locked':'0', + 'partner_owner_recid':my_partner['recid']}) + + + local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne( + my_partner, "EMARGEMENT_FORMATION", str(val_emarge['session_id']), "inscription", str(val_emarge['inscription_id']), + "") + + """ + Debut de la procedure d'envoie de l'email + """ + convention_dictionnary_data = {} + new_diction = {} + new_diction['token'] = diction['token'] + new_diction['list_stagiaire_id'] = [] + new_diction['list_session_id'] = [ObjectId(str(diction['session_id']))] + new_diction['list_class_id'] = [] + new_diction['list_client_id'] = [] + + local_status, local_retval = mycommon.Get_Dictionnary_data_For_Template(new_diction) + + if (local_status is False): + return local_status, local_retval + + if ("company_data" in local_retval.keys() and "societe_nom" in local_retval['company_data'].keys()): + company_name = local_retval['company_data']['societe_nom'] + + emargement_dictionnary_data = local_retval + emargement_dictionnary_data['mysyurl'] = url_for_qr_code + + smtpserver = None + + if (str(partner_own_smtp_value) == "1"): + 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) + + else: + + smtpserver = smtplib.SMTP(MYSY_GV.O365_SMTP_COUNT_smtpsrv, MYSY_GV.O365_SMTP_COUNT_port) + smtpserver.ehlo() + smtpserver.starttls() + smtpserver.login(MYSY_GV.O365_SMTP_COUNT_user, MYSY_GV.O365_SMTP_COUNT_password) + + """ + on envoi qu'un seul mail d'emargement par personnes. + 1 - On va aller recuperer la liste des personnes concernée (inscription_id) + 2 - Apres avoir envoyer les email, on va venir mettre à jour la table emargement id) + """ + + cpt_email_envoye = 0 + + tab_my_emargement_ids = str(my_emargement_ids).split(",") + + """ + Des qu'on envoie un emailn on met l'inscription_id dans la collection 'tab_inscription_id_emargement_send' + Avant d'envoyer un email à un inscrit on verifie qu'il n'est pa dans la table : tab_inscription_id_emargement_send + + """ + tab_inscription_id_emargement_send = [] + + # Recuperation des donnes smtp + (local_stpm_status, local_SMTP_COUNT_smtpsrv, local_own_smtp_value, local_SMTP_COUNT_password, + local_SMTP_COUNT_user, local_SMTP_COUNT_From_User, + local_SMTP_COUNT_port) = mycommon.Get_Partner_SMTP_Param(str(my_partner['recid'])) + + if (local_stpm_status is False): + return local_stpm_status, local_SMTP_COUNT_smtpsrv + + for my_emargement_id in tab_my_emargement_ids: + + my_emargement_data = MYSY_GV.dbname['emargement'].find_one({'_id':ObjectId(str(my_emargement_id)), + 'partner_owner_recid':str(my_partner['recid']), + 'valide':'1', + 'locked':'0'}) + + + if( str(my_emargement_data['inscription_id']) not in tab_inscription_id_emargement_send ): + + tab_inscription_id_emargement_send.append(str(my_emargement_data['inscription_id'])) + cpt_email_envoye = cpt_email_envoye + 1 + + # Recuperation des données de l'inscrit + local_inscrit_data = mycommon.Get_Inscrit_And_Apprenant_Data({'token':str(diction['token']), 'inscrit_id':str(my_emargement_data['inscription_id'])}) + emargement_dictionnary_data['emargement_inscrit_data'] = local_inscrit_data + + # Recuperation des données de la formation + myclass_data = MYSY_GV.dbname['myclass'].find_one( {'internal_url':str(my_emargement_data['class_internal_url']), 'partner_owner_recid':my_partner['recid']}, {'title':1}) + emargement_dictionnary_data['emargement_class_data'] = myclass_data + + emargement_dictionnary_data['emargement_data'] = my_emargement_data + + + body = { + "params": emargement_dictionnary_data, + } + + #print( " ### emargement_dictionnary_data ===== ", emargement_dictionnary_data) + + # Traitement du sujet du mail + sujet_mail_Template = jinja2.Template(str(courrier_data_retval['sujet'])) + sujetHtml = sujet_mail_Template.render(params=body["params"]) + + # Traitement du corps du mail + contenu_doc_Template = jinja2.Template(str(courrier_data_retval['contenu_doc'])) + sourceHtml = contenu_doc_Template.render(params=body["params"]) + html_mime = MIMEText(sourceHtml, 'html') + + # Creation de l'email à enoyer + msg = MIMEMultipart("alternative") + + + if (str(partner_own_smtp_value) == "1"): + msg.attach(html_mime) + msg['From'] = partner_SMTP_COUNT_From_User + msg['Bcc'] = 'contact@mysy-training.com' + msg['Subject'] = sujetHtml + msg['to'] = str(my_emargement_data['email']) + val = smtpserver.send_message(msg) + print(" Email demande emargement envoyé " + str(val)) + + else: + msg.attach(html_mime) + #msg['From'] = MYSY_GV.O365_SMTP_COUNT_From_User + if (company_name): + msg['From'] = str(company_name) + " <" + str(MYSY_GV.O365_SMTP_COUNT_From_User) + ">" + else: + msg['From'] = str(MYSY_GV.O365_SMTP_COUNT_From_User) + msg['Bcc'] = 'contact@mysy-training.com' + msg['Subject'] = sujetHtml + msg['to'] = str(my_emargement_data['email']) + val = smtpserver.send_message(msg) + print(" Email demande emargement envoyé " + str(val)) + + """ + Gestion des emails via mail_queu et internal email + """ + + tab_email_bcc = [] + tab_email_bcc.append("contact@mysy-training.com") + + """ + IMPORTANT : Cette section sera utilisée une fois que le module de Queu de message est ok + """ + queue_mail_diction = {} + queue_mail_diction['token'] = diction['token'] + queue_mail_diction['tab_email_cc'] = [] + queue_mail_diction['tab_email_bcc'] = tab_email_bcc + if (sujetHtml): + queue_mail_diction['email_sujet'] = sujetHtml + else: + queue_mail_diction['email_sujet'] = "[MySy Training]: Demande d'émargement" + + queue_mail_diction['message'] = sourceHtml + + queue_mail_diction['smtp_account_password'] = local_SMTP_COUNT_password + queue_mail_diction['smtp_account_smtpsrv'] = local_SMTP_COUNT_smtpsrv + queue_mail_diction['smtp_account_user'] = local_SMTP_COUNT_user + queue_mail_diction['smtp_account_From_User'] = local_SMTP_COUNT_From_User + queue_mail_diction['smtp_account_port'] = local_SMTP_COUNT_port + + queue_mail_diction['tab_files_to_attache_to_mail'] = [] + + queue_mail_diction['email_to'] = str(my_emargement_data['email']) + + queue_and_internal_mail_status, queue_and_internal_mail_status = email_mgt.Individual_Mail_Store_Queu_And_Internal_Mail( + queue_mail_diction) + if (queue_and_internal_mail_status is False): + print(" ## WARNING queue_mail_retval = ", queue_and_internal_mail_status) + + smtpserver.close() + + print(" NB_email envoyé = ", cpt_email_envoye) + return True, "Les demandes d'émargement ont été correctement envoyées " + + + 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 les demandes d'émargement " + + + +""" +Cette fonction prends une liste d'inscription et une session +pui créer un QR pour l'emargement +""" +def Create_Emargement_QR_Code_From_Inscription(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'session_id', 'tab_emargement_ids'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé") + return False, " Les informations fournies sont incorrectes" + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', 'session_id', 'tab_emargement_ids'] + + 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 que la session est valide + is_session_id_valide = MYSY_GV.dbname['session_formation'].count_documents( + {'_id': ObjectId(str(diction['session_id'])), + 'valide': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_session_id_valide != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de la session est invalide ") + return False, " L'identifiant de la session est invalide " + + + # Verifier que les inscriptions sont valides + my_emargement_ids = "" + if ("tab_emargement_ids" in diction.keys()): + if diction['tab_emargement_ids']: + my_emargement_ids = diction['tab_emargement_ids'] + + + + tab_my_emargement_ids = str(my_emargement_ids).split(",") + if(len(tab_my_emargement_ids) <= 0 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Aucune Séquence ") + return False, " Aucun Séquence " + + + for my_emargement_id in tab_my_emargement_ids: + + # Verifier qui la formation n'a pas deja été evaluée + tmp_count = MYSY_GV.dbname['emargement'].count_documents({'session_id': str(diction['session_id']), + '_id': ObjectId(str(my_emargement_id)), + 'partner_owner_recid': str(my_partner['recid']), + 'valide':'1', + 'locked':'0' }) + + if (tmp_count != 1): + mycommon.myprint(str(inspect.stack()[0][3]) + " L'identifiant de l'émargement "+str(my_emargement_id)+" est invalide ") + return False, " L'identifiant de l'émargement "+str(my_emargement_id)+" est invalide " + + # Creation d'une clé securisé + my_safe_token = mycommon.create_user_recid() + + """ + Mettre à jour l'inscription avec la , et on met le statut à "1" pour dire qu'on a demarré le process + """ + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + tab_my_emargement_ids = str(my_emargement_ids).split(",") + for my_emargement_id in tab_my_emargement_ids: + + ret_val2 = MYSY_GV.dbname['emargement'].find_one_and_update( + {'session_id': str(diction['session_id']), + '_id': ObjectId(str(my_emargement_id)), + 'partner_owner_recid': str(my_partner['recid']), + 'valide':'1','locked':'0'}, + {"$set": {'emargement_qr_safe_token':str(my_safe_token), 'statut':'1', + 'date_envoi':str(now), 'update_by':str(my_partner['_id']), + 'date_dernier_relance_auto': str(datetime.now().strftime("%d/%m/%Y")), + 'mode_envoi': 'qr' + }}, + return_document=ReturnDocument.AFTER, + upsert=False, + ) + + url_for_qr_code = str(MYSY_GV.CLIENT_URL_BASE)+"qr_emargement/"+str(diction['session_id'])+"/"+str(my_partner['recid'])+"/"+str(my_safe_token)+"/" + ts = datetime.now().timestamp() + ts = str(ts).replace(".", "").replace(",", "")[-3:] + qr_code_img_file = str(MYSY_GV.TEMPORARY_DIRECTORY_V2) + "qr_code_" + str(ts) + ".png" + + qrcode = segno.make_qr(str(url_for_qr_code)) + qrcode.save( + qr_code_img_file, + scale=5, + dark="darkblue", + ) + + print(" ### Create_Emargement_QR_Code_From_Inscription url_for_qr_code = ", url_for_qr_code) + + """ + 25/01/2024 : Apres l'envoi de la demande + d'emargement, on log une action dans la collection ==> courrier_template_tracking_history + """ + tab_my_emargement_ids = str(my_emargement_ids).split(",") + for my_emargement_id in tab_my_emargement_ids: + val_emarge = MYSY_GV.dbname['emargement'].find_one({'_id':ObjectId(str(my_emargement_id)), 'valide':'1', 'locked':'0', + 'partner_owner_recid':my_partner['recid']}) + + local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne( + my_partner, "EMARGEMENT_FORMATION", str(val_emarge['session_id']), "inscription", str(val_emarge['inscription_id']), + "") + + if os.path.exists(qr_code_img_file): + return True, send_file(qr_code_img_file, as_attachment=True) + + return False, " Impossible de générer les QR Code (1) " + + + 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 QR code " + + +""" +06/04/2026 +Cette fonction permet d'initialiser le tableau d'émargement +et de créer le QR Code dans la foulée. + +Ainsi au lieu de faire le process en 2 étapes, il sera fait en 1 étapes. +La fonction prends en argument la sequence_id, la durée de vie du QR code +(xxx minute apres la fin de la sequence. Si xxx < 0, alors pas de durée +ou durée = toujours) +""" +def Init_Emargement_And_Create_QR_Code_From_Inscription(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'session_id', 'tab_sequence_ids', 'qr_time_valide' ] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé") + return False, " Les informations fournies sont incorrectes" + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', 'session_id', 'tab_sequence_ids', ] + + 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 + + qr_time_valide = -1 + if( "qr_time_valide" in diction.keys() and diction['qr_time_valide'] ): + Isfloat_status, Isfloat_retval = mycommon.IsFloat(str(diction['qr_time_valide'])) + if (Isfloat_status is False): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le temps de validité de l'émargement est incorrecte ") + return False, " Le temps de validité de l'émargement est incorrecte " + + qr_time_valide = round(float(Isfloat_retval), 2) + + # Verifier que la session est valide + is_session_id_valide = MYSY_GV.dbname['session_formation'].count_documents( + {'_id': ObjectId(str(diction['session_id'])), + 'valide': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_session_id_valide != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de la session est invalide ") + return False, " L'identifiant de la session est invalide " + + + # Verifier que les sequences sont valides + tab_sequence_ids = [] + tab_sequence_ids_ObjectId = [] + + tab_sequence_ids_work = str(diction['tab_sequence_ids']).split(",") + for local_sequence in tab_sequence_ids_work: + if(local_sequence ): + is_valide_sequence = MYSY_GV.dbname['session_formation_sequence'].count_documents({'_id':ObjectId(str(local_sequence)), + 'session_id':str(diction['session_id']), + 'partner_owner_recid':str(my_partner['recid']), + 'valide':'1', + 'locked':'0'}) + if( is_valide_sequence != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de la séquence "+str(local_sequence)+" est invalide ") + return False, "L'identifiant de la séquence "+str(local_sequence)+" est invalide " + + tab_sequence_ids.append(str(local_sequence)) + tab_sequence_ids_ObjectId.append(ObjectId(str(local_sequence))) + + + + tab_my_emargement_ids = [] + # Creation d'une clé securisé + my_safe_token = mycommon.create_user_recid() + now_v2 = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + for local_sequence_id in tab_sequence_ids: + + local_sequence_data = MYSY_GV.dbname['session_formation_sequence'].find_one({'_id':ObjectId(str(local_sequence_id)), + 'partner_owner_recid': str(my_partner['recid']), + 'valide':'1', + 'locked':'0' }) + """ + Récuperer la liste inscrit (groupe d'etudiant associé) + """ + tab_grp_apprenant_ids = [] + if ("tab_grp_apprenant_ids" in local_sequence_data.keys()): + for local_tab_grp_apprenant_ids in local_sequence_data['tab_grp_apprenant_ids']: + tab_grp_apprenant_ids.append(str(local_tab_grp_apprenant_ids['_id'])) + + + """ + Pour chaque inscrit appartenant à tab_grp_apprenant_ids + """ + now = str(datetime.now()) + for local_inscrit in MYSY_GV.dbname['groupe_inscription_membre'].find({'groupe_inscription_id':{'$in':tab_grp_apprenant_ids}, + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked': '0' + }): + + for tmp_val in MYSY_GV.dbname['inscription'].find({"$and": [{'session_id': str(diction['session_id']), + + 'status': '1', + 'partner_owner_recid': str(my_partner['recid'])}, + {'_id': ObjectId(local_inscrit['inscription_id'])} + ]}): + + query_key = {} + query_key['inscription_id'] = str(tmp_val['_id']) + query_key['session_id'] = tmp_val['session_id'] + query_key['class_internal_url'] = tmp_val['class_internal_url'] + query_key['session_formation_sequence_id'] = str(local_sequence_data['_id']) + + new_my_local_data = {} + new_my_local_data['session_formation_sequence_id'] = str(local_sequence_data['_id']) + new_my_local_data['inscription_id'] = str(tmp_val['_id']) + new_my_local_data['email'] = tmp_val['email'] + new_my_local_data['nom'] = tmp_val['nom'] + new_my_local_data['prenom'] = tmp_val['prenom'] + new_my_local_data['session_id'] = tmp_val['session_id'] + new_my_local_data['class_internal_url'] = tmp_val['class_internal_url'] + + new_my_local_data['sequence_start'] = str(local_sequence_data['sequence_start']) + new_my_local_data['sequence_end'] = str(local_sequence_data['sequence_end']) + new_my_local_data['qr_time_valide'] = str(qr_time_valide) + + new_my_local_data['update_date'] = now + query_key['date'] = str(local_sequence_data['sequence_start'])[0:10] + new_my_local_data['is_present'] = False + new_my_local_data['matin'] = False + new_my_local_data['apresmidi'] = False + new_my_local_data['sequence_title'] = str(local_sequence_data['sequence_title']) + + if ("volume_theorique" in local_sequence_data.keys() and local_sequence_data['volume_theorique']): + new_my_local_data['time_in_hour'] = str(local_sequence_data['volume_theorique']) + else: + if ("time_in_hour" in local_sequence_data.keys()): + new_my_local_data['time_in_hour'] = local_sequence_data['time_in_hour'] + else: + delta_time = datetime.strptime(str(local_sequence_data['sequence_end']), + '%d/%m/%Y %H:%M') - datetime.strptime( + str(local_sequence_data['sequence_start']), '%d/%m/%Y %H:%M') + + delta_time_converted_in_hour = round(float(delta_time.total_seconds() / 3600), 2) + new_my_local_data['time_in_hour'] = str(delta_time_converted_in_hour) + + new_my_local_data['statut'] = "1" + new_my_local_data['date_envoi'] = str(now_v2) + + new_my_local_data['update_date'] = str(datetime.now()) + new_my_local_data['update_by'] = str(my_partner['recid']) + new_my_local_data['valide'] = "1" + new_my_local_data['locked'] = "0" + + new_my_local_data['partner_owner_recid'] = str(my_partner['recid']) + + new_my_local_data['emargement_qr_safe_token'] = str(my_safe_token) + new_my_local_data['date_dernier_relance_auto'] = str(datetime.now().strftime("%d/%m/%Y")), + new_my_local_data['mode_envoi'] = "qr" + + # print("### emargement insertion de : "+str(new_my_local_data)) + + local_ret_val = MYSY_GV.dbname['emargement'].find_one_and_update( + query_key, + {"$set": new_my_local_data}, + upsert=True, + return_document=ReturnDocument.AFTER + ) + + if( local_ret_val and '_id' in local_ret_val.keys()): + tab_my_emargement_ids.append(str(local_ret_val['_id'])) + + + + + + """ + Mettre à jour l'inscription avec la , et on met le statut à "1" pour dire qu'on a demarré le process + """ + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + + url_for_qr_code = str(MYSY_GV.CLIENT_URL_BASE)+"qr_emargement/"+str(diction['session_id'])+"/"+str(my_partner['recid'])+"/"+str(my_safe_token)+"/" + ts = datetime.now().timestamp() + ts = str(ts).replace(".", "").replace(",", "")[-3:] + qr_code_img_file = str(MYSY_GV.TEMPORARY_DIRECTORY_V2) + "qr_code_" + str(ts) + ".png" + + qrcode = segno.make_qr(str(url_for_qr_code)) + qrcode.save( + qr_code_img_file, + scale=5, + dark="darkblue", + ) + + print(" ### Create_Emargement_QR_Code_From_Inscription url_for_qr_code = ", url_for_qr_code) + + """ + 25/01/2024 : Apres l'envoi de la demande + d'emargement, on log une action dans la collection ==> courrier_template_tracking_history + """ + + for my_emargement_id in tab_my_emargement_ids: + val_emarge = MYSY_GV.dbname['emargement'].find_one({'_id':ObjectId(str(my_emargement_id)), 'valide':'1', 'locked':'0', + 'partner_owner_recid':my_partner['recid']}) + + local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne( + my_partner, "EMARGEMENT_FORMATION", str(val_emarge['session_id']), "inscription", str(val_emarge['inscription_id']), + "") + + + """ + On met à jour la séquence pour dire quand est ce qu'on a lancé + le dernier emargement - + """ + MYSY_GV.dbname['session_formation_sequence'].update_many({'_id':{'$in':tab_sequence_ids_ObjectId}, + 'partner_owner_recid':my_partner['recid']}, + {'$set':{'last_emargement_request_date':now}}) + + if os.path.exists(qr_code_img_file): + return True, send_file(qr_code_img_file, as_attachment=True) + + return False, " Impossible de générer l'émargement par QR Code (1) " + + + 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 générer l'émargement par QR Code " + + + + +""" +06/04/2026 +Cette fonction permet d'initialiser le tableau d'émargement +et d'envoyer l'email dans la foulée. + +Ainsi au lieu de faire le process en 2 étapes, il sera fait en 1 étapes. +La fonction prends en argument la sequence_id, la durée de vie du QR code +(xxx minute apres la fin de la sequence. Si xxx < 0, alors pas de durée +ou durée = toujours) +""" +def Init_Emargement_And_Send_Email_Code_From_Inscription(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'session_id', 'tab_sequence_ids', 'qr_time_valide' ] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé") + return False, " Les informations fournies sont incorrectes" + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', 'session_id', 'tab_sequence_ids', ] + + 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 + + """ + Recuperation du modèle de courrier pour la demande d'emargement + """ + local_diction = {} + local_diction['ref_interne'] = "EMARGEMENT_FORMATION" + local_diction['type_doc'] = "email" + local_diction['partner_owner_recid'] = str(my_partner['recid']) + + courrier_data_status, courrier_data_retval = mycommon.Get_Courrier_Template_Include_Default_Data(local_diction) + if (courrier_data_status is False): + return courrier_data_status, courrier_data_retval + + # Recuperation des donnes smtp + 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( + my_partner['recid']) + + if (local_stpm_status is False): + return local_stpm_status, partner_SMTP_COUNT_smtpsrv + + + qr_time_valide = -1 + if( "qr_time_valide" in diction.keys() and diction['qr_time_valide'] ): + Isfloat_status, Isfloat_retval = mycommon.IsFloat(str(diction['qr_time_valide'])) + if (Isfloat_status is False): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le temps de validité de l'émargement est incorrecte ") + return False, " Le temps de validité de l'émargement est incorrecte " + + qr_time_valide = round(float(Isfloat_retval), 2) + + # Verifier que la session est valide + is_session_id_valide = MYSY_GV.dbname['session_formation'].count_documents( + {'_id': ObjectId(str(diction['session_id'])), + 'valide': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_session_id_valide != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de la session est invalide ") + return False, " L'identifiant de la session est invalide " + + + # Verifier que les sequences sont valides + tab_sequence_ids = [] + tab_sequence_ids_ObjectId = [] + + tab_sequence_ids_work = str(diction['tab_sequence_ids']).split(",") + for local_sequence in tab_sequence_ids_work: + if(local_sequence ): + is_valide_sequence = MYSY_GV.dbname['session_formation_sequence'].count_documents({'_id':ObjectId(str(local_sequence)), + 'session_id':str(diction['session_id']), + 'partner_owner_recid':str(my_partner['recid']), + 'valide':'1', + 'locked':'0'}) + if( is_valide_sequence != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de la séquence "+str(local_sequence)+" est invalide ") + return False, "L'identifiant de la séquence "+str(local_sequence)+" est invalide " + + tab_sequence_ids.append(str(local_sequence)) + tab_sequence_ids_ObjectId.append(ObjectId(str(local_sequence))) + + + + tab_my_emargement_ids = [] + # Creation d'une clé securisé + my_safe_token = mycommon.create_user_recid() + now_v2 = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + for local_sequence_id in tab_sequence_ids: + + local_sequence_data = MYSY_GV.dbname['session_formation_sequence'].find_one({'_id':ObjectId(str(local_sequence_id)), + 'partner_owner_recid': str(my_partner['recid']), + 'valide':'1', + 'locked':'0' }) + """ + Récuperer la liste inscrit (groupe d'etudiant associé) + """ + tab_grp_apprenant_ids = [] + if ("tab_grp_apprenant_ids" in local_sequence_data.keys()): + for local_tab_grp_apprenant_ids in local_sequence_data['tab_grp_apprenant_ids']: + tab_grp_apprenant_ids.append(str(local_tab_grp_apprenant_ids['_id'])) + + + """ + Pour chaque inscrit appartenant à tab_grp_apprenant_ids + """ + now = str(datetime.now()) + for local_inscrit in MYSY_GV.dbname['groupe_inscription_membre'].find({'groupe_inscription_id':{'$in':tab_grp_apprenant_ids}, + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked': '0' + }): + + for tmp_val in MYSY_GV.dbname['inscription'].find({"$and": [{'session_id': str(diction['session_id']), + + 'status': '1', + 'partner_owner_recid': str(my_partner['recid'])}, + {'_id': ObjectId(local_inscrit['inscription_id'])} + ]}): + + query_key = {} + query_key['inscription_id'] = str(tmp_val['_id']) + query_key['session_id'] = tmp_val['session_id'] + query_key['class_internal_url'] = tmp_val['class_internal_url'] + query_key['session_formation_sequence_id'] = str(local_sequence_data['_id']) + + new_my_local_data = {} + new_my_local_data['session_formation_sequence_id'] = str(local_sequence_data['_id']) + new_my_local_data['inscription_id'] = str(tmp_val['_id']) + new_my_local_data['email'] = tmp_val['email'] + new_my_local_data['nom'] = tmp_val['nom'] + new_my_local_data['prenom'] = tmp_val['prenom'] + new_my_local_data['session_id'] = tmp_val['session_id'] + new_my_local_data['class_internal_url'] = tmp_val['class_internal_url'] + + new_my_local_data['sequence_start'] = str(local_sequence_data['sequence_start']) + new_my_local_data['sequence_end'] = str(local_sequence_data['sequence_end']) + new_my_local_data['qr_time_valide'] = str(qr_time_valide) + + new_my_local_data['update_date'] = now + query_key['date'] = str(local_sequence_data['sequence_start'])[0:10] + new_my_local_data['is_present'] = False + new_my_local_data['matin'] = False + new_my_local_data['apresmidi'] = False + new_my_local_data['sequence_title'] = str(local_sequence_data['sequence_title']) + + if ("volume_theorique" in local_sequence_data.keys() and local_sequence_data['volume_theorique']): + new_my_local_data['time_in_hour'] = str(local_sequence_data['volume_theorique']) + else: + if ("time_in_hour" in local_sequence_data.keys()): + new_my_local_data['time_in_hour'] = local_sequence_data['time_in_hour'] + else: + delta_time = datetime.strptime(str(local_sequence_data['sequence_end']), + '%d/%m/%Y %H:%M') - datetime.strptime( + str(local_sequence_data['sequence_start']), '%d/%m/%Y %H:%M') + + delta_time_converted_in_hour = round(float(delta_time.total_seconds() / 3600), 2) + new_my_local_data['time_in_hour'] = str(delta_time_converted_in_hour) + + new_my_local_data['statut'] = "1" + new_my_local_data['date_envoi'] = str(now_v2) + + new_my_local_data['update_date'] = str(datetime.now()) + new_my_local_data['update_by'] = str(my_partner['recid']) + new_my_local_data['valide'] = "1" + new_my_local_data['locked'] = "0" + + new_my_local_data['partner_owner_recid'] = str(my_partner['recid']) + + new_my_local_data['emargement_qr_safe_token'] = str(my_safe_token) + new_my_local_data['date_dernier_relance_auto'] = str(datetime.now().strftime("%d/%m/%Y")), + new_my_local_data['mode_envoi'] = "qr" + + # print("### emargement insertion de : "+str(new_my_local_data)) + + local_ret_val = MYSY_GV.dbname['emargement'].find_one_and_update( + query_key, + {"$set": new_my_local_data}, + upsert=True, + return_document=ReturnDocument.AFTER + ) + + if( local_ret_val and '_id' in local_ret_val.keys()): + tab_my_emargement_ids.append(str(local_ret_val['_id'])) + + + + + + """ + Mettre à jour l'inscription avec la , et on met le statut à "1" pour dire qu'on a demarré le process + """ + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + url_for_qr_code = str(MYSY_GV.CLIENT_URL_BASE)+"qr_emargement/"+str(diction['session_id'])+"/"+str(my_partner['recid'])+"/"+str(my_safe_token)+"/" + ts = datetime.now().timestamp() + ts = str(ts).replace(".", "").replace(",", "")[-3:] + qr_code_img_file = str(MYSY_GV.TEMPORARY_DIRECTORY_V2) + "qr_code_" + str(ts) + ".png" + + qrcode = segno.make_qr(str(url_for_qr_code)) + qrcode.save( + qr_code_img_file, + scale=5, + dark="darkblue", + ) + + print(" ### Create_Emargement_QR_Code_From_Inscription url_for_qr_code = ", url_for_qr_code) + + + + """ + 25/01/2024 : Apres l'envoi de la demande + d'emargement, on log une action dans la collection ==> courrier_template_tracking_history + """ + """ + Debut de la procedure d'envoie de l'email + """ + convention_dictionnary_data = {} + new_diction = {} + new_diction['token'] = diction['token'] + new_diction['list_stagiaire_id'] = [] + new_diction['list_session_id'] = [ObjectId(str(diction['session_id']))] + new_diction['list_class_id'] = [] + new_diction['list_client_id'] = [] + + local_status, local_retval = mycommon.Get_Dictionnary_data_For_Template(new_diction) + + if (local_status is False): + return local_status, local_retval + + if ("company_data" in local_retval.keys() and "societe_nom" in local_retval['company_data'].keys()): + company_name = local_retval['company_data']['societe_nom'] + + emargement_dictionnary_data = local_retval + emargement_dictionnary_data['mysyurl'] = url_for_qr_code + + smtpserver = None + if (str(partner_own_smtp_value) == "1"): + smtpserver = smtplib.SMTP(partner_SMTP_COUNT_smtpsrv, partner_SMTP_COUNT_port) + else: + smtpserver = smtplib.SMTP(MYSY_GV.O365_SMTP_COUNT_smtpsrv, MYSY_GV.O365_SMTP_COUNT_port) + + smtpserver.ehlo() + smtpserver.starttls() + smtpserver.login(partner_SMTP_COUNT_user, partner_SMTP_COUNT_password) + + tab_inscription_id_emargement_send = [] + cpt_email_envoye = 0 + + for my_emargement_id in tab_my_emargement_ids: + my_emargement_data = MYSY_GV.dbname['emargement'].find_one({'_id':ObjectId(str(my_emargement_id)), 'valide':'1', 'locked':'0', + 'partner_owner_recid':my_partner['recid']}) + + local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne( + my_partner, "EMARGEMENT_FORMATION", str(my_emargement_data['session_id']), "inscription", str(my_emargement_data['inscription_id']), + "") + + + if (str(my_emargement_data['inscription_id']) not in tab_inscription_id_emargement_send): + + tab_inscription_id_emargement_send.append(str(my_emargement_data['inscription_id'])) + cpt_email_envoye = cpt_email_envoye + 1 + + # Recuperation des données de l'inscrit + local_inscrit_data = mycommon.Get_Inscrit_And_Apprenant_Data( + {'token': str(diction['token']), 'inscrit_id': str(my_emargement_data['inscription_id'])}) + emargement_dictionnary_data['emargement_inscrit_data'] = local_inscrit_data + + # Recuperation des données de la formation + myclass_data = MYSY_GV.dbname['myclass'].find_one( + {'internal_url': str(my_emargement_data['class_internal_url']), + 'partner_owner_recid': my_partner['recid']}, {'title': 1}) + emargement_dictionnary_data['emargement_class_data'] = myclass_data + + emargement_dictionnary_data['emargement_data'] = my_emargement_data + + body = { + "params": emargement_dictionnary_data, + } + + # print( " ### emargement_dictionnary_data ===== ", emargement_dictionnary_data) + + # Traitement du sujet du mail + sujet_mail_Template = jinja2.Template(str(courrier_data_retval['sujet'])) + sujetHtml = sujet_mail_Template.render(params=body["params"]) + + # Traitement du corps du mail + contenu_doc_Template = jinja2.Template(str(courrier_data_retval['contenu_doc'])) + sourceHtml = contenu_doc_Template.render(params=body["params"]) + html_mime = MIMEText(sourceHtml, 'html') + + # Creation de l'email à enoyer + msg = MIMEMultipart("alternative") + + if (str(partner_own_smtp_value) == "1"): + msg.attach(html_mime) + msg['From'] = partner_SMTP_COUNT_From_User + msg['Bcc'] = 'contact@mysy-training.com' + msg['Subject'] = sujetHtml + msg['to'] = str(my_emargement_data['email']) + + smtpserver.ehlo() + smtpserver.starttls() + smtpserver.login(partner_SMTP_COUNT_user, partner_SMTP_COUNT_password) + val = smtpserver.send_message(msg) + #print(" Email demande emargement envoyé " + str(val)) + + else: + msg.attach(html_mime) + # msg['From'] = MYSY_GV.O365_SMTP_COUNT_From_User + if (company_name): + msg['From'] = str(company_name) + " <" + str(MYSY_GV.O365_SMTP_COUNT_From_User) + ">" + else: + msg['From'] = str(MYSY_GV.O365_SMTP_COUNT_From_User) + msg['Bcc'] = 'contact@mysy-training.com' + msg['Subject'] = sujetHtml + msg['to'] = str(my_emargement_data['email']) + val = smtpserver.send_message(msg) + #print(" Email demande emargement envoyé " + str(val)) + + """ + Gestion des emails via mail_queu et internal email + """ + + tab_email_bcc = [] + tab_email_bcc.append("contact@mysy-training.com") + + """ + IMPORTANT : Cette section sera utilisée une fois que le module de Queu de message est ok + """ + queue_mail_diction = {} + queue_mail_diction['token'] = diction['token'] + queue_mail_diction['tab_email_cc'] = [] + queue_mail_diction['tab_email_bcc'] = tab_email_bcc + if (sujetHtml): + queue_mail_diction['email_sujet'] = sujetHtml + else: + queue_mail_diction['email_sujet'] = "[MySy Training]: Demande d'émargement" + + queue_mail_diction['message'] = sourceHtml + + queue_mail_diction['smtp_account_password'] = partner_SMTP_COUNT_password + queue_mail_diction['smtp_account_smtpsrv'] = partner_SMTP_COUNT_smtpsrv + queue_mail_diction['smtp_account_user'] = partner_SMTP_COUNT_user + queue_mail_diction['smtp_account_From_User'] = partner_SMTP_COUNT_From_User + queue_mail_diction['smtp_account_port'] = partner_SMTP_COUNT_port + + queue_mail_diction['tab_files_to_attache_to_mail'] = [] + + queue_mail_diction['email_to'] = str(my_emargement_data['email']) + + queue_and_internal_mail_status, queue_and_internal_mail_status = email_mgt.Individual_Mail_Store_Queu_And_Internal_Mail( + queue_mail_diction) + if (queue_and_internal_mail_status is False): + print(" ## WARNING queue_mail_retval = ", queue_and_internal_mail_status) + + smtpserver.close() + + print(" NB_email envoyé = ", cpt_email_envoye) + """ + On met à jour la séquence pour dire quand est ce qu'on a lancé + le dernier emargement - + """ + MYSY_GV.dbname['session_formation_sequence'].update_many({'_id':{'$in':tab_sequence_ids_ObjectId}, + 'partner_owner_recid':my_partner['recid']}, + {'$set':{'last_emargement_request_date':now}}) + + + + + + return True, str(cpt_email_envoye)+" Email(s) d'émargement envoyé(s) " + + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible de générer l'émargement par email " + + + + +""" +Verifier qu'un QR code est valide avec le mail de la personne. +C'est le controle qui est fait avant acces à l'emargemnt + +07/06/26 - avec le champs 'qr_time_valide', il va etre possible de gérer +la durée de validité d'un QR code. +regle : +si qr_time_valide < 0 ==> Valide pour toujours +si qr_time_valide >= 0 (miniute), on compare avec la colonne 'sequence_end' +""" + +def Check_Emargement_QR_Code_From_Inscription_No_Token(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['partner_owner_recid', 'my_safe_token', 'session_id', 'user_email'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé") + return False, " Les informations fournies sont incorrectes" + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['partner_owner_recid', 'my_safe_token', 'session_id', 'user_email'] + + 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 + """ + + local_status, my_partner = mycommon.Get_Connected_User_Partner_Data_From_RecID( + str(diction['partner_owner_recid'])) + if (local_status is not True): + return local_status, my_partner + + # Verifier que les info sont valide + + + is_emargement_valide_count = MYSY_GV.dbname['emargement'].count_documents({'session_id': str(diction['session_id']), + 'emargement_qr_safe_token': str(diction['my_safe_token']), + 'email': str(diction['user_email']).lower().strip(), + 'partner_owner_recid': str(diction['partner_owner_recid']), + 'statut': '1'}) + + if( is_emargement_valide_count <= 0 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Les identifiants sont invalides ") + return False, " Les identifiants sont invalides " + + RetObject = [] + nb_val = 0 + + for retval in MYSY_GV.dbname['emargement'].find( + {'session_id': str(diction['session_id']), + 'emargement_qr_safe_token': str(diction['my_safe_token']), + 'email': str(diction['user_email']).lower().strip(), + 'partner_owner_recid': str(diction['partner_owner_recid']), + 'statut': '1'}): + + + user = {} + user = retval + user['id'] = str(nb_val) + code_session = "" + class_interna_url = "" + class_title = "" + sequence_title = "" + qr_time_valide = "-1" + + """ + 07/04/26 - gestion de la durée de validité du QR code + """ + if( "qr_time_valide" in retval.keys() and retval['qr_time_valide'] and "sequence_end" in retval.keys() and retval['sequence_end']): + qr_time_valide = mycommon.tryFloat(str(retval['qr_time_valide'])) + print(" ### qr_time_valide = ", str(qr_time_valide)) + + if( qr_time_valide >= 0 ): + today_date_heure_minute = datetime.now().strftime("%d/%m/%Y %H:%M") + limite_validite_qr_code = datetime.strptime(str(retval['sequence_end']).strip(), '%d/%m/%Y %H:%M')+ timedelta(minutes=qr_time_valide) + """print(" ### CONTROLE LIMITE VALIDITE ") + print(" ### today_date_heure_minute = ", str(today_date_heure_minute)) + print(" ### qr_time_valide = ", str(qr_time_valide)) + print(" ### Fin Sequence = ", str(retval['sequence_end'])) + print(" ### limite_validite_qr_code = ", str(limite_validite_qr_code.strftime("%d/%m/%Y %H:%M")))""" + + if( today_date_heure_minute < limite_validite_qr_code.strftime("%d/%m/%Y %H:%M")): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Oups, ce QR code n’est plus valide 😅, Contactez le gestionnaire pour en obtenir un nouveau. ") + return False, "Oups, ce QR code n’est plus valide 😅, Contactez le gestionnaire pour en obtenir un nouveau. " + + + if( "session_formation_sequence_id" in retval.keys() ): + session_formation_sequence_data = MYSY_GV.dbname['session_formation_sequence'].find_one({'_id':ObjectId(str(retval['session_formation_sequence_id'])), + 'partner_owner_recid':str(diction['partner_owner_recid']),}, {'sequence_title':1}) + + + if( session_formation_sequence_data and "sequence_title" in session_formation_sequence_data.keys() ): + sequence_title = session_formation_sequence_data['sequence_title'] + + + session_data = MYSY_GV.dbname['session_formation'].find_one({'_id':ObjectId(str(retval['session_id'])), + 'partner_owner_recid':str(diction['partner_owner_recid']), + 'valide':'1'}) + + if( session_data and 'code_session' in session_data.keys() ): + code_session = session_data['code_session'] + + if (session_data and 'class_internal_url' in session_data.keys()): + class_interna_url = session_data['class_internal_url'] + class_data = MYSY_GV.dbname['myclass'].find_one({'internal_url':str(class_interna_url), + 'partner_owner_recid':str(diction['partner_owner_recid']), + 'valide':'1'}, {'title':1}) + + if( class_data and "title" in class_data.keys() ): + class_title = class_data['title'] + + + user['class_title'] = str(class_title) + user['code_session'] = str(code_session) + user['sequence_title'] = str(sequence_title) + + nb_val = nb_val + 1 + + RetObject.append(mycommon.JSONEncoder().encode(user)) + + return True, RetObject + + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible de vérifier la validité des informations " + + +""" +Emargement avec le QR CODE pour dire qu'on est présent ou absent +""" +def Update_Emargement_QR_Code_From_Inscription_No_Token(file_img=None, Folder=None, diction=None): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['partner_owner_recid', 'my_safe_token', 'tab_emargement_ids', 'is_present', 'signature_img_selected'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé") + return False, " Les informations fournies sont incorrectes" + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['partner_owner_recid', 'my_safe_token', 'tab_emargement_ids', 'is_present', 'signature_img_selected'] + + 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 + """ + + + + local_status, my_partner = mycommon.Get_Connected_User_Partner_Data_From_RecID( + str(diction['partner_owner_recid'])) + if (local_status is not True): + return local_status, my_partner + + # Verifier que l'identifiant de l'emargement est valide + my_emargement_ids = "" + if ("tab_emargement_ids" in diction.keys()): + if diction['tab_emargement_ids']: + my_emargement_ids = diction['tab_emargement_ids'] + + + tab_my_emargement_ids = str(my_emargement_ids).split(",") + for my_emargement_id in tab_my_emargement_ids: + is_emargement_valide_count = MYSY_GV.dbname['emargement'].count_documents({'emargement_qr_safe_token': str(diction['my_safe_token']), + '_id': ObjectId(str( my_emargement_id) ), + 'partner_owner_recid': str(diction['partner_owner_recid']), + 'statut': '1'}) + + if( is_emargement_valide_count != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de l'émargement "+str(my_emargement_id)+" est invalide ") + return False, " L'identifiant de l'émargement "+str(my_emargement_id)+" est invalide " + + image_signature_manuelle_string = "" + if (file_img): + status, saved_file = mycommon.Upload_Save_IMG_File(file_img, Folder) + if (status is False): + mycommon.myprint(str(saved_file)) + return False, str(saved_file) + + #print(" signature manuelle = ", saved_file) + with open(saved_file, "rb") as imageFile: + image_signature_manuelle_string = base64.b64encode(imageFile.read()).decode() + + """ + 22/06/204 - On abandone l'approche qui consiste a envoyer le fichier de signature. + on va plutot envoyer directement la signature sous forme d'image. + """ + image_signature_manuelle_string_v2 = diction['signature_img_selected'] + + tab_my_emargement_ids = str(my_emargement_ids).split(",") + for my_emargement_id in tab_my_emargement_ids: + data_cle = {'emargement_qr_safe_token': str(diction['my_safe_token']), + '_id': ObjectId(str(my_emargement_id)), + 'partner_owner_recid': str(diction['partner_owner_recid']), + 'statut': '1'} + + is_present = "" + if ("is_present" in diction.keys()): + if diction['is_present']: + is_present = diction['is_present'] + + + + # Mettre à jour de l'emargement + data_update = {} + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + data_update['update_date'] = now + data_update['statut'] = "2" + data_update['date_emargement'] = now + data_update['update_by'] = str(my_partner['_id']) + + #data_update["mysy_manual_signature_img"] = "data:image/png;base64," + image_signature_manuelle_string + + data_update["mysy_manual_signature_img"] = image_signature_manuelle_string_v2 + + if (is_present == "1"): + data_update['is_present'] = True + elif (is_present == "0"): + data_update['is_present'] = False + + inserted_id = "" + result = MYSY_GV.dbname['emargement'].find_one_and_update( + data_cle, + {"$set": data_update}, + upsert=False, + return_document=ReturnDocument.AFTER + ) + + return True, "L'émargement a été pris en compte" + + + 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'émarger " + +""" +Cette fonction permet d'ajouter et mettre à jour un split de facture sur une inscription + +La fonction prends en entrée, l'inscription_id, tab_split :[{'partner_client':'cccc', 'invoice_part':'10'}, + {'partner_client':'yyyyy', 'invoice_part':'800'}]} +""" +def Add_Update_Inscription_Split_Invoice(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'inscription_id', 'split_type', 'tab_split'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé") + return False, " Les informations fournies sont incorrectes" + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', 'inscription_id', 'split_type', 'tab_split'] + + 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'inscription + is_inscription_valide_count = MYSY_GV.dbname['inscription'].count_documents({'_id':ObjectId(str(diction['inscription_id'])), + 'valide':'1', + 'partner_owner_recid':str(my_partner['recid']) + }) + if( is_inscription_valide_count != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de l'inscription est invalide ") + return False, " L'identifiant de l'inscription est invalide " + + # Verifier que le 'split_type' est soit percent, soit fixe + split_type = str(diction["split_type"]).lower() + + if( split_type not in ['fixe', 'percent']): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le type de partage doit être en pourcentage ou en montant ") + return False, " Le type de partage doit être en pourcentage ou en montant " + + # Verifier que le contenu 'tab_split' est valide et du type : [{'partner_client':'cccc', 'invoice_part':'10'}, + # {'partner_client':'yyyyy', 'invoice_part':'800'}] + tab_split = diction['tab_split'] + tab_split_JSON = ast.literal_eval(tab_split) + + print(" ### tab_split_JSON = ", tab_split_JSON) + + total_invoice_part = 0 + + for val in tab_split_JSON: + is_val_ok = "0" + if( "partner_client" in val.keys() and val['partner_client'] and "invoice_part" in val.keys() and val["invoice_part"]): + local_client = str(val['partner_client']) + local_partage = str(val["invoice_part"]) + + # Verifier que le client dans le partage est valide + is_partage_client_valide = MYSY_GV.dbname['partner_client'].count_documents({'_id':ObjectId(str(local_client)), + 'valide':'1', + 'locked':'0', + 'partner_owner_recid':str(my_partner['recid'])}) + + + if( is_partage_client_valide != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant du client "+str(local_client)+" est invalide ") + return False, " L'identifiant du client "+str(local_client)+" est invalide " + + # Verifier que la valeur de partage est bien un floattant + is_partage_float_status, is_partage_float_retval = mycommon.IsFloat(local_partage) + if( is_partage_float_status is False ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " La valeur de partage " + str( + local_partage) + " est invalide ") + return False, " La valeur de partage " + str(local_partage) + " est invalide " + + + total_invoice_part = total_invoice_part + is_partage_float_retval + is_val_ok = "1" + + else: + mycommon.myprint( + str(inspect.stack()[0][3]) + " Les paramètres de partage de la facture sont invalides ") + return False, " Les paramètres de partage de la facture sont invalides " + + + + if( split_type == "percent" and total_invoice_part > 100 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Pour une répartition par pourcentage, le total ne doit pas depasser 100% ") + return False, " Pour une répartition par pourcentage, le total ne doit pas dépasser 100% " + + + node_invoice_split = {} + node_invoice_split['split_type'] = split_type + node_invoice_split['tab_split'] = tab_split_JSON + + data_update = {} + data_update['update_by'] = str(my_partner['_id']) + data_update['update_date'] = str(datetime.now()) + data_update['invoice_split'] = node_invoice_split + + + + inserted_id = "" + result = MYSY_GV.dbname['inscription'].find_one_and_update( + {'_id': ObjectId(str(diction['inscription_id'])), + 'valide': '1', + 'partner_owner_recid': str(my_partner['recid']) + }, + {"$set": data_update}, + upsert=False, + return_document=ReturnDocument.AFTER + ) + if ("_id" not in result.keys()): + mycommon.myprint(" Impossible de mettre à jour le partage de facture (2) ") + return False, " Impossible de mettre à jour le partage de facture (2) " + + return True, " Le partage de facture 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) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible de mettre à jour le Le partage de facture " + +""" +Cette fonction permet de recuperer uniquement +le partage de facture d'un inscription +""" + +def Get_Inscription_Split_Invoice(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'inscription_id',] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé") + return False, " Les informations fournies sont incorrectes" + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', '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, " 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'inscription + is_inscription_valide_count = MYSY_GV.dbname['inscription'].count_documents({'_id':ObjectId(str(diction['inscription_id'])), + 'valide':'1', + 'partner_owner_recid':str(my_partner['recid']) + }) + if( is_inscription_valide_count != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de l'inscription est invalide ") + return False, " L'identifiant de l'inscription est invalide " + + RetObject = [] + val_tmp = 0 + for New_retVal in MYSY_GV.dbname['inscription'].find({'_id':ObjectId(str(diction['inscription_id'])), + 'valide':'1', + 'partner_owner_recid':str(my_partner['recid']) + }, {'_id':1, 'email':1, 'invoice_split':1}): + user = New_retVal + user['id'] = str(val_tmp) + val_tmp = val_tmp + 1 + RetObject.append(mycommon.JSONEncoder().encode(user)) + + return True, RetObject + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible de récupérer les données de partage de facture " + + +""" +Cette fonction supprime un partage de facture sur une inscription +""" + +def Delete_Inscription_Split_Invoice(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'inscription_id', ] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé") + return False, " Les informations fournies sont incorrectes" + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', '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, " 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'inscription + is_inscription_valide_count = MYSY_GV.dbname['inscription'].count_documents( + {'_id': ObjectId(str(diction['inscription_id'])), + 'valide': '1', + 'partner_owner_recid': str(my_partner['recid']) + }) + if (is_inscription_valide_count != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de l'inscription est invalide ") + return False, " L'identifiant de l'inscription est invalide " + + result = MYSY_GV.dbname['inscription'].find_one_and_update( + {'_id': ObjectId(str(diction['inscription_id'])), + 'valide': '1', + 'partner_owner_recid': str(my_partner['recid']) + }, + {"$unset": {"invoice_split":""}}, + upsert=False, + return_document=ReturnDocument.AFTER + ) + if ("_id" not in result.keys()): + mycommon.myprint(" Impossible supprimer le partage de facture (2) ") + return False, " Impossible supprimer le partage de facture (2) " + + return True, " Le partage de facture a été correctement supprimé " + + 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 supprimer le partage de facture " + + + +""" +Cette fonction permet de modidier la fin de +validité des acces au e-learning pour une liste +d'inscription. +Concretement cette fonction va desincrire l'apprenant à la formation dans le LMS +""" +def Update_LMS_Inscrition_End_Date(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'session_id', 'tab_inscription_ids', 'end_date'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé") + return False, " Les informations fournies sont incorrectes" + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', 'session_id', 'tab_inscription_ids', 'end_date'] + + 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 + """ + 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, False + + end_date = str(diction['end_date'])[0:10] + local_status = mycommon.CheckisDate(end_date) + if (local_status is False): + mycommon.myprint(str( + inspect.stack()[0][3]) + " La date de fin n'est pas au format jj/mm/aaaa.") + return False, " La date de fin n'est pas au format jj/mm/aaaa." + + mytoday = datetime.today().strftime("%d/%m/%Y") + if (datetime.strptime(str(diction['end_date'])[0:10], '%d/%m/%Y') < datetime.strptime(str(mytoday).strip(), + '%d/%m/%Y')): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La date de fin d'accès au LMS " + str( + diction['end_date']) + " est antérieure à la date du jour ") + + return False, " La date de fin d'accès au LMS " + str( + diction['end_date']) + " est antérieure à la date du jour " + + + # Verifier que la session est valide + is_session_id_valide = MYSY_GV.dbname['session_formation'].count_documents( + {'_id': ObjectId(str(diction['session_id'])), + 'valide': '1', + 'partner_owner_recid': str(my_partner['recid'])}) + + if (is_session_id_valide != 1): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " L'identifiant de la session est invalide ") + return False, " L'identifiant de la session est invalide ", False + + + my_inscription_ids = "" + if ("tab_inscription_ids" in diction.keys()): + if diction['tab_inscription_ids']: + my_inscription_ids = diction['tab_inscription_ids'] + + tab_my_inscription_ids = str(my_inscription_ids).split(",") + tab_my_inscription_ids_ObjectId = [] + for tmp in tab_my_inscription_ids: + tab_my_inscription_ids_ObjectId.append(ObjectId(str(tmp))) + + + tab_my_inscription_ids = str(my_inscription_ids).split(",") + + now = str(datetime.now()) + update_data = {} + + update_data['update_date'] = now + update_data['update_by'] = str(my_partner['_id']) + update_data['lms_account_expiration_date'] = str(end_date) + + update = MYSY_GV.dbname['inscription'].update_many({'partner_owner_recid': str(my_partner['recid']), + 'session_id': diction['session_id'], + '_id':{'$in':tab_my_inscription_ids_ObjectId},}, + {'$set': update_data}) + + + + + + return True, " La mise à jour été correctement faite " + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible de mettre à jour la date " + + + +""" +02/06/2025 : Archivage d'un stagiaire +""" +def archive_stagiaire(diction): + try: + + ''' + # Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés + # Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API + # Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste + # field_list. + ''' + field_list = ['tab_stagiaire_ids', 'token'] + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint( + str(inspect.stack()[0][3])+" - Le champ '" + val + "' n'existe pas") + return False, " Le champ '" + val + "' n'existe pas" + + ''' + 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 = ['tab_stagiaire_ids', '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, " Impossible de mettre à jour la formation" + + # recuperation des paramettre + mydata = {} + my_internal_url = "" + + if ("token" in diction.keys()): + if diction['token']: + mydata['token'] = diction['token'] + + # Verification de la validité du token + tab_stagiaire_ids = [] + tab_stagiaire_ids_ObjectId = [] + if ("tab_stagiaire_ids" in diction.keys()): + tab_stagiaire_ids = str(diction['tab_stagiaire_ids']).split(",") + + for tmp in tab_stagiaire_ids: + if (tmp): + tab_stagiaire_ids_ObjectId.append(ObjectId(tmp)) + + # Verification de la validité du token + local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) + if (local_status is not True): + return local_status, my_partner + + mydata['update_date'] = str(datetime.now()) + mydata['update_by'] = str(my_partner['_id']) + mydata['archive'] = '1' + + + # seules les formations avec locked = 0 et valide=1 sont modifiables + ret_val = MYSY_GV.dbname['inscription'].update_many( + {'_id': {'$in': tab_stagiaire_ids_ObjectId}, 'valide': '1', + 'partner_owner_recid': str(my_partner['recid'])}, + {"$set": mydata}, + + ) + + for stagiaire_id in tab_stagiaire_ids: + # pour la collection 'myclass' + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + # print(" ####### laaaa diction = ", diction) + + history_event_dict = {} + history_event_dict['token'] = str(diction['token']) + history_event_dict['related_collection'] = "inscription" + history_event_dict['related_collection_recid'] = str(stagiaire_id) + history_event_dict['action_date'] = str(now) + + history_event_dict['action_description'] = "Archivage " + 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, " Stagiaire(s) archivé(s) " + + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible d'archiver les inscrits " + + +""" +02/06/2025 : De-Archivage d'un stagiaire +""" +def unarchive_stagiaire(diction): + try: + + ''' + # Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés + # Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API + # Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste + # field_list. + ''' + field_list = ['tab_stagiaire_ids', 'token'] + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint( + str(inspect.stack()[0][3])+" - Le champ '" + val + "' n'existe pas") + return False, " Le champ '" + val + "' n'existe pas" + + ''' + 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 = ['tab_stagiaire_ids', '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, " Impossible de mettre à jour la formation" + + # recuperation des paramettre + mydata = {} + my_internal_url = "" + + if ("token" in diction.keys()): + if diction['token']: + mydata['token'] = diction['token'] + + # Verification de la validité du token + tab_stagiaire_ids = [] + tab_stagiaire_ids_ObjectId = [] + if ("tab_stagiaire_ids" in diction.keys()): + tab_stagiaire_ids = str(diction['tab_stagiaire_ids']).split(",") + + for tmp in tab_stagiaire_ids: + if (tmp): + tab_stagiaire_ids_ObjectId.append(ObjectId(tmp)) + + # Verification de la validité du token + local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) + if (local_status is not True): + return local_status, my_partner + + mydata['update_date'] = str(datetime.now()) + mydata['update_by'] = str(my_partner['_id']) + mydata['archive'] = '0' + + + # seules les formations avec locked = 0 et valide=1 sont modifiables + ret_val = MYSY_GV.dbname['inscription'].update_many( + {'_id': {'$in': tab_stagiaire_ids_ObjectId}, 'valide': '1', + 'partner_owner_recid': str(my_partner['recid'])}, + {"$set": mydata}, + + ) + + for stagiaire_id in tab_stagiaire_ids: + # pour la collection 'myclass' + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + # print(" ####### laaaa diction = ", diction) + + history_event_dict = {} + history_event_dict['token'] = str(diction['token']) + history_event_dict['related_collection'] = "inscription" + history_event_dict['related_collection_recid'] = str(stagiaire_id) + history_event_dict['action_date'] = str(now) + + history_event_dict['action_description'] = "Desarchivage " + 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, " Stagiaire(s) desarchivé(s) " + + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible desarchiver les inscrits" + + +""" +Cette fonction pemet recuperer les tuteurs d'un inscrit +""" +def Get_Inscrit_List_Tuteurs(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'inscription_id'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ") + return False, " Les informations fournies sont incorrectes", + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', '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, " Les informations fournies sont incorrectes", + + """ + Verification de l'identité et autorisation de l'entité qui + appelle cette API + """ + token = "" + if ("token" in diction.keys()): + if diction['token']: + token = diction['token'] + + + local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) + if (local_status is not True): + return local_status, my_partner + + + + RetObject = [] + val_tmp = 0 + + for retval in MYSY_GV.dbname['ressource_humaine'].find({'partner_recid': my_partner['recid'], + 'tab_inscription_id.inscription_id':str(diction['inscription_id'])} ): + + node_rh_tuteur = {} + node_rh_tuteur['_id'] = str(retval['_id']) + node_rh_tuteur['id'] = str(val_tmp) + val_tmp = val_tmp + 1 + + + if( "nom" in retval.keys()): + node_rh_tuteur['nom'] = str(retval['nom']) + else: + node_rh_tuteur['nom'] = "" + + if ("prenom" in retval.keys()): + node_rh_tuteur['prenom'] = str(retval['prenom']) + else: + node_rh_tuteur['prenom'] = "" + + if ("email" in retval.keys()): + node_rh_tuteur['email'] = str(retval['email']) + else: + node_rh_tuteur['email'] = "" + + if ("telephone" in retval.keys()): + node_rh_tuteur['telephone'] = str(retval['telephone']) + else: + node_rh_tuteur['telephone'] = "" + + if ("telephone_mobile" in retval.keys()): + node_rh_tuteur['telephone_mobile'] = str(retval['telephone_mobile']) + else: + node_rh_tuteur['telephone_mobile'] = "" + + if ("adr_adresse" in retval.keys()): + node_rh_tuteur['adr_adresse'] = str(retval['adr_adresse']) + else: + node_rh_tuteur['adr_adresse'] = "" + + if ("adr_code_postal" in retval.keys()): + node_rh_tuteur['adr_code_postal'] = str(retval['adr_code_postal']) + else: + node_rh_tuteur['adr_code_postal'] = "" + + + if ("adr_ville" in retval.keys()): + node_rh_tuteur['adr_ville'] = str(retval['adr_ville']) + else: + node_rh_tuteur['adr_ville'] = "" + + if ("adr_pays" in retval.keys()): + node_rh_tuteur['adr_pays'] = str(retval['adr_pays']) + else: + node_rh_tuteur['adr_pays'] = "" + + if ("civilite" in retval.keys()): + node_rh_tuteur['civilite'] = str(retval['civilite']) + else: + node_rh_tuteur['civilite'] = "" + + if ("date_naissance" in retval.keys()): + node_rh_tuteur['date_naissance'] = str(retval['date_naissance']) + else: + node_rh_tuteur['date_naissance'] = "" + + + + for insc_tutore_data in retval["tab_inscription_id"]: + if(str(insc_tutore_data['inscription_id']) == str(diction['inscription_id']) ): + + if ("role" in insc_tutore_data.keys()): + node_rh_tuteur['role'] = str(insc_tutore_data['role']) + tuteur_label = "" + if( str(insc_tutore_data['role']) == "0"): + tuteur_label = "Parent" + elif( str(insc_tutore_data['role']) == "1"): + tuteur_label = "Tuteur légal" + elif (str(insc_tutore_data['role']) == "2"): + tuteur_label = "Tuteur scolaire" + elif (str(insc_tutore_data['role']) == "3"): + tuteur_label = "Autre" + elif (str(insc_tutore_data['role']) == "4"): + tuteur_label = "Tuteur pédagogique" + + node_rh_tuteur['tuteur_role_label'] = tuteur_label + + else: + node_rh_tuteur['role'] = "" + node_rh_tuteur['tuteur_role_label'] = "" + + if ("include_com" in insc_tutore_data.keys() and str(insc_tutore_data['include_com']) in ['0', '1']): + node_rh_tuteur['include_com'] = str(insc_tutore_data['include_com']) + else: + node_rh_tuteur['include_com'] = "0" + + if ("comment" in insc_tutore_data.keys()): + node_rh_tuteur['comment'] = str(insc_tutore_data['comment']) + else: + node_rh_tuteur['comment'] = "" + + + + RetObject.append(mycommon.JSONEncoder().encode(node_rh_tuteur)) + + + 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 tuteurs " + + + +""" +Cette fonction recuperer la liste des inscrits avec un filtre sur le statut de facturation +invoice_status +""" +def Get_Inscrit_By_Invoice_Status_For_List_Session(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'tab_session_id', 'invoice_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, " Les informations fournies sont incorrectes", + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', 'tab_session_id', 'invoice_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, " Les informations fournies sont incorrectes", + + """ + Verification de l'identité et autorisation de l'entité qui + appelle cette API + """ + token = "" + if ("token" in diction.keys()): + if diction['token']: + token = diction['token'] + + + local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction) + if (local_status is not True): + return local_status, my_partner + + tab_session_id = [] + tab_session_id_work = str(diction['tab_session_id']).split(',') + for session_id in tab_session_id_work: + if( session_id ): + if (MYSY_GV.dbname['session_formation'].count_documents({'_id': ObjectId(str(session_id)), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " La session_id :" + str(session_id) + " est invalide ") + return False, " L'identifiant de la session :" + str(session_id) + " est invalide " + + + tab_session_id.append(session_id) + + filt_invoice_status = {} + if ("invoice_status" in diction.keys()): + invoice_status = {'invoiced': str(diction['invoice_status'])} + + query = {'$and': [filt_invoice_status, {'partner_owner_recid': my_partner['recid'], 'session_id': {'$in': tab_session_id} }]} + + + RetObject = [] + val_tmp = 0 + + for retval in MYSY_GV.dbname['inscription'].find(query ).sort([("_id", pymongo.DESCENDING), ]): + + user = {} + user['id'] = str(val_tmp) + user['_id'] = str(retval['_id']) + val_tmp = val_tmp + 1 + + if( "email" in retval.keys()): + user['email'] = str(retval['email']) + else: + user['email'] = "" + + if ("session_id" in retval.keys()): + user['session_id'] = str(retval['session_id']) + else: + user['session_id'] = "" + + if ("apprenant_id" in retval.keys()): + user['apprenant_id'] = str(retval['apprenant_id']) + else: + user['apprenant_id'] = "" + + if ("civilite" in retval.keys()): + user['civilite'] = str(retval['civilite']) + else: + user['civilite'] = "" + + if ("prenom" in retval.keys()): + user['prenom'] = str(retval['prenom']) + else: + user['prenom'] = "" + + if ("nom" in retval.keys()): + user['nom'] = str(retval['nom']) + else: + user['nom'] = "" + + if ("date_naissance" in retval.keys()): + user['date_naissance'] = str(retval['date_naissance']) + else: + user['date_naissance'] = "" + + + if ("invoiced" in retval.keys()): + user['invoiced'] = str(retval['invoiced']) + else: + user['invoiced'] = "" + + if ("invoiced_ref" in retval.keys()): + user['invoiced_ref'] = str(retval['invoiced_ref']) + else: + user['invoiced_ref'] = "" + + if ("invoiced_date" in retval.keys()): + user['invoiced_date'] = str(retval['invoiced_date']) + else: + user['invoiced_date'] = "" + + + 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 facturés " + + + +""" +Ce fonction permet de recuperer la liste de toutes les séquences qui concerne un inscrit. +Alogo : +1 - Pour une session donnée, recuprer la liste tous les groupes d'inscrit qui concerne cet inscrit +2 - Recuprer la liste des séquences auxquelles ces groupes sont rattaché +""" +def Get_Inscrit_List_Sequence_Formation_For_Given_Session(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'session_id', 'tab_inscrit_ids', 'tab_domaine_competence_ids'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ") + return False, " Les informations fournies sont incorrectes", + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', 'session_id', 'tab_inscrit_ids'] + 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 la session + if (MYSY_GV.dbname['session_formation'].count_documents({'_id': ObjectId(str(diction['session_id'])), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " La session_id :" + str(diction['session_id']) + " est invalide ") + return False, " L'identifiant de la session :" + str(diction['session_id']) + " est invalide " + + filt_domaine_competence = {} + tab_domaine_competence_ids = [] + if( "tab_domaine_competence_ids" in diction.keys() and diction['tab_domaine_competence_ids']): + tab_domaine_competence_ids_work = str(diction['tab_domaine_competence_ids']).split(',') + for domaine_competence_id in tab_domaine_competence_ids_work: + if (domaine_competence_id): + if (MYSY_GV.dbname['domaine_competence_pedagogique'].count_documents({'_id': ObjectId(str(domaine_competence_id)), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le domaine de compétenec " + str(domaine_competence_id) + " est invalide ") + return False, " Le domaine de compétenec " + str(domaine_competence_id) + " est invalide " + + tab_domaine_competence_ids.append(str(domaine_competence_id)) + + + + tab_inscrit_ids = [] + tab_inscrit_ids_work = str(diction['tab_inscrit_ids']).split(',') + for inscrit_id in tab_inscrit_ids_work: + if (inscrit_id): + if (MYSY_GV.dbname['inscription'].count_documents({'_id': ObjectId(str(inscrit_id)), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'inscription " + str(inscrit_id) + " est invalide ") + return False, " L'inscription " + str(inscrit_id) + " est invalide " + + tab_inscrit_ids.append(str(inscrit_id)) + + tab_groupe_inscription_id = list( + MYSY_GV.dbname["groupe_inscription_membre"].distinct( + "groupe_inscription_id", + { + "inscription_id": {'$in':tab_inscrit_ids}, + "partner_owner_recid": str(my_partner["recid"]), + "valide": "1", + "locked": "0" + } + ) + ) + + tab_groupe_inscription_id_ObjectId = [] + for tmp in tab_groupe_inscription_id : + if( tmp ): + tab_groupe_inscription_id_ObjectId.append(ObjectId(str(tmp))) + + + RetObject = [] + val_tmp = 0 + + query = {} + query['tab_grp_apprenant_ids._id'] = {'$in':tab_groupe_inscription_id_ObjectId} + query['partner_owner_recid'] = str(my_partner["recid"]) + query['valide'] = "1" + query['locked'] = "0" + + if (len(tab_domaine_competence_ids) > 0): + query['domaine_competence_id'] = {'$in': tab_domaine_competence_ids} + + #print(" ### query = ", query) + + for retval in MYSY_GV.dbname['session_formation_sequence'].find(query).sort("sequence_start", 1): + print(" retval === ", retval) + user = {} + user['id'] = str(val_tmp) + user['_id'] = str(retval['_id']) + val_tmp = val_tmp + 1 + + user['session_id'] = retval['session_id'] + user['type'] = retval['type'] + user['sequence_title'] = retval['sequence_title'] + user['sequence_start'] = retval['sequence_start'] + user['sequence_end'] = retval['sequence_end'] + user['time_in_hour'] = retval['time_in_hour'] + user['volume_theorique'] = retval['volume_theorique'] + + user['domaine_competence_id'] = retval['domaine_competence_id'] + domaine_competence_id_code = "" + + if( retval['domaine_competence_id'] ): + bc_data = MYSY_GV.dbname['domaine_competence_pedagogique'].find_one({'_id':ObjectId(str( retval['domaine_competence_id'])), + 'partner_owner_recid': str(my_partner['recid'])}, {'code':1}) + + if( bc_data and 'code' in bc_data.keys() ): + domaine_competence_id_code = bc_data['code'] + + user['domaine_competence_id_code'] = str(domaine_competence_id_code) + + user['obligatoire'] = retval['obligatoire'] + if( "tab_grp_apprenant_ids" in retval.keys() ): + user['tab_grp_apprenant_ids'] = retval['tab_grp_apprenant_ids'] + else: + user['tab_grp_apprenant_ids'] = [] + + 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 séquences de formation " + + +""" +Cette fonction créer les absence d'un inscrit avec une plage de date pour +pour une séquence donnée +Besoin : +pour une plage assez long, le système va aller chercher les sequences qui concerne +l'inscrit et créer des absences pour ces séquences +""" +def Create_Inscrit_Absence_By_Plage_Of_Date_OR_Sequence_Id(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'session_id', 'tab_inscrit_ids', 'start_date', 'end_date', 'sequence_id', 'justified', + 'comment'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ") + return False, " Les informations fournies sont incorrectes", + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', 'session_id', 'tab_inscrit_ids', 'start_date', 'end_date', 'sequence_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", + + + """ + Important : On prend soit la sequence, soit une plage de date, pas les deux + """ + if( ( len(diction['start_date']) > 0 or len(diction['end_date']) > 0) and len(diction['sequence_id']) > 0 ): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " Les données fournies sont incohérente. Vous devez fournir soit une plage de dates, ou une séquence ") + return False, " Les données fournies sont incohérente. Vous devez fournir soit une plage de dates, ou une séquence ", + + + option_absence = "" + if( len(diction['sequence_id']) > 0 ): + option_absence = "sequence_id" + elif ( len(diction['start_date']) > 0 and len(diction['end_date']) > 0 ): + option_absence = "plage" + + """ + 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 qu'il n'y a pas de chevauchement de date avec une autre sequence de la meme session. + date_debut_seq = "" + if ("start_date" in diction.keys()): + if diction['start_date']: + date_debut_seq = str(diction['start_date']) + local_status = mycommon.CheckisDate_Hours(date_debut_seq) + if (local_status is False): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La date de debut de séquence " + str( + date_debut_seq) + " n'est pas au format 'jj/mm/aaaa hh:mm' ") + return False, " La date de debut de séquence " + str( + date_debut_seq) + " n'est pas au format 'jj/mm/aaaa hh:mm'" + + date_fin_seq = "" + if ("end_date" in diction.keys()): + if diction['end_date']: + date_fin_seq = str(diction['end_date']) + local_status = mycommon.CheckisDate_Hours(date_fin_seq) + if (local_status is False): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La date de fin de séquence " + str( + date_fin_seq) + " n'est pas au format 'jj/mm/aaaa hh:mm' ") + return False, " La date de fin de séquence " + str( + date_fin_seq) + " n'est pas au format 'jj/mm/aaaa hh:mm'" + + if (date_debut_seq and date_fin_seq and + datetime.strptime(str(date_debut_seq), '%d/%m/%Y %H:%M') >= datetime.strptime(str(date_fin_seq), + '%d/%m/%Y %H:%M')): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " La date de fin de séquence " + str( + date_fin_seq) + " doit être postérieure à la date de début de séquence " + str( + date_debut_seq) + " ") + return False, " La date de fin de séquence " + str( + date_fin_seq) + " doit être postérieure à la date de début de séquence " + str(date_debut_seq) + " " + + + + + # Verifier la validité de la session + if (MYSY_GV.dbname['session_formation'].count_documents({'_id': ObjectId(str(diction['session_id'])), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " La session_id :" + str(diction['session_id']) + " est invalide ") + return False, " L'identifiant de la session :" + str(diction['session_id']) + " est invalide " + + tab_inscrit_ids = [] + tab_inscrit_ids_work = str(diction['tab_inscrit_ids']).split(',') + for inscrit_id in tab_inscrit_ids_work: + if (inscrit_id): + if (MYSY_GV.dbname['inscription'].count_documents({'_id': ObjectId(str(inscrit_id)), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'inscription " + str(inscrit_id) + " est invalide ") + return False, " L'inscription " + str(inscrit_id) + " est invalide " + + tab_inscrit_ids.append(str(inscrit_id)) + + tab_groupe_inscription_id = list( + MYSY_GV.dbname["groupe_inscription_membre"].distinct( + "groupe_inscription_id", + { + "inscription_id": {'$in':tab_inscrit_ids}, + "partner_owner_recid": str(my_partner["recid"]), + "valide": "1", + "locked": "0" + } + ) + ) + + tab_groupe_inscription_id_ObjectId = [] + for tmp in tab_groupe_inscription_id : + if( tmp ): + tab_groupe_inscription_id_ObjectId.append(ObjectId(str(tmp))) + + + print(" ## tab_groupe_inscription_id = ",tab_groupe_inscription_id) + print(" ## option_absence = ", option_absence) + + cpt = 0 + for inscrit in tab_inscrit_ids : + + inscrit_data = MYSY_GV.dbname['inscription'].find_one({'_id': ObjectId(str(inscrit)), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}, {'_id':1, 'email':1}) + + query = "" + if( option_absence == "sequence_id"): + + query = [{ + "$match": { + "session_id": str(diction['session_id']), + "partner_owner_recid": str(my_partner["recid"]), + "valide": "1", + "locked": "0", + "_id":ObjectId(str(diction['sequence_id'])) + } + }] + elif ( option_absence == "plage"): + query = [ + { + "$match": { + "session_id": str(diction['session_id']), + "partner_owner_recid": str(my_partner["recid"]), + "valide": "1", + "locked": "0", + "tab_grp_apprenant_ids._id": {'$in':tab_groupe_inscription_id_ObjectId} + } + }, + { + "$addFields": { + "sequence_start_date": { + "$dateFromString": { + "dateString": "$sequence_start", + "format": "%d/%m/%Y %H:%M" + } + }, + "sequence_end_date": { + "$dateFromString": { + "dateString": "$sequence_end", + "format": "%d/%m/%Y %H:%M" + } + } + } + }, + { + "$match": { + "sequence_start_date": { + "$gte": datetime.strptime(date_debut_seq, "%d/%m/%Y %H:%M") + }, + "sequence_end_date": { + "$lte": datetime.strptime(date_fin_seq, "%d/%m/%Y %H:%M") + } + } + }, + { + "$sort": { + "sequence_start_date": 1 + } + }, + { + "$project": { + "_id": 1, + "session_id": 1, + "type": 1, + "sequence_title": 1, + "sequence_start": 1, + "sequence_end": 1, + "sequence_start_date": 1, + "sequence_end_date": 1, + "time_in_hour": 1, + "domaine_competence_id": 1, + "ue_id": 1, + "tab_grp_apprenant_ids": 1 + } + } + ] + + print(" QRYYY = ",query) + for retval in MYSY_GV.dbname["session_formation_sequence"].aggregate(query) : + print(' CREATION ABSENCE SUR ', retval) + + absence_data_to_add = {} + absence_data_to_add['related_collection'] = "apprenant" + absence_data_to_add['related_collection_email'] = inscrit_data['email'] + absence_data_to_add['inscription_id'] = str(inscrit) + absence_data_to_add['event_title'] = "Abs : "+str(retval['sequence_title']) + + start_date = datetime.strptime(str(retval['sequence_start']), "%d/%m/%Y %H:%M") + absence_data_to_add['event_start'] = start_date.strftime("%Y-%m-%dT%H:%M:%S") + + end_date = datetime.strptime(str(retval['sequence_end']), "%d/%m/%Y %H:%M") + absence_data_to_add['event_end'] = end_date.strftime("%Y-%m-%dT%H:%M:%S") + + absence_data_to_add['domaine_competence_id'] = str(retval['domaine_competence_id']) + absence_data_to_add['ue_id'] = str(retval['ue_id']) + absence_data_to_add['time_in_hour'] = str(retval['time_in_hour']) + + absence_data_to_add['session_id'] = str(retval['session_id']) + absence_data_to_add['event_type'] = "absence" + + if("justified" in diction.keys() and diction['justified'] == "1"): + absence_data_to_add['justified'] = "true" + else: + absence_data_to_add['justified'] = "false" + + if ("comment" in diction.keys() ): + absence_data_to_add['comment'] = str(diction['comment']) + else: + absence_data_to_add['justified'] = "" + + absence_data_to_add['partner_owner_recid'] = str(my_partner['recid']) + absence_data_to_add['valide'] = "1" + absence_data_to_add['locked'] = "0" + + data_key = {} + data_key['related_collection'] = "inscription" + data_key['event_type'] = "absence" + data_key['event_start'] = absence_data_to_add['event_start'] + data_key['event_end'] = absence_data_to_add['event_end'] + data_key['session_id'] = absence_data_to_add['session_id'] + data_key['domaine_competence_id'] = absence_data_to_add['domaine_competence_id'] + data_key['ue_id'] = absence_data_to_add['ue_id'] + + + ret_val = MYSY_GV.dbname['agenda'].find_one_and_update( + data_key, + {"$set": absence_data_to_add}, + upsert=True, + return_document=ReturnDocument.AFTER + ) + + cpt = cpt +1 + + + return True, str(cpt) +" absence (s) créée(s)" + + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible de créer la ou les absences " + + +""" +Cette fonction retourn le pourcentage d'absence par BC pour un inscrit, par rapport un domaine de compétence donné +""" +def Get_Inscrit_Absence_Pourcentage_By_BC_For_Given_Session(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'session_id', 'tab_inscrit_ids', 'tab_domaine_competence_ids'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ") + return False, " Les informations fournies sont incorrectes", + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', 'session_id', 'tab_inscrit_ids'] + 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 la session + if (MYSY_GV.dbname['session_formation'].count_documents({'_id': ObjectId(str(diction['session_id'])), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " La session_id :" + str(diction['session_id']) + " est invalide ") + return False, " L'identifiant de la session :" + str(diction['session_id']) + " est invalide " + + filt_domaine_competence = {} + tab_domaine_competence_ids = [] + if( "tab_domaine_competence_ids" in diction.keys() and diction['tab_domaine_competence_ids']): + tab_domaine_competence_ids_work = str(diction['tab_domaine_competence_ids']).split(',') + for domaine_competence_id in tab_domaine_competence_ids_work: + if (domaine_competence_id): + if (MYSY_GV.dbname['domaine_competence_pedagogique'].count_documents({'_id': ObjectId(str(domaine_competence_id)), + 'valide': '1', + 'nb_heure': { + '$exists': True, + '$ne': ""}, + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le domaine de compétenec " + str(domaine_competence_id) + " est invalide ") + return False, " Le domaine de compétenec " + str(domaine_competence_id) + " est invalide " + + tab_domaine_competence_ids.append(str(domaine_competence_id)) + + + + tab_inscrit_ids = [] + tab_inscrit_ids_work = str(diction['tab_inscrit_ids']).split(',') + for inscrit_id in tab_inscrit_ids_work: + if (inscrit_id): + if (MYSY_GV.dbname['inscription'].count_documents({'_id': ObjectId(str(inscrit_id)), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'inscription " + str(inscrit_id) + " est invalide ") + return False, " L'inscription " + str(inscrit_id) + " est invalide " + + tab_inscrit_ids.append(str(inscrit_id)) + + RetObject = [] + + for my_inscrit in tab_inscrit_ids : + node_inscrit = {} + node_inscrit['inscription_id'] = str(my_inscrit) + node_inscrit['tab_absence'] = [] + for my_domaine_competence_id in tab_domaine_competence_ids : + node_absence = {} + node_absence['domaine_competence_id'] = str(my_domaine_competence_id) + """ + Recuprer le volume horaire du domaine de compétence + """ + my_domaine_competence_total_heure = 0 + my_domaine_competence_seuil_absence = -1 + + my_domaine_competence_id_data = MYSY_GV.dbname['domaine_competence_pedagogique'].find_one( + {'_id': ObjectId(str(my_domaine_competence_id)), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}, {'nb_heure':1, 'code':1, 'seuil_absence':1}) + + if( my_domaine_competence_id_data and "nb_heure" in my_domaine_competence_id_data.keys() and my_domaine_competence_id_data['nb_heure']): + my_domaine_competence_total_heure = mycommon.tryFloat(my_domaine_competence_id_data['nb_heure']) + + if( my_domaine_competence_total_heure <= 0 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " La configuration du volume horaire du BC" + str(my_domaine_competence_id) + " est invalide ") + return False, "La configuration du volume horaire du BC" + str(my_domaine_competence_id) + " est invalide " + + if (my_domaine_competence_id_data and "seuil_absence" in my_domaine_competence_id_data.keys() and + my_domaine_competence_id_data['seuil_absence']): + my_domaine_competence_seuil_absence = mycommon.tryFloat(my_domaine_competence_id_data['seuil_absence']) + + RetObject = [] + val_tmp = 0 + + query = {} + query['inscription_id'] = str(my_inscrit) + query['partner_owner_recid'] = str(my_partner["recid"]) + query['event_type'] = "absence" + query['valide'] = "1" + query['locked'] = "0" + query['domaine_competence_id'] = str(my_domaine_competence_id) + + #print(" ### query = ", query) + total_heure_absence = 0 + total_heure_absence_justifie = 0 + total_heure_absence_non_justifie = 0 + + for New_retVal in MYSY_GV.dbname['agenda'].find(query): + print(" retval === ", New_retVal) + a = datetime.fromisoformat(New_retVal['event_start']) + b = datetime.fromisoformat(New_retVal['event_end']) + total = (b - a) + + total_heure_absence = total_heure_absence + total.total_seconds() / 3600 + + if ("justified" in New_retVal.keys() and New_retVal['justified'] == "true"): + total_heure_absence_justifie = total_heure_absence_justifie + total.total_seconds() / 3600 + else: + total_heure_absence_non_justifie = total_heure_absence_non_justifie + total.total_seconds() / 3600 + + total_heure_absence = mycommon.tryFloat(round(total_heure_absence, 2)) + total_heure_absence_justifie = mycommon.tryFloat(round(total_heure_absence_justifie, 2)) + total_heure_absence_non_justifie = mycommon.tryFloat(round(total_heure_absence_non_justifie, 2)) + + + + print(" DOMAINE COMPETENCE ==== ", my_domaine_competence_id_data['code']) + print(" \t## my_domaine_competence_total_heure = ", my_domaine_competence_total_heure) + print(" \t## total_heure_absence = ", total_heure_absence) + print(" \t## total_heure_absence_justifie = ", total_heure_absence_justifie) + print(" \t## total_heure_absence_non_justifie = ", total_heure_absence_non_justifie) + + pourcentage_absence_non_justifed = 100 + if( my_domaine_competence_total_heure > 0 ): + pourcentage = (total_heure_absence_non_justifie / my_domaine_competence_total_heure)*100 + pourcentage_absence_non_justifed = mycommon.tryFloat( round(pourcentage, 2)) + + print(" \t## pourcentage_absence_non_justifed = ", pourcentage_absence_non_justifed) + + + if( my_domaine_competence_seuil_absence > 0 and my_domaine_competence_seuil_absence < pourcentage_absence_non_justifed ): + print(" \t## pourcentage_absence_non_justifed DEPACE LE POURCENTAGE AUTORISE QUI EST DE ", my_domaine_competence_seuil_absence) + node_absence['absence_deplace_seuil'] = "1" + else: + node_absence['absence_deplace_seuil'] = "" + + + node_absence['domaine_competence_total_heure'] = str(my_domaine_competence_total_heure) + node_absence['domaine_competence_seuil_absence'] = str(my_domaine_competence_seuil_absence) + node_absence['total_heure_absence'] = str(total_heure_absence) + node_absence['total_heure_absence_non_justifie'] = str(total_heure_absence_non_justifie) + node_absence['pourcentage_absence_non_justifed'] = str(pourcentage_absence_non_justifed) + node_inscrit['tab_absence'].append(node_absence) + + RetObject.append(mycommon.JSONEncoder().encode(node_inscrit)) + + 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 calculer les pourcentage d'absence " + + +""" +fonction interne identique à la précedente : Get_Inscrit_Absence_Pourcentage_By_BC_For_Given_Session + """ +def Internal_Get_Inscrit_Absence_Pourcentage_By_BC_For_Given_Session(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', 'session_id', 'tab_inscrit_ids', 'tab_domaine_competence_ids'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ") + return False, " Les informations fournies sont incorrectes", + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', 'session_id', 'tab_inscrit_ids'] + 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 la session + if (MYSY_GV.dbname['session_formation'].count_documents({'_id': ObjectId(str(diction['session_id'])), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " La session_id :" + str(diction['session_id']) + " est invalide ") + return False, " L'identifiant de la session :" + str(diction['session_id']) + " est invalide " + + filt_domaine_competence = {} + tab_domaine_competence_ids = [] + if( "tab_domaine_competence_ids" in diction.keys() and diction['tab_domaine_competence_ids']): + tab_domaine_competence_ids_work = str(diction['tab_domaine_competence_ids']).split(',') + for domaine_competence_id in tab_domaine_competence_ids_work: + if (domaine_competence_id): + if (MYSY_GV.dbname['domaine_competence_pedagogique'].count_documents({'_id': ObjectId(str(domaine_competence_id)), + 'valide': '1', + 'nb_heure': { + '$exists': True, + '$ne': ""}, + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le domaine de compétenec " + str(domaine_competence_id) + " est invalide ") + return False, " Le domaine de compétenec " + str(domaine_competence_id) + " est invalide " + + tab_domaine_competence_ids.append(str(domaine_competence_id)) + + + + tab_inscrit_ids = [] + tab_inscrit_ids_work = str(diction['tab_inscrit_ids']).split(',') + for inscrit_id in tab_inscrit_ids_work: + if (inscrit_id): + if (MYSY_GV.dbname['inscription'].count_documents({'_id': ObjectId(str(inscrit_id)), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}) != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'inscription " + str(inscrit_id) + " est invalide ") + return False, " L'inscription " + str(inscrit_id) + " est invalide " + + tab_inscrit_ids.append(str(inscrit_id)) + + RetObject = [] + + for my_inscrit in tab_inscrit_ids : + node_inscrit = {} + node_inscrit['inscription_id'] = str(my_inscrit) + node_inscrit['tab_absence'] = [] + for my_domaine_competence_id in tab_domaine_competence_ids : + node_absence = {} + node_absence['domaine_competence_id'] = str(my_domaine_competence_id) + """ + Recuprer le volume horaire du domaine de compétence + """ + my_domaine_competence_total_heure = 0 + my_domaine_competence_seuil_absence = -1 + + my_domaine_competence_id_data = MYSY_GV.dbname['domaine_competence_pedagogique'].find_one( + {'_id': ObjectId(str(my_domaine_competence_id)), + 'valide': '1', + 'partner_owner_recid': str( + my_partner['recid'])}, {'nb_heure':1, 'code':1, 'seuil_absence':1}) + + if( my_domaine_competence_id_data and "nb_heure" in my_domaine_competence_id_data.keys() and my_domaine_competence_id_data['nb_heure']): + my_domaine_competence_total_heure = mycommon.tryFloat(my_domaine_competence_id_data['nb_heure']) + + if( my_domaine_competence_total_heure <= 0 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " La configuration du volume horaire du BC" + str(my_domaine_competence_id) + " est invalide ") + return False, "La configuration du volume horaire du BC" + str(my_domaine_competence_id) + " est invalide " + + if (my_domaine_competence_id_data and "seuil_absence" in my_domaine_competence_id_data.keys() and + my_domaine_competence_id_data['seuil_absence']): + my_domaine_competence_seuil_absence = mycommon.tryFloat(my_domaine_competence_id_data['seuil_absence']) + + RetObject = [] + val_tmp = 0 + + query = {} + query['inscription_id'] = str(my_inscrit) + query['partner_owner_recid'] = str(my_partner["recid"]) + query['event_type'] = "absence" + query['valide'] = "1" + query['locked'] = "0" + query['domaine_competence_id'] = str(my_domaine_competence_id) + + #print(" ### query = ", query) + total_heure_absence = 0 + total_heure_absence_justifie = 0 + total_heure_absence_non_justifie = 0 + + for New_retVal in MYSY_GV.dbname['agenda'].find(query): + print(" retval === ", New_retVal) + a = datetime.fromisoformat(New_retVal['event_start']) + b = datetime.fromisoformat(New_retVal['event_end']) + total = (b - a) + + total_heure_absence = total_heure_absence + total.total_seconds() / 3600 + + if ("justified" in New_retVal.keys() and New_retVal['justified'] == "true"): + total_heure_absence_justifie = total_heure_absence_justifie + total.total_seconds() / 3600 + else: + total_heure_absence_non_justifie = total_heure_absence_non_justifie + total.total_seconds() / 3600 + + total_heure_absence = mycommon.tryFloat(round(total_heure_absence, 2)) + total_heure_absence_justifie = mycommon.tryFloat(round(total_heure_absence_justifie, 2)) + total_heure_absence_non_justifie = mycommon.tryFloat(round(total_heure_absence_non_justifie, 2)) + + + + print(" DOMAINE COMPETENCE ==== ", my_domaine_competence_id_data['code']) + print(" \t## my_domaine_competence_total_heure = ", my_domaine_competence_total_heure) + print(" \t## total_heure_absence = ", total_heure_absence) + print(" \t## total_heure_absence_justifie = ", total_heure_absence_justifie) + print(" \t## total_heure_absence_non_justifie = ", total_heure_absence_non_justifie) + + pourcentage_absence_non_justifed = 100 + if( my_domaine_competence_total_heure > 0 ): + pourcentage = (total_heure_absence_non_justifie / my_domaine_competence_total_heure)*100 + pourcentage_absence_non_justifed = mycommon.tryFloat( round(pourcentage, 2)) + + print(" \t## pourcentage_absence_non_justifed = ", pourcentage_absence_non_justifed) + + + if( my_domaine_competence_seuil_absence > 0 and my_domaine_competence_seuil_absence < pourcentage_absence_non_justifed ): + print(" \t## pourcentage_absence_non_justifed DEPACE LE POURCENTAGE AUTORISE QUI EST DE ", my_domaine_competence_seuil_absence) + node_absence['absence_deplace_seuil'] = "1" + else: + node_absence['absence_deplace_seuil'] = "" + + + node_absence['domaine_competence_total_heure'] = str(my_domaine_competence_total_heure) + node_absence['domaine_competence_seuil_absence'] = str(my_domaine_competence_seuil_absence) + node_absence['total_heure_absence'] = str(total_heure_absence) + node_absence['total_heure_absence_non_justifie'] = str(total_heure_absence_non_justifie) + node_absence['pourcentage_absence_non_justifed'] = str(pourcentage_absence_non_justifed) + node_inscrit['tab_absence'].append(node_absence) + + RetObject.append(node_inscrit) + + 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, " Internal Impossible de calculer les pourcentage d'absence " + diff --git a/Log/log_file.log b/Log/log_file.log index 42b76b6..291a3b9 100644 --- a/Log/log_file.log +++ b/Log/log_file.log @@ -158189,3 +158189,3185 @@ INFO:root:2026-06-26 18:16:20.839317 : ++ FLASK PORT 5001 ++ INFO:root:2026-06-26 18:16:20.839317 : ++ LMS_BAS_URL mysy-hosting.com/ ++ WARNING:werkzeug: * Debugger is active! INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\partner_client.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-26 18:27:28.089012 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-26 18:27:28.089012 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-26 18:27:28.089012 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-26 18:27:28.089012 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-26 18:27:28.089012 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\partner_client.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-26 18:30:45.347164 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-26 18:30:45.348170 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-26 18:30:45.348170 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-26 18:30:45.348170 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-26 18:30:45.348170 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 07:59:30.061651 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 07:59:30.062651 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 07:59:30.062651 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 07:59:30.062651 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 07:59:30.062651 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +INFO:werkzeug:WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. + * Running on http://localhost:5001 +INFO:werkzeug:Press CTRL+C to quit +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:00:44.057230 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:00:44.057230 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:00:44.057230 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:00:44.058230 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:00:44.058230 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 08:00:44.485216 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:00:44.487297 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:00:44.499328 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:00:44.501325 : Le token partner est vide +INFO:root:2026-06-27 08:00:44.510382 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:00:44.513950 : La session de connexion n'est pas valide +INFO:root:2026-06-27 08:00:44.517071 : La session de connexion n'est pas valide +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:00:44] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:00:44.525032 : La session de connexion n'est pas valide +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:00:44] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:00:48.407337 : getRecodedImage - Impossible de récupérer le recid du user +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:00:48] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:00:48.410350 : get_partner_account - La session de connexion n'est pas valide +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:00:48] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:01:49.608436 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:49] "POST /myclass/api/partner_login/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:01:49.654529 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:01:49.659531 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:01:49.664541 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:49] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:01:49.672537 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:49] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:49] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:01:49.696049 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:49] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:01:49.711057 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:01:49.715099 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:01:49.719724 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:01:49.723145 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:49] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:01:49.730145 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:49] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:49] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:01:49.741383 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:01:49.745363 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:49] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:01:49.755876 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:49] "POST /myclass/api/Get_List_Ressource_Materielle_no_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:01:49.762392 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:49] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:01:49.776385 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:01:49.779413 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:49] "POST /myclass/api/Get_List_Partner_Or_Default_session_step/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:01:49.788386 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:49] "POST /myclass/api/GetPartnerAttestation_Certificat/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:01:49.798393 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:01:49.811395 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:49] "POST /myclass/api/Is_Partnair_Has_Digital_Signature/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:49] "POST /myclass/api/Get_List_Site_Formation_with_filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:50] "POST /myclass/api/Get_List_Ressource_Humaine_no_filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:51] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:51] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:01:53] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:03:40.309546 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:03:40] "POST /myclass/api/Update_Context_Partner_Account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:03:40.349572 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:03:40.351572 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:03:40.356135 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:03:40.362094 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:03:40.368095 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:03:40] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:03:40.376100 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:03:40.377102 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:03:40] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:03:40] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:03:40.387619 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:03:40] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:03:40] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:03:41] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:03:41] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:03:42] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:04:05.186197 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:04:05.191217 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:04:05.195207 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:04:05.199205 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:04:05.209306 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:04:05] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:04:05] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:04:05] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:04:05.218204 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:04:05.223203 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:04:05.228209 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:04:05] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:04:05] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:04:05] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:04:06] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:04:07] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:04:15.845274 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:04:17] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:06:08.435184 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:06:08.435184 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:06:08.435184 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:06:08.435184 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:06:08.435184 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:08:33.883347 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:08:33.883347 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:08:33.884348 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:08:33.884348 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:08:33.884348 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:09:49.963066 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:09:49.964065 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:09:49.964065 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:09:49.964065 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:09:49.964065 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 08:10:23.868464 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:10:23.871465 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:10:23.874968 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:10:23.876973 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:23] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:23] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:23] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:10:23.899005 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:10:23.900982 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:10:23.908629 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:10:23.917143 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:23] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:10:23.920161 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:23] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:23] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:10:23.926141 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:23] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:10:23.931166 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:10:23.935142 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:10:23.942141 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:23] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:23] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:24] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:24] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:10:25.265887 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:25] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:26] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:10:44.388281 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:10:44.390283 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:44] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:10:44.393794 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:10:44.396850 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:44] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:44] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:10:44.417232 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:44] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:10:44.424205 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:10:44.427207 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:10:44.430208 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:10:44.435205 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:44] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:10:44.441716 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:44] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:10:44.446716 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:44] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:10:44.456722 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:10:44.460722 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:44] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:44] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:45] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:45] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:10:45.585503 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:46] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:10:47] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:12:33.322947 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:12:33.322947 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:12:33.324461 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:12:33.324461 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:12:33.324461 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:13:19.728565 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:13:19.728565 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:13:19.728565 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:13:19.728565 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:13:19.728565 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:14:16.508674 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:14:16.508674 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:14:16.508674 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:14:16.508674 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:14:16.509674 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:16:24.869489 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:16:24.869489 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:16:24.869489 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:16:24.870498 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:16:24.870498 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:18:14.716648 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:18:14.716648 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:18:14.716648 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:18:14.716648 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:18:14.716648 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:19:05.958979 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:19:05.958979 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:19:05.958979 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:19:05.958979 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:19:05.958979 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:19:32.827186 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:19:32.828186 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:19:32.828186 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:19:32.828186 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:19:32.828186 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:20:50.680414 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:20:50.681408 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:20:50.681408 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:20:50.681408 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:20:50.681408 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:21:35.075246 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:21:35.075246 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:21:35.075246 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:21:35.075246 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:21:35.075246 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:22:30.047730 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:22:30.047730 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:22:30.047730 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:22:30.047730 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:22:30.047730 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:23:42.114841 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:23:42.114841 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:23:42.114841 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:23:42.115840 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:23:42.115840 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:27:41.976171 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:27:41.976171 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:27:41.976171 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:27:41.976171 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:27:41.976171 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +INFO:werkzeug:WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. + * Running on http://localhost:5001 +INFO:werkzeug:Press CTRL+C to quit +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:28:00.535411 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:28:00.535411 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:28:00.535411 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:28:00.535411 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:28:00.535411 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\main.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:29:26.821391 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:29:26.822402 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:29:26.822402 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:29:26.822402 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:29:26.822402 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 08:29:27.724748 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:29:27.749277 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:29:27.784876 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:29:27.790876 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:29:27.797876 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:29:27.809875 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:28] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:28] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:29:28.243558 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:29:28.245557 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:28] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:28] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:29] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:33] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:34] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:36] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:29:40.206945 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:40] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:29:40.226948 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:29:40.233486 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:29:40.253702 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:40] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:29:40.267735 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:40] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:29:40.269713 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:40] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:29:40.281069 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:40] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:29:40.290706 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:40] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:29:40.303699 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:40] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:29:40.320830 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:29:40.368387 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:29:40.404514 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:29:40.438869 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:40] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:40] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:41] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:41] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:43] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:29:44.154876 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:29:45] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:30:31.235750 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:30:31.237751 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:30:31.239749 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:30:31.242755 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:30:31] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:30:31] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:30:31.246794 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:30:31.248756 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:30:31.251753 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:30:31] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:30:31.255757 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:30:31] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:30:31] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:30:32] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:30:32] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:30:33] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:30:45.305058 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:30:48] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:31:33.082177 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:31:33.082177 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:31:33.082177 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:31:33.082177 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:31:33.082177 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 08:31:33.237550 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:31:33.239572 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:31:33.241552 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:31:33.246083 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:31:33] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:31:33.251085 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:31:33.255091 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:31:33.259086 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:31:33] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:31:33] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:31:33] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:31:33] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:31:33.280165 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:31:33.286171 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:31:33] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:31:33.289168 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:31:33] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:31:33.294239 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:31:33.297758 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:31:33.302285 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:31:33] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:31:33] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:31:34] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:31:34] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:31:34] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:31:40.239423 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:31:41] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:33:39.340112 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:33:39.340112 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:33:39.340112 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:33:39.340112 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:33:39.340112 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:34:43.523093 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:34:43.524105 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:34:43.524105 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:34:43.524105 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:34:43.524105 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 08:34:43.712576 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:34:43.716573 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:34:43.720574 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:34:43.725005 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:34:43.729522 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:34:43] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:34:43.735536 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:34:43.740538 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:34:43] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:34:43.764549 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:34:43] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:34:43] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:34:43] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:34:43.782096 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:34:43] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:34:43.786632 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:34:43.791629 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:34:43] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:34:43.796631 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:34:43.801173 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:34:43.809174 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:34:43] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:34:43] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:34:45] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:34:45] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:34:45] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:34:46] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:36:25.759620 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:36:25.759620 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:36:25.760620 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:36:25.760620 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:36:25.760620 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 08:36:26.115365 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:36:26.120362 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:36:26.124366 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:36:26.130901 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:36:26.137899 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:36:26.146426 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:36:26] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:36:26.166017 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:36:26] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:36:26.186074 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:36:26] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:36:26.200085 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:36:26] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:36:26] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:36:26.213613 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:36:26.224139 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:36:26.239145 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:36:26] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:36:26] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:36:26.275720 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:36:26] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:36:26] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:36:28.470422 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:36:32] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:36:32] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:36:33] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:36:39] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:37:22.512806 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:37:22.512806 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:37:22.512806 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:37:22.512806 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:37:22.512806 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 08:37:30.755480 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:37:30.760479 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:37:30.764480 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:37:30.768479 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:37:30] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:37:30] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:37:30] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:37:30.883578 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:37:30.899578 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:37:30.912584 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:37:30.918650 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:37:30] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:37:30.926165 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:37:30.944698 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:37:30.950212 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:37:30] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:37:30] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:37:30.981211 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:37:30.986211 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:37:31] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:37:31] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:37:31] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:37:32] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:37:32] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:37:36] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:37:38.175462 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:37:42.590961 : Get_Statgaire_List_Partner_with_filter_uptimized -'myclass_collection' - ERRORRRR AT Line : 11265 +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:37:42] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:38:35.639981 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:38:35.639981 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:38:35.639981 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:38:35.639981 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:38:35.639981 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 08:38:42.395856 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:38:42.397858 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:38:42.401857 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:38:42.407857 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:38:42] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:38:42] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:38:42.425022 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:38:42.428021 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:38:42.439113 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:38:42] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:38:42] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:38:42.446135 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:38:42.451136 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:root:2026-06-27 08:38:42.453137 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:38:42] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:38:42.457166 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:38:42] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:38:42] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:38:42.467174 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:38:42.472687 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:38:42] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:38:42] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:38:43] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:38:43] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:38:44] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:38:55.656273 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:39:00.100095 : Get_Statgaire_List_Partner_with_filter_uptimized -name 'count_session' is not defined - ERRORRRR AT Line : 11324 +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:39:00] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:40:00.695960 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:40:00.695960 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:40:00.696962 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:40:00.696962 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:40:00.696962 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 08:40:01.101115 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:40:01.115642 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:40:01.166688 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:40:01.204684 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:40:01.253276 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:40:01.300343 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:40:01.312345 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:40:01] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:40:02] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:40:02] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:40:02.648141 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:40:02] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:40:02.660494 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:40:02.675022 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:40:02] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:40:02.683558 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:40:02] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:40:02] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:40:02.690562 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:40:02.694560 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:40:02.700103 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:40:02] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:40:02] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:40:04] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:40:05] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:40:06] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:40:08.992241 : Get_Statgaire_List_Partner_with_filter_uptimized -'class_id' - ERRORRRR AT Line : 11261 +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:40:08] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:40:58.086038 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:40:58.086038 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:40:58.086038 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:40:58.086038 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:40:58.086038 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:42:45.277650 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:42:45.277650 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:42:45.277650 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:42:45.277650 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:42:45.277650 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:44:18.375940 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:44:18.375940 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:44:18.375940 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:44:18.375940 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:44:18.375940 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 08:44:18.468641 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:44:18.470640 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:44:18.473640 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:44:18.473640 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:44:18] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:44:18.478640 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:44:18.479640 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:44:18.482146 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:44:18] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:44:18] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:44:18.493272 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:44:18] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:44:18.496270 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:44:18] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:44:18.501270 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:44:18.504781 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:44:18.507781 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:44:18] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:44:18.511781 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:44:18] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:44:18] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:44:18] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:44:19] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:44:19] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:44:19] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:44:21.627306 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:44:22] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:45:58.361539 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:45:58.362545 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:45:58.362545 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:45:58.363548 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:45:58.363548 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 08:45:58.710068 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:45:58.712061 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:45:58.718059 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:45:58.726974 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:45:58] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:45:58.741094 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:45:58.752742 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:45:58] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:45:58.780881 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:45:58.784879 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:45:58] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:45:58] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:45:58.805445 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:45:58.805445 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:45:58] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:45:58] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:45:58] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:45:58.818434 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:45:58.832450 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:45:58.834490 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:45:58] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:45:58] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:45:59] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:00] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:02] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:18.983815 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:19] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:24.907514 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:46:24.909582 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:46:24.912586 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:46:24.917586 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:24] "POST /myclass/api/Get_List_Unite_Enseignement_Of_Given_Class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:24] "POST /myclass/api/Get_List_Class_Evaluation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:27.257983 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:27] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:27.290506 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:27] "POST /myclass/api/GetAttendeeDetail_perSession/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:27.317247 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:27] "POST /myclass/api/getRecodedStagiaireImage_from_front/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:27.351144 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:46:27.381653 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:27] "POST /myclass/api/GetSessionFormation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:27.425860 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:46:27.428369 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:27] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:27] "POST /myclass/api/Get_List_Jury_Soutenenace_With_Filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:27] "POST /myclass/api/Get_List_Participant_Notes/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:27.502943 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:27] "POST /myclass/api/Get_Inscrit_List_Tuteurs/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:27.543469 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:27] "POST /myclass/api/Get_Inscrit_List_Groupe/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:28.547816 : Get_Inscrit_List_EU Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:28] "POST /myclass/api/Get_Inscrit_List_EU/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:28.552812 : Get_Inscrit_List_EU_Type_Evaluation Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:28] "POST /myclass/api/Get_Inscrit_List_EU_Type_Evaluation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:40.893767 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:41] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:48.906078 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:48] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:52.840016 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:46:52.844019 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:46:52.849016 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:46:52.852015 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:46:52.867021 : Get_Inscrit_List_EU Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:52] "POST /myclass/api/Get_Inscrit_List_EU/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:52.869021 : Get_Inscrit_List_EU_Type_Evaluation Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:52] "POST /myclass/api/Get_Inscrit_List_EU_Type_Evaluation/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:52] "POST /myclass/api/Get_List_Unite_Enseignement_Of_Given_Class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:52] "POST /myclass/api/Get_List_Class_Evaluation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:53.756163 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:46:53.760670 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:46:53.763667 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:46:53.766684 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:46:53.772684 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:53] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:53] "POST /myclass/api/getRecodedStagiaireImage_from_front/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:53.782337 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:53] "POST /myclass/api/GetAttendeeDetail_perSession/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:53.788338 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:53] "POST /myclass/api/GetSessionFormation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:53.794897 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:53] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:46:53.801878 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:53] "POST /myclass/api/Get_List_Jury_Soutenenace_With_Filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:53] "POST /myclass/api/Get_Inscrit_List_Tuteurs/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:53] "POST /myclass/api/Get_Inscrit_List_Groupe/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:46:53] "POST /myclass/api/Get_List_Participant_Notes/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:47:03.100177 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:47:03.102686 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:47:03.105223 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:03] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:47:03.108224 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:03] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:03] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:47:03.131148 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:47:03.134272 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:47:03.134272 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:03] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:47:03.138791 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:47:03.142790 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:03] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:03] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:03] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:47:03.154382 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:47:03.158357 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:47:03.161362 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:47:03.167869 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:03] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:03] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:03] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:03] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:47:04.433703 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:04] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:04] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:47:40.059468 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:47:40.060469 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:47:40.062979 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:47:40.063979 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:47:40.067978 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:40] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:47:40.069979 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:47:40.072978 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:40] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:40] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:47:40.078548 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:40] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:40] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:40] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:40] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:47:41] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 08:48:50.596189 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 08:48:50.596189 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 08:48:50.596189 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 08:48:50.596189 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 08:48:50.596189 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 08:48:50.737756 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:48:51] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:48:53.209032 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:48:53.211028 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:48:53] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:48:53.215016 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:48:53.217020 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:48:53] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:48:53] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:48:53.235902 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:48:53] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:48:53.247129 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:48:53.250129 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:48:53.253131 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:48:53.256484 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:48:53] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:48:53.260662 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:48:53] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:48:53.263200 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:48:53.265196 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:48:53] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:48:53.267199 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:48:53] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:48:53] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:48:53] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:48:54] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:48:54] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:48:58.761972 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:48:59] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:08.801420 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:08] "POST /myclass/api/Update_Context_Partner_Account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:08.840991 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:08.842992 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:08.847994 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:08.852994 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:08.858507 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:08] "POST /myclass/api/Get_Partner_All_Class_Few_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:08] "POST /myclass/api/Get_Partner_Session_Ftion_Reduice_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:08] "POST /myclass/api/Get_List_Site_Formation_with_filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:08] "POST /myclass/api/Get_List_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:08] "POST /myclass/api/Get_List_Ressource_Humaine_no_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:11.382369 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:11.384882 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:11.387890 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:11.392404 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:11.394403 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:11] "POST /myclass/api/Get_List_Admission_Setup/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:11.403410 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:11] "POST /myclass/api/Get_Given_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:11] "POST /myclass/api/Get_List_Admission_Setup_Etape/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:11] "POST /myclass/api/Get_List_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:11] "POST /myclass/api/Get_Partner_Session_Ftion_Reduice_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:11] "POST /myclass/api/Get_List_Admission_Setup_Document/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:12.716468 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:12] "POST /myclass/api/Get_List_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:14.329681 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:14.333260 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:14.337246 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:14] "POST /myclass/api/Get_List_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:14] "POST /myclass/api/Get_Inscrit_Admiss_Session_Recorded_Image_from_front/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:14] "POST /myclass/api/Get_Given_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:16.273371 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:16.276371 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:16] "POST /myclass/api/Get_List_Candidat_Document/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:16] "POST /myclass/api/Get_Pourcentage_Candidat_Document/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:30.045091 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:30.048110 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:30.051203 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:30.056203 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:30] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:30] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:30] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:30.074208 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:30] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:30.090756 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:30.093262 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:30.097268 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:30.102326 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:30.108327 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:30] "POST /myclass/api/Get_Partner_All_Class_Few_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:30] "POST /myclass/api/Get_List_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:30] "POST /myclass/api/Get_Partner_Session_Ftion_Reduice_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:30] "POST /myclass/api/Get_List_Site_Formation_with_filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:30] "POST /myclass/api/Get_List_Ressource_Humaine_no_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:38.667580 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:38] "POST /myclass/api/Update_Context_Partner_Account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:38.715123 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:38.718593 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:38.719592 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:38.721592 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:38.726592 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:38] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:38.735597 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:38.736598 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:38] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:38.753109 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:38] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:38] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:38] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:39] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:39] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:40] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:42.213167 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:42] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:44.778959 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:44.782963 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:44.785962 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:44.789960 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:44] "POST /myclass/api/Get_List_Class_Evaluation/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:44] "POST /myclass/api/Get_List_Unite_Enseignement_Of_Given_Class/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:45.714566 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:45.717763 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:45.722766 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:45.725762 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:45.733274 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:49:45.738271 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:45] "POST /myclass/api/GetAttendeeDetail_perSession/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:45.747857 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:45] "POST /myclass/api/getRecodedStagiaireImage_from_front/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:45] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:45] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:45.758449 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:45] "POST /myclass/api/GetSessionFormation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:45.764450 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:45] "POST /myclass/api/Get_List_Jury_Soutenenace_With_Filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:45] "POST /myclass/api/Get_Inscrit_List_Tuteurs/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:45] "POST /myclass/api/Get_Inscrit_List_Groupe/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:45] "POST /myclass/api/Get_List_Participant_Notes/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:46.956335 : Get_Inscrit_List_EU_Type_Evaluation Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:46] "POST /myclass/api/Get_Inscrit_List_EU_Type_Evaluation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:46.959335 : Get_Inscrit_List_EU Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:46] "POST /myclass/api/Get_Inscrit_List_EU/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:49.781105 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:49] "POST /myclass/api/Get_List_Survey_with_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:49:49.836659 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:49:49] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:50:36.342142 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:50:36.345679 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:50:36.349661 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:50:36] "POST /myclass/api/Get_List_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:50:36] "POST /myclass/api/Get_Inscrit_Admiss_Session_Recorded_Image_from_front/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:50:36] "POST /myclass/api/Get_Given_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:50:38.717441 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:50:38.720471 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:50:38] "POST /myclass/api/Get_List_Candidat_Document/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:50:38] "POST /myclass/api/Get_Pourcentage_Candidat_Document/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:50:50.126335 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:50:50] "GET /myclass/api/Get_Stored_Downloaded_File_From_Id/66R8NExLflHhvOvlO6pBeYsuEvOtSpIT-Q/697634543421382f036ae21c HTTP/1.1" 200 - +INFO:root:2026-06-27 08:52:40.924678 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:52:40.928683 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:52:40.931682 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:52:40.935678 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:52:40.947845 : Get_Inscrit_List_EU Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:40] "POST /myclass/api/Get_Inscrit_List_EU/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:52:40.953845 : Get_Inscrit_List_EU_Type_Evaluation Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:40] "POST /myclass/api/Get_Inscrit_List_EU_Type_Evaluation/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:40] "POST /myclass/api/Get_List_Unite_Enseignement_Of_Given_Class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:40] "POST /myclass/api/Get_List_Class_Evaluation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:52:42.020075 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:52:42.024075 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:52:42.028081 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:52:42.031081 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:52:42.038081 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:52:42.044595 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:42] "POST /myclass/api/GetAttendeeDetail_perSession/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:42] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:52:42.053331 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:52:42.057331 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:42] "POST /myclass/api/getRecodedStagiaireImage_from_front/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:42] "POST /myclass/api/GetSessionFormation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:52:42.067381 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:42] "POST /myclass/api/Get_Inscrit_List_Tuteurs/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:42] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:42] "POST /myclass/api/Get_List_Jury_Soutenenace_With_Filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:42] "POST /myclass/api/Get_Inscrit_List_Groupe/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:42] "POST /myclass/api/Get_List_Participant_Notes/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:52:44.301455 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:44] "POST /myclass/api/Get_List_Survey_with_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:52:44.354063 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:44] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:52:53.689823 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:52:53] "GET /myclass/api/Get_Stored_Downloaded_File_From_Id/66R8NExLflHhvOvlO6pBeYsuEvOtSpIT-Q/697634543421382f036ae21c HTTP/1.1" 304 - +INFO:root:2026-06-27 08:55:39.504487 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:55:39.508540 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:55:39.513517 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:55:39.517518 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:55:39.518517 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:55:39] "POST /myclass/api/Get_Partner_All_Class_Few_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:55:39] "POST /myclass/api/Get_List_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:55:39] "POST /myclass/api/Get_List_Site_Formation_with_filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:55:39] "POST /myclass/api/Get_Partner_Session_Ftion_Reduice_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:55:39] "POST /myclass/api/Get_List_Ressource_Humaine_no_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:56:48.684866 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:56:48] "POST /myclass/api/Add_Stagiaire_To_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:56:48.824400 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:56:48] "POST /myclass/api/Get_List_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:56:52.783385 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:56:52.786946 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:56:52.789939 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:56:52] "POST /myclass/api/Get_Given_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:56:52] "POST /myclass/api/Get_Inscrit_Admiss_Session_Recorded_Image_from_front/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:56:52] "POST /myclass/api/Get_List_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:57:15.779237 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:57:15] "POST /myclass/api/Update_Stagiaire_To_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:57:15.878006 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:57:15] "POST /myclass/api/Get_List_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:57:31.026972 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:57:31] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:57:31.092761 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:57:31.093761 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:57:31.094759 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:57:31] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:57:31] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:57:31] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:57:34.236176 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:57:34] "POST /myclass/api/Update_Stagiaire_Only_Status_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:57:34.258268 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:57:34] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:57:36.778419 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:57:36] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:58:39.269567 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:58:39] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 08:59:07.170583 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:59:07.174097 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 08:59:07.177098 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:59:07] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:59:07] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 08:59:07] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 09:00:39.426862 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 09:00:39.427889 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 09:00:39.427889 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 09:00:39.427889 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 09:00:39.427889 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 09:01:26.515128 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 09:01:26.515128 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 09:01:26.515128 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 09:01:26.515128 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 09:01:26.515128 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 09:01:52.169152 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 09:01:52.169152 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 09:01:52.169152 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 09:01:52.169152 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 09:01:52.169152 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 09:03:23.639035 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 09:03:23.639035 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 09:03:23.639035 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 09:03:23.639035 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 09:03:23.639035 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\apprenant_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 09:08:49.931484 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 09:08:49.931484 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 09:08:49.931484 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 09:08:49.931484 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 09:08:49.933092 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\apprenant_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 09:10:40.808463 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 09:10:40.808463 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 09:10:40.808463 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 09:10:40.808463 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 09:10:40.808463 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 09:11:03.364807 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 09:11:03.364807 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 09:11:03.364807 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 09:11:03.364807 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 09:11:03.364807 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 09:11:32.580047 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 09:11:32.580047 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 09:11:32.580047 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 09:11:32.580047 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 09:11:32.580047 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 14:39:39.927520 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:39:39.928520 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:39:39.932520 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:39:39.932520 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:39:39.933520 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:39] "POST /myclass/api/get_List_domaine_formation/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/Get_Suggested_Fr_Cities/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/Get_Suggested_Word/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/get_all_class/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.274977 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:39:40.276482 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:39:40.281000 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:39:40.281000 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/getRecodedClassImage_no_token/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.290509 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/getRecodedClassImage_no_token/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.296509 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSessionFormation_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.309022 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:39:40.310528 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSession_Cities_And_Distance_Formation_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSessionFormation_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/getRecodedClassImage_no_token/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSession_Cities_And_Distance_Formation_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.321535 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:39:40.325044 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:39:40.328044 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/getRecodedClassImage_no_token/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSessionFormation_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.334094 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSession_Cities_And_Distance_Formation_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.339119 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:39:40.345872 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSession_Cities_And_Distance_Formation_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.352057 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/getRecodedClassImage_no_token/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSessionFormation_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.358567 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSessionFormation_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.365078 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/getRecodedClassImage_no_token/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.371081 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSession_Cities_And_Distance_Formation_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.377747 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/getRecodedClassImage_no_token/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSessionFormation_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.383746 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSession_Cities_And_Distance_Formation_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.389247 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:39:40.392247 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSessionFormation_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/getRecodedClassImage_no_token/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.400332 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:39:40.402334 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSession_Cities_And_Distance_Formation_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.405842 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:39:40.411358 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/getRecodedClassImage_no_token/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.415360 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:39:40.422869 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSessionFormation_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/getRecodedClassImage_no_token/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSession_Cities_And_Distance_Formation_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSessionFormation_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.436269 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSession_Cities_And_Distance_Formation_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:39:40.447683 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSessionFormation_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:39:40] "POST /myclass/api/GetActiveSession_Cities_And_Distance_Formation_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:51:18.716215 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:51:18] "POST /myclass/api/Update_Context_Partner_Account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:51:18.782546 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:51:18.786086 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:51:18.789111 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:51:18.794604 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:51:18] "POST /myclass/api/Get_Competence_Domaine/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:51:18] "POST /myclass/api/Get_Client_Type_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:51:18.801599 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:51:18] "POST /myclass/api/Get_List_Partner_Basic_Setup/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:51:18] "POST /myclass/api/Get_List_Groupe_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:51:18.811261 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:51:18.813266 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:51:18] "POST /myclass/api/Get_List_Site_Formation_with_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:51:18.816267 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:51:18.823266 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:51:18] "POST /myclass/api/Get_List_Paiement_Condition/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:51:18] "POST /myclass/api/Get_CRM_List_Opportunite_Etape/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:51:18.831272 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:51:18] "POST /myclass/api/Get_Competence_no_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:51:18.839778 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:51:18] "POST /myclass/api/Get_List_Partner_Basic_Setup/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:51:18] "POST /myclass/api/Get_List_Partner_Basic_Setup/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:51:18] "POST /myclass/api/Get_List_base_document_automatic_setup/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:54:15.301851 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:54:15] "POST /myclass/api/Get_List_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:54:20.032856 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:54:20.036065 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:54:20.039171 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:54:20] "POST /myclass/api/Get_Given_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:54:20] "POST /myclass/api/Get_Inscrit_Admiss_Session_Recorded_Image_from_front/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:54:20] "POST /myclass/api/Get_List_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:54:22.431984 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:54:22.434985 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:54:22] "POST /myclass/api/Get_Pourcentage_Candidat_Document/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:54:22] "POST /myclass/api/Get_List_Candidat_Document/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:54:45.047122 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:54:45] "POST /myclass/api/Store_User_Downloaded_File/ HTTP/1.1" 200 - +INFO:root:2026-06-27 14:54:45.094682 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 14:54:45.095682 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:54:45] "POST /myclass/api/Get_Pourcentage_Candidat_Document/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 14:54:45] "POST /myclass/api/Get_List_Candidat_Document/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:00:11.561783 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:00:11] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:00:11.635498 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:00:11.641005 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:00:11.643004 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:00:11] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:00:11] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:00:11] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:02:11.462853 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:02:11.462853 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:02:11.462853 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:02:11.462853 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:02:11.462853 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:02:30.096049 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:02:30.096049 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:02:30.096049 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:02:30.096049 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:02:30.096049 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:04:14.845095 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:04:14.845095 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:04:14.845095 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:04:14.845095 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:04:14.845095 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:04:28.306097 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:04:28.306097 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:04:28.306097 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:04:28.306097 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:04:28.306097 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:05:07.664818 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:05:07.664818 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:05:07.664818 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:05:07.664818 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:05:07.664818 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 15:05:33.745541 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:05:33] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:05:47.757731 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:05:49.709790 : Candidat_Inscrire_To_Session Le type d'apprenant est invalide +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:05:49] "POST /myclass/api/Candidat_Inscrire_To_Session/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:11:46.564620 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:11:46.564620 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:11:46.564620 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:11:46.564620 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:11:46.564620 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +INFO:werkzeug:WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. + * Running on http://localhost:5001 +INFO:werkzeug:Press CTRL+C to quit +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:11:56.365717 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:11:56.365717 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:11:56.365717 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:11:56.365717 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:11:56.365717 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:14:01.222564 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:14:01.222564 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:14:01.223565 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:14:01.223565 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:14:01.223565 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 15:14:05.854278 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:14:05.857276 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:14:05.859276 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:14:05] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:14:05] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:14:05] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:17:34.707699 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:17:34.709713 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:17:34.714727 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:17:34] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:17:34] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:17:34] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:17:58.051771 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:17:58.055754 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:17:58.057755 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:17:58] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:17:58] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:17:58] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:18:25.406475 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:18:25.408475 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:18:25.410476 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:18:25] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:18:25] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:18:25] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:21:18.356312 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:21:18.356312 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:21:18.356312 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:21:18.356312 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:21:18.356312 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +INFO:werkzeug:WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. + * Running on http://localhost:5001 +INFO:werkzeug:Press CTRL+C to quit +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:21:25.792051 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:21:25.793051 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:21:25.793051 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:21:25.793051 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:21:25.793051 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 15:22:59.651831 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:22:59] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:23:14.685772 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:23:16.663440 : Internal_Apprenant_Inscrire_Session_Ret_id Le type d'apprenant est invalide +INFO:root:2026-06-27 15:23:16.664445 : Candidat_Inscrire_To_Session -not enough values to unpack (expected 3, got 2) - Line : 3279 +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:23:16] "POST /myclass/api/Candidat_Inscrire_To_Session/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\apprenant_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:25:25.500468 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:25:25.500468 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:25:25.500468 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:25:25.500468 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:25:25.501478 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 15:25:25.770141 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:25:25.773033 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:25:25.782031 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:25:25.788133 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:25:25.795028 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:25:25] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:25:25] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:25:25] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:25:25] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:25:25] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:26:23.322553 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:23] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:26:34.523774 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:35] "POST /myclass/api/Candidat_Inscrire_To_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:26:35.932405 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:35] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:26:46.223491 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:46] "POST /myclass/api/Update_Context_Partner_Account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:26:46.294061 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:26:46.297062 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:26:46.299062 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:26:46.304062 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:46] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:26:46.311062 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:26:46.314066 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:46] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:46] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:26:46.323068 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:26:46.327069 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:46] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:46] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:47] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:47] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:26:47.472281 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:47] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:48] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:26:58.711567 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:26:58.715570 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:26:58.719567 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:26:58.723566 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:58] "POST /myclass/api/Get_List_Unite_Enseignement_Of_Given_Class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:58] "POST /myclass/api/Get_List_Class_Evaluation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:26:59.982807 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:26:59.986357 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:26:59.992388 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:26:59] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:27:00.001034 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:00] "POST /myclass/api/GetAttendeeDetail_perSession/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:00] "POST /myclass/api/getRecodedStagiaireImage_from_front/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:27:00.007052 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:27:00.008540 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:27:00.015544 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:27:00.021546 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:27:00.028545 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:00] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:00] "POST /myclass/api/Get_List_Participant_Notes/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:00] "POST /myclass/api/GetSessionFormation/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:00] "POST /myclass/api/Get_Inscrit_List_Tuteurs/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:00] "POST /myclass/api/Get_Inscrit_List_Groupe/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:00] "POST /myclass/api/Get_List_Jury_Soutenenace_With_Filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:27:00.978246 : Get_Inscrit_List_EU_Type_Evaluation Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:00] "POST /myclass/api/Get_Inscrit_List_EU_Type_Evaluation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:27:00.980245 : Get_Inscrit_List_EU Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:00] "POST /myclass/api/Get_Inscrit_List_EU/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:27:16.011616 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:16] "POST /myclass/api/Get_List_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:27:19.131814 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:27:19.135798 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:27:19.139797 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:19] "POST /myclass/api/Get_Inscrit_Admiss_Session_Recorded_Image_from_front/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:19] "POST /myclass/api/Get_List_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:19] "POST /myclass/api/Get_Given_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:27:19.186224 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:27:19.188458 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:19] "POST /myclass/api/Get_Pourcentage_Candidat_Document/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:27:19] "POST /myclass/api/Get_List_Candidat_Document/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:29:36.189180 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:29:36.190179 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:29:36.195179 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:29:36.200200 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:29:36.203200 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:29:36] "POST /myclass/api/Get_List_Site_Formation_with_filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:29:36] "POST /myclass/api/Get_List_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:29:36] "POST /myclass/api/Get_Partner_Session_Ftion_Reduice_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:29:36] "POST /myclass/api/Get_Partner_All_Class_Few_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:29:36] "POST /myclass/api/Get_List_Ressource_Humaine_no_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:30:35.291340 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:35.293940 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:35.300953 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:35.305953 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:35] "POST /myclass/api/Get_Partner_All_Class_Few_Fields/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:30:35.314459 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:35] "POST /myclass/api/Get_List_Site_Formation_with_filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:35] "POST /myclass/api/Get_List_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:35] "POST /myclass/api/Get_Partner_Session_Ftion_Reduice_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:35] "POST /myclass/api/Get_List_Ressource_Humaine_no_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:30:37.417443 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:37.419976 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:37.423517 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:37.429513 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:37.430513 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:37.432512 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:37] "POST /myclass/api/Get_List_Admission_Setup/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:37] "POST /myclass/api/Get_Given_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:37] "POST /myclass/api/Get_Partner_Session_Ftion_Reduice_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:37] "POST /myclass/api/Get_List_Admission_Setup_Etape/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:37] "POST /myclass/api/Get_List_Admission_Setup_Document/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:37] "POST /myclass/api/Get_List_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:30:40.836581 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:40.839091 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:40.844627 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:40.847626 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:40.853627 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:40.864638 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:40] "POST /myclass/api/Get_List_Admission_Setup/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:40] "POST /myclass/api/Get_Given_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:40] "POST /myclass/api/Get_Partner_Session_Ftion_Reduice_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:40] "POST /myclass/api/Get_List_Admission_Setup_Etape/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:40] "POST /myclass/api/Get_List_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:40] "POST /myclass/api/Get_List_Admission_Setup_Document/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:30:42.129702 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:42] "POST /myclass/api/Get_List_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:30:44.791102 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:44.795644 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:44.799620 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:44.802618 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:44] "POST /myclass/api/Get_List_Admission_Setup/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:30:44.810625 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:44] "POST /myclass/api/Get_Given_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:30:44.815625 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:44] "POST /myclass/api/Get_Partner_Session_Ftion_Reduice_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:44] "POST /myclass/api/Get_List_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:44] "POST /myclass/api/Get_List_Admission_Setup_Document/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:44] "POST /myclass/api/Get_List_Admission_Setup_Etape/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:30:46.230025 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:46] "POST /myclass/api/Get_List_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:30:47.865890 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:47.869452 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:30:47.872451 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:47] "POST /myclass/api/Get_List_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:47] "POST /myclass/api/Get_Given_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:30:47] "POST /myclass/api/Get_Inscrit_Admiss_Session_Recorded_Image_from_front/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:31:13.473006 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:31:13] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:31:13.525258 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:31:13.526258 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:31:13.529257 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:31:13] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:31:13] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:31:13] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:34:37.847204 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:34:37] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:34:38.521600 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:34:38] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:34:38.559276 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:34:38.562793 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:34:38.565788 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:34:38] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:34:38] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:34:38] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:34:40.122836 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:34:40] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\apprenant_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:43:52.077238 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:43:52.077238 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:43:52.077238 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:43:52.077238 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:43:52.077238 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +INFO:werkzeug:WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. + * Running on http://localhost:5001 +INFO:werkzeug:Press CTRL+C to quit +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:44:04.969989 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:44:04.969989 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:44:04.970990 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:44:04.970990 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:44:04.970990 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 15:44:06.030030 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:44:06] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:44:18.542620 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:44:20.138266 : AddStagiairetoClass - Le champ 'piece_identite_type' n'est pas autorisé +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:44:20] "POST /myclass/api/Candidat_Inscrire_To_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:44:20.142266 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:44:20] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\apprenant_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:45:51.655795 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:45:51.656795 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:45:51.656795 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:45:51.656795 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:45:51.656795 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 15:46:00.143016 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:00] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:00.604432 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:00] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:00.641053 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:00.642051 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:00.645583 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:00] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:00] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:00] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:01.721307 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:01] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:12.359904 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:12] "POST /myclass/api/Candidat_Inscrire_To_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:12.968542 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:13] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:23.146380 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:23.149423 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:23.152576 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:23.155578 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:23] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:23] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:23] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:23.173092 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:23] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:23.182091 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:23.185597 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:23.189145 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:23] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:23.195195 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:23] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:23.200537 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:23] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:23.205536 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:23.209540 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:23.212537 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:23] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:23] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:23] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:23] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:24.495351 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:25] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:25] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:27.475890 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:27.478891 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:27.482891 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:27.486887 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:27] "POST /myclass/api/Get_List_Unite_Enseignement_Of_Given_Class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:27] "POST /myclass/api/Get_List_Class_Evaluation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:28.389730 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:28.391238 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:28.394243 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:28.401245 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:28.408246 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:28.414246 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:28] "POST /myclass/api/GetAttendeeDetail_perSession/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:28] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:28] "POST /myclass/api/getRecodedStagiaireImage_from_front/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:28] "POST /myclass/api/GetSessionFormation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:28.429817 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:28] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:28.434817 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:46:28.439818 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:28] "POST /myclass/api/Get_List_Participant_Notes/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:28] "POST /myclass/api/Get_List_Jury_Soutenenace_With_Filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:28] "POST /myclass/api/Get_Inscrit_List_Tuteurs/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:28] "POST /myclass/api/Get_Inscrit_List_Groupe/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:29.152193 : Get_Inscrit_List_EU Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:29] "POST /myclass/api/Get_Inscrit_List_EU/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:46:29.153716 : Get_Inscrit_List_EU_Type_Evaluation Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:46:29] "POST /myclass/api/Get_Inscrit_List_EU_Type_Evaluation/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\apprenant_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:47:35.451897 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:47:35.451897 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:47:35.451897 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:47:35.451897 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:47:35.451897 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\apprenant_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:48:22.877418 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:48:22.877418 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:48:22.877418 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:48:22.877418 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:48:22.877418 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\apprenant_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:51:02.893868 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:51:02.893868 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:51:02.893868 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:51:02.893868 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:51:02.894863 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\apprenant_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:51:34.617918 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:51:34.617918 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:51:34.618426 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:51:34.618426 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:51:34.618426 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\apprenant_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:54:54.498232 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:54:54.498232 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:54:54.498232 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:54:54.498232 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:54:54.498232 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\apprenant_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:55:33.228394 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:55:33.228394 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:55:33.228394 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:55:33.228394 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:55:33.228394 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 15:55:33.311636 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:55:33.313641 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:55:33.314649 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:55:33.316642 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:55:33.318641 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:55:33] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:55:33] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:55:33] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:55:33] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:55:33] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:55:47.473200 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:55:47] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:00.762536 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:00] "POST /myclass/api/Candidat_Inscrire_To_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:40.047127 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:40] "POST /myclass/api/Candidat_Inscrire_To_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:40.887804 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:40] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:45.892489 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:56:45.893461 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:56:45.896966 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:45] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:45.905489 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:45] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:45] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:45.918491 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:45] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:45.922489 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:56:45.923400 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:56:45.928494 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:56:45.930875 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:45] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:45.940393 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:45] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:45] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:45.944398 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:56:45.950399 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:56:45.957947 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:45] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:45] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:46] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:46.863892 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:46] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:47] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:48] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:49.015920 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:56:49.019933 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:56:49.020932 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:56:49.023931 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:49] "POST /myclass/api/Get_List_Unite_Enseignement_Of_Given_Class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:49] "POST /myclass/api/Get_List_Class_Evaluation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:50.118036 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:56:50.122046 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:56:50.123573 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:56:50.131589 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:50] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:50.140096 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:56:50.142129 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:50] "POST /myclass/api/GetAttendeeDetail_perSession/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:50] "POST /myclass/api/getRecodedStagiaireImage_from_front/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:50.155099 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:56:50.158099 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:50] "POST /myclass/api/Get_List_Participant_Notes/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:50] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:50] "POST /myclass/api/Get_Inscrit_List_Tuteurs/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:50] "POST /myclass/api/GetSessionFormation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:50.177097 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:50] "POST /myclass/api/Get_List_Jury_Soutenenace_With_Filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:50] "POST /myclass/api/Get_Inscrit_List_Groupe/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:51.023495 : Get_Inscrit_List_EU Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:51] "POST /myclass/api/Get_Inscrit_List_EU/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:56:51.026012 : Get_Inscrit_List_EU_Type_Evaluation Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:56:51] "POST /myclass/api/Get_Inscrit_List_EU_Type_Evaluation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:57:03.326958 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:57:03] "POST /myclass/api/Get_List_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:57:04.547688 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:57:04.551230 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:57:04.555437 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:57:04] "POST /myclass/api/Get_Inscrit_Admiss_Session_Recorded_Image_from_front/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:57:04] "POST /myclass/api/Get_Given_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:57:04] "POST /myclass/api/Get_List_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:57:53.384639 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:57:53] "POST /myclass/api/Update_Stagiaire_To_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:57:53.538518 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:57:53] "POST /myclass/api/Get_List_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\apprenant_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:58:25.700034 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:58:25.700034 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:58:25.700034 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:58:25.700034 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:58:25.700034 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\apprenant_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 15:58:55.551116 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 15:58:55.551116 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 15:58:55.551116 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 15:58:55.551116 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 15:58:55.551116 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 15:59:35.003986 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:59:35.005987 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:35] "POST /myclass/api/Get_List_Candidat_Document/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:35] "POST /myclass/api/Get_Pourcentage_Candidat_Document/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:59:35.727902 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:35] "POST /myclass/api/Get_List_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:59:39.816052 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:39] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:59:39.856644 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:59:39.858639 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:59:39.860629 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:39] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:39] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:39] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:59:41.098761 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:41] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:59:49.637507 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:50] "POST /myclass/api/Candidat_Inscrire_To_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:59:50.322605 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:50] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:59:54.975848 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:59:54.978848 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:54] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:59:54.984846 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:59:54.987855 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:54] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:55] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:59:55.005814 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:55] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:59:55.008814 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:59:55.016324 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:59:55.018324 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:59:55.026675 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:55] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:59:55.031677 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:55] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:55] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:59:55.040184 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:59:55.046185 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 15:59:55.053712 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:55] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:55] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:55] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:55] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 15:59:56.200407 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:56] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 15:59:56] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:01.589846 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:01.592886 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:01.596445 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:01.600471 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:01] "POST /myclass/api/Get_List_Unite_Enseignement_Of_Given_Class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:01] "POST /myclass/api/Get_List_Class_Evaluation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:02.449363 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:02.452687 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:02.453688 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:02.454686 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:02.462689 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:02.471199 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:02.473198 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:02] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:02] "POST /myclass/api/getRecodedStagiaireImage_from_front/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:02] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:02] "POST /myclass/api/GetAttendeeDetail_perSession/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:02.488837 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:02.489860 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:02] "POST /myclass/api/GetSessionFormation/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:02] "POST /myclass/api/Get_List_Participant_Notes/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:02] "POST /myclass/api/Get_List_Jury_Soutenenace_With_Filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:02] "POST /myclass/api/Get_Inscrit_List_Tuteurs/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:02] "POST /myclass/api/Get_Inscrit_List_Groupe/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:03.778601 : Get_Inscrit_List_EU_Type_Evaluation Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:03] "POST /myclass/api/Get_Inscrit_List_EU_Type_Evaluation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:03.781602 : Get_Inscrit_List_EU Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:03] "POST /myclass/api/Get_Inscrit_List_EU/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:08.073256 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:08.074569 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:08.077575 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:08.084575 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:08.097088 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:08.112677 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:08.113683 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:08.117682 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:08.121684 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:08.129192 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:08.133229 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:08.136192 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:08.145734 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:08.153222 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/Get_List_Ressource_Materielle_no_filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:08.161237 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/GetPartnerAttestation_Certificat/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:08.170759 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/Get_List_Partner_Or_Default_session_step/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:08.174359 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:08.184360 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/Get_List_Site_Formation_with_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:08.196918 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:08.201465 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/Is_Partnair_Has_Digital_Signature/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:08.219287 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/Get_Session_Sequence_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:08.241312 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/GetSessionFormation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:08.255855 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/GetSessionFormation/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/GetAllClassStagiaire/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:08.275728 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:08.279728 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/GetAllClassStagiaire/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/GetTableauEmargement/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/Get_List_Ressource_Humaine_no_filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:08] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:09] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:10] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:00:10.400740 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:00:10.403756 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:10] "POST /myclass/api/GetAllClassStagiaire/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:00:12] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:02:35.054593 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:02:35] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:02:35.506417 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:02:35] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:02:35.569327 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:02:35.572330 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:02:35.574327 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:02:35] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:02:35] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:02:35] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:02:36.973084 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:02:37] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:02:49.064488 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:02:49] "POST /myclass/api/Candidat_Inscrire_To_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:02:49.768494 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:02:49] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\apprenant_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 16:05:11.274891 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 16:05:11.275892 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 16:05:11.275892 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 16:05:11.275892 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 16:05:11.275892 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 16:05:15.628471 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:05:15] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:05:16.141871 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:05:16] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:05:16.210760 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:05:16.215745 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:05:16.225947 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:05:16] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:05:16] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:05:16] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:05:17.194256 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:05:17] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:05:23.587505 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:05:24] "POST /myclass/api/Candidat_Inscrire_To_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:05:24.183142 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:05:24] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\apprenant_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 16:06:16.374207 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 16:06:16.375209 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 16:06:16.375209 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 16:06:16.375209 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 16:06:16.375209 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 16:12:40.378965 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 16:12:40.378965 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 16:12:40.378965 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 16:12:40.378965 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 16:12:40.378965 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +INFO:werkzeug:WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. + * Running on http://localhost:5001 +INFO:werkzeug:Press CTRL+C to quit +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 16:12:54.723112 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 16:12:54.724111 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 16:12:54.724111 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 16:12:54.724111 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 16:12:54.724111 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 16:13:11.976355 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:11] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:12.398647 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:12] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:12.437169 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:13:12.439183 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:13:12.441183 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:12] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:12] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:12] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:14.874417 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:14] "POST /myclass/api/Get_List_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:19.216346 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:19] "POST /myclass/api/Get_List_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:21.179662 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:13:21.183188 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:13:21.187219 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:21] "POST /myclass/api/Get_List_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:21] "POST /myclass/api/Get_Given_Stagiaire_Admission_Session/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:21] "POST /myclass/api/Get_Inscrit_Admiss_Session_Recorded_Image_from_front/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:22.532164 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:13:22.535135 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:22] "POST /myclass/api/Get_List_Candidat_Document/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:22] "POST /myclass/api/Get_Pourcentage_Candidat_Document/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:27.904911 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:27] "POST /myclass/api/Store_User_Downloaded_File/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:27.939946 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:13:27.942947 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:27] "POST /myclass/api/Get_List_Candidat_Document/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:27] "POST /myclass/api/Get_Pourcentage_Candidat_Document/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:34.020592 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:34] "POST /myclass/api/Store_User_Downloaded_File/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:34.041126 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:13:34.045163 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:34] "POST /myclass/api/Get_List_Candidat_Document/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:34] "POST /myclass/api/Get_Pourcentage_Candidat_Document/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:38.322359 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:38] "POST /myclass/api/Acceptance_Stored_Downloaded_File_From_Id/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:38.361359 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:13:38.375356 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:38] "POST /myclass/api/Get_List_Candidat_Document/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:38] "POST /myclass/api/Get_Pourcentage_Candidat_Document/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:39.507298 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:39] "POST /myclass/api/Acceptance_Stored_Downloaded_File_From_Id/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:39.556029 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:13:39.585030 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:39] "POST /myclass/api/Get_List_Candidat_Document/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:39] "POST /myclass/api/Get_Pourcentage_Candidat_Document/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:41.236396 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:41] "POST /myclass/api/Acceptance_Stored_Downloaded_File_From_Id/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:41.285418 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:13:41.301446 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:41] "POST /myclass/api/Get_List_Candidat_Document/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:41] "POST /myclass/api/Get_Pourcentage_Candidat_Document/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:44.946692 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:44] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:45.019580 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:45] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:45.037057 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:45] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:45.064067 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:45] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:13:47.647453 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:13:49] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:14:02.783808 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:14:05.285183 : Candidat_Inscrire_To_Session -module 'GlobalVariable' has no attribute 'download_files' - Line : 3308 +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:14:05] "POST /myclass/api/Candidat_Inscrire_To_Session/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 16:14:36.696901 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 16:14:36.696901 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 16:14:36.696901 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 16:14:36.696901 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 16:14:36.696901 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 16:15:11.392866 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:14] "POST /myclass/api/Candidat_Inscrire_To_Session/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:14.568299 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:14] "POST /myclass/api/Get_Synthese_Candidat_Process_Admission/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:22.761047 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:15:22.764047 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:15:22.767049 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:15:22.770047 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:22] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:22] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:22] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:22.795571 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:22] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:22.799606 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:15:22.801607 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:15:22.805112 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:15:22.808629 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:22] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:22.815662 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:22] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:22.818662 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:22] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:22.826216 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:15:22.832224 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:22] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:22] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:23] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:23] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:23.847193 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:24] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:25] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:25.595430 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:15:25.598416 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:15:25.601415 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:15:25.606415 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:25] "POST /myclass/api/Get_List_Unite_Enseignement_Of_Given_Class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:25] "POST /myclass/api/Get_List_Class_Evaluation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:26.662091 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:15:26.666607 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:15:26.669604 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:15:26.675604 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:15:26.681649 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:26] "POST /myclass/api/GetAttendeeDetail_perSession/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:26.693615 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:26] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:26] "POST /myclass/api/getRecodedStagiaireImage_from_front/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:26.706688 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:26] "POST /myclass/api/GetSessionFormation/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:26] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:26.711690 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:26] "POST /myclass/api/Get_List_Participant_Notes/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:26.718690 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:26] "POST /myclass/api/Get_Inscrit_List_Tuteurs/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:26] "POST /myclass/api/Get_List_Jury_Soutenenace_With_Filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:26] "POST /myclass/api/Get_Inscrit_List_Groupe/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:27.653056 : Get_Inscrit_List_EU_Type_Evaluation Il ne s'agit pas d'un formation initiale +INFO:root:2026-06-27 16:15:27.654070 : Get_Inscrit_List_EU Il ne s'agit pas d'un formation initiale +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:27] "POST /myclass/api/Get_Inscrit_List_EU/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:27] "POST /myclass/api/Get_Inscrit_List_EU_Type_Evaluation/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:28.927554 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:28] "POST /myclass/api/Get_List_Survey_with_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:29.007254 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:29] "POST /myclass/api/Get_List_object_owner_collection_Stored_Files/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:42.384767 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:42] "GET /myclass/api/Get_Stored_Downloaded_File_From_Id/66R8NExLflHhvOvlO6pBeYsuEvOtSpIT-Q/6a3fc81533af6e7d5c0de906 HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:44.902952 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:44] "GET /myclass/api/Get_Stored_Downloaded_File_From_Id/66R8NExLflHhvOvlO6pBeYsuEvOtSpIT-Q/6a3fda8733af6e7d5c0de90e HTTP/1.1" 200 - +INFO:root:2026-06-27 16:15:47.093181 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:15:47] "GET /myclass/api/Get_Stored_Downloaded_File_From_Id/66R8NExLflHhvOvlO6pBeYsuEvOtSpIT-Q/6a3fda8e33af6e7d5c0de90f HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\session_admission_fi.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 16:16:41.888093 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 16:16:41.888093 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 16:16:41.888093 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 16:16:41.888093 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 16:16:41.888093 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 16:16:41.968320 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:16:41.969351 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:16:41] "POST /myclass/api/GetAllClassStagiaire/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:16:42] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:17:12.056968 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:17:12.059947 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:17:12] "POST /myclass/api/GetAllClassStagiaire/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:17:13] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:17:13.309208 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:17:13.313208 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:17:13.314209 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:17:13.318209 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:17:13.328722 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:17:13] "POST /myclass/api/Get_Session_Sequence_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:17:13] "POST /myclass/api/Get_List_Unite_Enseignement_Of_Given_Session_Id/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:17:13] "POST /myclass/api/Get_List_Ressource_Materielle_no_filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:17:13] "POST /myclass/api/Get_List_Groupe_Inscrit_With_Filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:17:13] "POST /myclass/api/Get_List_Ressource_Humaine_no_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:17:15.437927 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:17:15.440905 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:17:15] "POST /myclass/api/GetAllClassStagiaire/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:17:16] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:17:21.002759 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:17:21] "POST /myclass/api/UpdateStagiairetoClass/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:17:21.119360 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:17:21.121358 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:17:21.125361 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:17:21] "POST /myclass/api/GetAllClassStagiaire/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:17:21] "POST /myclass/api/GetAllClassStagiaire/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:17:21] "POST /myclass/api/GetTableauEmargement/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:17:23.565858 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:17:23.569885 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:17:23] "POST /myclass/api/GetAllClassStagiaire/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:17:24] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:19:55.662872 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:19:55.666877 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:19:55.671876 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:19:55.674878 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:19:55.679877 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:19:55] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:19:55] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:19:55] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 16:19:55.696398 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:19:55.700912 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 16:19:55.706927 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:19:55] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:19:55] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:19:56] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:19:56] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 16:19:57] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 16:27:49.859403 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 16:27:49.859403 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 16:27:49.860433 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 16:27:49.860433 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 16:27:49.860433 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 16:30:05.150977 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 16:30:05.150977 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 16:30:05.150977 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 16:30:05.151977 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 16:30:05.151977 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 16:30:38.668735 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 16:30:38.669735 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 16:30:38.669735 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 16:30:38.669735 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 16:30:38.669735 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\main.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 16:32:41.833506 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 16:32:41.833506 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 16:32:41.833506 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 16:32:41.833506 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 16:32:41.833506 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 17:37:19.041771 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:37:19.043771 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:37:19.052280 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:37:19.059280 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:37:19.068813 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:37:19.081330 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:37:19] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:37:19] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:37:19.119356 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:37:19] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:37:19.138902 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:37:19] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:37:19] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:37:24] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:37:25] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:37:44] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 17:40:28.493470 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 17:40:28.494470 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 17:40:28.494470 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 17:40:28.494470 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 17:40:28.494470 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 17:40:28.889207 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:40:28.893198 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:40:28.898205 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:40:28.903206 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:40:28.908735 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:40:28.917276 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:28] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:28] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:28.945924 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:28] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:28.963928 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:40:28.971925 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:28] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:29] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:29.012011 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:40:29.022055 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:29] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:29] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:29.042066 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:29] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:29.056144 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:40:29.079706 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:30] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:30.702909 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:30] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:30.754521 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:30] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:30.800061 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:30] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:30.828617 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:30] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:30.851593 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:30] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:30.874628 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:30] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:30.903638 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:31] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:31.403416 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:31] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:31.686672 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:31] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:31.741301 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:31] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:31.785337 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:31] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:31.832579 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:31] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:31.865005 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:31] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:31.911547 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:33] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:33.096647 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:33] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:33.759977 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:33] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:33.817809 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:33] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:33.884176 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:33] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:35] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:35] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:35] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:36] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:36] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:40:49.413711 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:40:50] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 17:43:45.756503 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 17:43:45.757503 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 17:43:45.757503 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 17:43:45.757503 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 17:43:45.757503 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 17:44:35.615288 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 17:44:35.615288 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 17:44:35.615288 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 17:44:35.615288 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 17:44:35.615288 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 17:44:35.727875 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:44:36] "POST /myclass/api/Cancel_Tab_Inscription/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 17:46:07.281101 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 17:46:07.281101 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 17:46:07.281101 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 17:46:07.281101 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 17:46:07.281101 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 17:46:07.444164 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:46:07.448131 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:46:07.451035 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:46:07.454652 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:46:07.459062 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:46:07.464021 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:46:07] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:46:07] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:46:07.478359 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:46:07.483923 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:46:07] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:46:07] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:46:07] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:46:08] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:46:08] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:46:10] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:46:15.732771 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:46:16] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:46:30.365008 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:46:32] "POST /myclass/api/Cancel_Tab_Inscription/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 17:47:34.580723 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 17:47:34.581747 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 17:47:34.581747 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 17:47:34.581747 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 17:47:34.581747 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 17:48:24.854453 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 17:48:24.855452 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 17:48:24.861452 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 17:48:24.862451 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 17:48:24.862451 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 17:49:04.975547 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:49:09] "POST /myclass/api/Cancel_Tab_Inscription/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 17:51:14.408279 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 17:51:14.408279 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 17:51:14.408279 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 17:51:14.408279 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 17:51:14.408279 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 17:51:14.499806 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:51:14.503240 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:51:14.504242 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:51:14.506246 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:51:14.508241 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:51:14] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:51:14.512754 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:51:14.513755 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:51:14] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:51:14] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:51:14.521753 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:51:14.523754 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:51:14] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:51:14] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:51:14] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:51:15] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:51:15] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:51:15] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:51:26.139537 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:51:28] "POST /myclass/api/Cancel_Tab_Inscription/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 17:52:28.124008 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 17:52:28.124008 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 17:52:28.124008 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 17:52:28.124008 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 17:52:28.124008 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 17:53:23.836297 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 17:53:23.836297 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 17:53:23.836297 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 17:53:23.836297 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 17:53:23.837301 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 17:53:43.961028 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:53:44] "POST /myclass/api/Cancel_Tab_Inscription/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:53:44.047097 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:53:44] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:54:00.702927 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:54:00] "POST /myclass/api/Delete_List_AttendeeInscription/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:54:00.856201 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:54:03] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:56:44.504947 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:56:44.509943 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:56:44.512940 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:56:44.519455 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:56:44] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:56:44.525455 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:56:44.531961 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:56:44.535962 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:56:44] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:56:44] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:56:44.547967 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:56:44] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:56:44] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:56:45] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:56:45] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:56:46] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:56:48.429329 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:56:48] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:56:54.245493 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:56:54] "POST /myclass/api/Cancel_Tab_Inscription/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:56:54.343457 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:56:54] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:57:02.611234 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:57:05.132454 : Accept_List_AttendeeInscription Toutes les inscriptions doivent être au statut : en cours ou preinscription +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:57:05] "POST /myclass/api/Accept_List_AttendeeInscription/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:57:27.224085 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:57:27.293169 : Notification_partner_Pre_incription_mail - : La valeur 'telephone' n'est pas presente dans la liste des arguments +INFO:root:2026-06-27 17:57:27.296169 : WARNING : Impossible d'envoyer le mail de preinscriton à UpdateStagiairetoClass - l'adresse email nadia.sbaih@fondationjeanmoulin.fr pour la session 6a382f75d743e3853b07ef62 +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:57:27] "POST /myclass/api/UpdateStagiairetoClass/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:57:27.366229 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:57:27.368228 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:57:27] "POST /myclass/api/GetAttendeeDetail_perSession/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:57:27] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:57:34.661781 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:57:34.702409 : Notification_partner_Pre_incription_mail - : La valeur 'telephone' n'est pas presente dans la liste des arguments +INFO:root:2026-06-27 17:57:34.704395 : WARNING : Impossible d'envoyer le mail de preinscriton à UpdateStagiairetoClass - l'adresse email lesptitescanailles91@orange.fr pour la session 6a382f75d743e3853b07ef56 +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:57:34] "POST /myclass/api/UpdateStagiairetoClass/ HTTP/1.1" 200 - +INFO:root:2026-06-27 17:57:34.729732 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 17:57:34.730761 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:57:34] "POST /myclass/api/GetAttendeeDetail_perSession/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 17:57:35] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 18:01:07.197209 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 18:01:07.198210 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 18:01:07.198210 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 18:01:07.198210 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 18:01:07.198210 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 18:02:34.473135 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 18:02:34.476137 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 18:02:34.476137 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 18:02:34.476137 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 18:02:34.476137 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 +INFO:root:2026-06-27 18:03:47.566344 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:03:49] "POST /myclass/api/Cancel_Tab_Inscription/ HTTP/1.1" 200 - +INFO:root:2026-06-27 18:03:49.273399 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:03:49] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 18:04:02.632266 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 18:04:03.581348 : L'utilisateur destinataire de l'email n'est pas enregistré sur la plateforme => Add_Message_To_Internal_Mail +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:04:03] "POST /myclass/api/UpdateStagiairetoClass/ HTTP/1.1" 200 - +INFO:root:2026-06-27 18:04:03.587361 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 18:04:03.589373 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:04:03] "POST /myclass/api/GetAttendeeDetail_perSession/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:04:04] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 18:04:36.384647 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 18:04:37.001735 : L'utilisateur destinataire de l'email n'est pas enregistré sur la plateforme => Add_Message_To_Internal_Mail +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:04:37] "POST /myclass/api/UpdateStagiairetoClass/ HTTP/1.1" 200 - +INFO:root:2026-06-27 18:04:37.006736 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 18:04:37.011735 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:04:37] "POST /myclass/api/GetAttendeeDetail_perSession/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:04:37] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 18:04:46.021032 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:04:46] "POST /myclass/api/Accept_List_AttendeeInscription/ HTTP/1.1" 200 - +INFO:root:2026-06-27 18:04:46.342268 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:04:46] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 18:06:28.702579 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 18:06:28.705579 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 18:06:28.707579 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 18:06:28.709578 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:06:28] "POST /myclass/api/getRecodedImage/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:06:28] "POST /myclass/api/Get_Nb_User_Internal_Mail_Not_Read/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:06:28] "POST /myclass/api/LMS_Get_Partner_Data/ HTTP/1.1" 200 - +INFO:root:2026-06-27 18:06:28.735096 : Connexion du partner recid = 43598820dd270936c3d2fd822717d0f18f194b1a1b894aaf89 OK. Mise à jour du firstconnexion et/ou lastconnexion : OK +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:06:28] "POST /myclass/api/get_partner_account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 18:06:28.741094 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 18:06:28.744093 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 18:06:28.747603 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 18:06:28.752110 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:06:28] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 18:06:28.755123 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 18:06:28.760639 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 18:06:28.765638 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:06:28] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:06:28] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 18:06:28.776158 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:06:28] "POST /myclass/api/Get_Partner_List_Partner_Client_with_filter_Like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:06:28] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:06:29] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:06:29] "POST /myclass/api/GetAllValideSessionPartner_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 18:06:30.748884 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:06:31] "POST /myclass/api/Get_Partner_List_Partner_Client/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 18:06:31] "POST /myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:08:00.334281 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:08:00] "POST /myclass/api/Update_Context_Partner_Account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:08:00.376464 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 19:08:00.378497 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 19:08:00.380497 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 19:08:00.383526 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 19:08:00.388587 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:08:00] "POST /myclass/api/Get_Competence_Domaine/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:08:00] "POST /myclass/api/Get_List_Partner_Basic_Setup/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:08:00.395585 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:08:00] "POST /myclass/api/Get_Client_Type_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:08:00.401584 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:08:00] "POST /myclass/api/Get_List_Groupe_Client/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:08:00.406583 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:08:00] "POST /myclass/api/Get_List_Site_Formation_with_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:08:00.409603 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 19:08:00.411583 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 19:08:00.415590 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:08:00] "POST /myclass/api/Get_List_Paiement_Condition/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:08:00] "POST /myclass/api/Get_CRM_List_Opportunite_Etape/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:08:00] "POST /myclass/api/Get_Competence_no_filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:08:00] "POST /myclass/api/Get_List_Partner_Basic_Setup/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:08:00] "POST /myclass/api/Get_List_Partner_Basic_Setup/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:08:00] "POST /myclass/api/Get_List_base_document_automatic_setup/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:14:30.660259 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:14:30] "POST /myclass/api/Get_Client_Type_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:14:46.450191 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:14:46] "POST /myclass/api/Get_List_Financement_Mode/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:15:35.370604 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:15:35] "POST /myclass/api/Get_List_Type_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:16:31.050318 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:16:31] "POST /myclass/api/Get_List_Type_Groupe_Inscrit/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:16:43.483917 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:16:43] "POST /myclass/api/Get_List_Categorie_Apprenant/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:17:01.335280 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:17:01] "POST /myclass/api/Get_Client_Type_List/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:17:03.998240 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:17:04] "POST /myclass/api/Get_List_Site_Formation_with_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:17:11.345541 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:17:11] "POST /myclass/api/Get_List_Paiement_Condition/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:17:22.018693 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:17:22] "POST /myclass/api/Get_Competence_no_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:18:14.345982 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:18:14] "POST /myclass/api/Get_List_Partner_Basic_Setup/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:18:17.333935 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:18:17] "POST /myclass/api/Get_List_Partner_Basic_Setup/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:18:23.775479 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:18:24] "POST /myclass/api/Get_List_Message_To_Mail_Queue/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:18:41.609532 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 19:18:41.642250 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 19:18:41.646801 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 19:18:41.649362 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 19:18:41.656891 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:18:41] "POST /myclass/api/Get_List_Class_domaine/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:18:41.662916 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:18:41] "POST /myclass/api/Get_List_Class_Categorie/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:18:41.669924 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:18:41] "POST /myclass/api/Get_List_class_metier/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:18:41] "POST /myclass/api/Get_bloc_competence_no_filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:18:41] "POST /myclass/api/Get_Partner_Object_Specific_Valide_Displayed_Fields/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:18:42] "POST /myclass/api/find_partner_class_like/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:18:42] "POST /myclass/api/get_partner_class/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:18:53.551891 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:18:53] "POST /myclass/api/Update_Context_Partner_Account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:18:53.610536 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 19:18:53.611540 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 19:18:53.614540 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 19:18:53.616540 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:18:53] "POST /myclass/api/Get_List_Class_domaine/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:18:53] "POST /myclass/api/Get_List_Type_Cours/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:18:53] "POST /myclass/api/Get_Competence_no_filter/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:18:53] "POST /myclass/api/Get_List_Unite_Enseignement_with_filter/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:19:08.947997 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:19:08] "POST /myclass/api/Update_Context_Partner_Account/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:19:08.972683 : Security check : IP adresse '127.0.0.1' connected +INFO:root:2026-06-27 19:19:08.974682 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:19:08] "POST /myclass/api/Get_List_Class_domaine/ HTTP/1.1" 200 - +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:19:08] "POST /myclass/api/Get_List_Class_domaine/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:19:15.209017 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:19:15] "POST /myclass/api/Get_List_Class_Categorie/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:19:47.979968 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:19:47] "POST /myclass/api/Get_List_Class_domaine/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:22:42.620301 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:22:42] "POST /myclass/api/Get_List_Class_Categorie/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:23:57.834086 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:23:57] "POST /myclass/api/Get_List_class_metier/ HTTP/1.1" 200 - +INFO:root:2026-06-27 19:23:59.337544 : Security check : IP adresse '127.0.0.1' connected +INFO:werkzeug:127.0.0.1 - - [27/Jun/2026 19:23:59] "POST /myclass/api/Get_List_Class_Categorie/ HTTP/1.1" 200 - +INFO:werkzeug: * Detected change in 'C:\\Users\\Cherif\\Documents\\myclass.com\\Siteweb\\Elyos_Ftion_Initiale\\Ela_back\\Back_Office_FI\\Inscription_mgt.py', reloading +INFO:werkzeug: * Restarting with stat +DEBUG:matplotlib:matplotlib data path: C:\Users\Cherif\Documents\myclass.com\Siteweb\Elyos_Ftion_Continue\Ela_back\Back_Office\venv\Lib\site-packages\matplotlib\mpl-data +DEBUG:matplotlib:CONFIGDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib:interactive is False +DEBUG:matplotlib:platform is win32 +DEBUG:matplotlib:CACHEDIR=C:\Users\Cherif\.matplotlib +DEBUG:matplotlib.font_manager:Using fontManager instance from C:\Users\Cherif\.matplotlib\fontlist-v390.json +INFO:root:2026-06-27 19:30:42.966564 : ++++ ENVIRONNEMENT DEVELOPPEMENT ++++ +INFO:root:2026-06-27 19:30:42.967563 : ++ DATABASE mongodb://localhost:27017/cherifdb_dev_fi ++ +INFO:root:2026-06-27 19:30:42.967563 : ++ DBNAME Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'cherifdb_dev_fi') ++ +INFO:root:2026-06-27 19:30:42.967563 : ++ FLASK PORT 5001 ++ +INFO:root:2026-06-27 19:30:42.967563 : ++ LMS_BAS_URL mysy-hosting.com/ ++ +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 479-264-725 diff --git a/apprenant_mgt.py b/apprenant_mgt.py index b9b2f89..6e05471 100644 --- a/apprenant_mgt.py +++ b/apprenant_mgt.py @@ -1297,6 +1297,369 @@ def Apprenant_Inscrire_Session(diction): return False, " Impossible d'inscrire l'apprenant à la session de formation " +""" +Internal avec return inscription_id""" +def Internal_Apprenant_Inscrire_Session_Ret_id(diction): + try: + diction = mycommon.strip_dictionary(diction) + + """ + Verification des input acceptés + """ + field_list = ['token', '_id', 'session_id', 'type_apprenant' , 'modefinancement', 'client_rattachement_id', 'tab_ue_ids', 'statut_inscription'] + + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list and val.startswith('my_') is False: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé") + return False, " Les informations fournies sont incorrectes", False + + """ + Verification des champs obligatoires + """ + field_list_obligatoire = ['token', '_id', 'session_id', 'type_apprenant' ] + + 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", False + + """ + 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, False + + + # Verifier que le type d'apprenant est bien valide + if ("type_apprenant" in diction.keys() and str(diction['type_apprenant'])): + is_valide_type_apprenant = MYSY_GV.dbname['type_apprenant'].count_documents( + {'_id': ObjectId(str(diction['type_apprenant'])), + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked': '0'}) + + if (is_valide_type_apprenant != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le type d'apprenant est invalide ") + return False, " Le type d'apprenant est invalide ", False + + type_apprenant = str(diction['type_apprenant']) + + + # Verifier que l'apprenant existe + is_apprenant_exist = MYSY_GV.dbname['apprenant'].count_documents({'_id':ObjectId(str(diction['_id'])), + 'partner_owner_recid':str(my_partner['recid']), + 'valide':'1', + 'locked':'0'}) + if( is_apprenant_exist <= 0 ): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de l'apprenant n'est pas valide ") + return False, " L'identifiant de l'apprenant n'est pas valide ", False + + # Verifier la validité du client , s'il ya un client + client_rattachement_id = "" + if( "client_rattachement_id" in diction.keys() and diction['client_rattachement_id'] ) : + is_client_rattachement_id_exist = MYSY_GV.dbname['partner_client'].count_documents({'_id': ObjectId(diction['client_rattachement_id']), + 'partner_owner_recid': str( + my_partner['recid']), + 'valide': '1', + 'locked': '0'}) + if (is_client_rattachement_id_exist <= 0): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant du client n'est pas valide ") + return False, " L'identifiant du client n'est pas valide ", False + + client_rattachement_id = str(diction['client_rattachement_id']) + + + # Recuperer les données de l'apprenant + apprenant_data = MYSY_GV.dbname['apprenant'].find_one({'_id': ObjectId(str(diction['_id'])), + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked': '0'}) + + # Verifier que la session de formation existe et est valide + is_session_existe = MYSY_GV.dbname['session_formation'].count_documents({'_id':ObjectId(str(diction['session_id'])), + 'partner_owner_recid':str(my_partner['recid']), + 'valide':'1', + }) + + if (is_session_existe <= 0): + mycommon.myprint( + str(inspect.stack()[0][3]) + " L'identifiant de la session de formation n'est pas valide ") + return False, " L'identifiant de la session de formation n'est pas valide ", False + + # Recuperer les données de la session + session_data = MYSY_GV.dbname['session_formation'].find_one( + {'_id': ObjectId(str(diction['session_id'])), + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + }) + + local_class_id = "" + tab_local_class_eu = [] + list_local_class_eu = "" + + class_data = MYSY_GV.dbname['myclass'].find_one({'internal_url':str(session_data['class_internal_url']), + 'valide':'1', + 'locked':'0', + 'partner_owner_recid':str(my_partner['recid'])}) + + if(class_data and '_id' in class_data.keys() ): + local_class_id = str(class_data['_id']) + + if( "list_unite_enseignement" in class_data.keys()): + for class_ue in class_data['list_unite_enseignement']: + if('_id' in class_ue.keys()): + tab_local_class_eu.append(str(class_ue['_id'])) + + + print(" ### tab_local_class_eu == ", tab_local_class_eu) + list_local_class_eu = ",".join(tab_local_class_eu) + + print(" ### list_local_class_eu == ", list_local_class_eu) + + """ + Recgarder si la personne est déja inscrite à cette promo + """ + is_alread_inscrit_id = "" + is_alread_inscrit_count = MYSY_GV.dbname['inscription'].count_documents({'session_id':str(session_data['_id']), + 'email':apprenant_data['email'], + 'valide':'1'}) + + if( is_alread_inscrit_count > 0 ): + is_alread_inscrit_data = MYSY_GV.dbname['inscription'].find_one( + {'session_id': str(session_data['_id']), + 'email': apprenant_data['email'], + 'valide': '1'}, {'_id':1}) + + if( is_alread_inscrit_data and '_id' in is_alread_inscrit_data.keys() ): + is_alread_inscrit_id = str(is_alread_inscrit_data['_id']) + + new_data = {} + new_data['token'] = diction['token'] + new_data['email'] = apprenant_data['email'] + new_data['nom'] = apprenant_data['nom'] + new_data['civilite'] = str(apprenant_data['civilite']).lower() + if( str(apprenant_data['civilite']).strip() == ""): + new_data['civilite'] = "neutre" + + + new_data['prenom'] = apprenant_data['prenom'] + new_data['telephone'] = apprenant_data['telephone'] + new_data['modefinancement'] = str(diction['modefinancement']) + new_data['client_rattachement_id'] = client_rattachement_id + + new_data['apprenant_id'] = str(apprenant_data['_id']) + new_data['session_id'] = str(session_data['_id']) + new_data['class_internal_url'] = session_data['class_internal_url'] + + if ("statut_inscription" in diction.keys() and diction['statut_inscription'] == "1"): + new_data['status'] = "1" + else: + new_data['status'] = "0" + + new_data['type_apprenant'] = str(type_apprenant) + + if("is_droit_image" in apprenant_data.keys()): + new_data['is_droit_image'] = apprenant_data['is_droit_image'] + else: + new_data['is_droit_image'] = "0" + + if ("is_handicap" in apprenant_data.keys()): + new_data['is_handicap'] = apprenant_data['is_handicap'] + else: + new_data['is_handicap'] = "0" + + if ("is_rgpd" in apprenant_data.keys()): + new_data['is_rgpd'] = apprenant_data['is_rgpd'] + else: + new_data['is_rgpd'] = "0" + + if ("matricule" in apprenant_data.keys()): + new_data['matricule'] = apprenant_data['matricule'] + else: + new_data['matricule'] = "" + + + if ("matricule" in apprenant_data.keys()): + new_data['matricule'] = apprenant_data['matricule'] + else: + new_data['matricule'] = "" + + + if ("naissance_departement" in apprenant_data.keys()): + new_data['naissance_departement'] = apprenant_data['naissance_departement'] + else: + new_data['naissance_departement'] = "" + + + if ("naissance_lieu" in apprenant_data.keys()): + new_data['naissance_lieu'] = apprenant_data['naissance_lieu'] + else: + new_data['naissance_lieu'] = "" + + + if ("naissance_pays" in apprenant_data.keys()): + new_data['naissance_pays'] = apprenant_data['naissance_pays'] + else: + new_data['naissance_pays'] = "" + + if ("nationalite" in apprenant_data.keys()): + new_data['nationalite'] = apprenant_data['nationalite'] + else: + new_data['nationalite'] = "" + + + if ("nom_fille" in apprenant_data.keys()): + new_data['nom_fille'] = apprenant_data['nom_fille'] + else: + new_data['nom_fille'] = "" + + + if ("num_secu" in apprenant_data.keys()): + new_data['num_secu'] = apprenant_data['num_secu'] + else: + new_data['num_secu'] = "" + + if ("pays" in apprenant_data.keys()): + new_data['pays'] = apprenant_data['pays'] + else: + new_data['pays'] = "" + + ############# + if ("piece_identite_num" in apprenant_data.keys()): + new_data['piece_identite_num'] = apprenant_data['piece_identite_num'] + else: + new_data['piece_identite_num'] = "" + + if ("piece_identite_type" in apprenant_data.keys()): + new_data['identite_type'] = apprenant_data['piece_identite_type'] + else: + new_data['identite_type'] = "" + + if ("situation_famille" in apprenant_data.keys()): + new_data['situation_famille'] = apprenant_data['situation_famille'] + else: + new_data['situation_famille'] = "" + + if ("telephone" in apprenant_data.keys()): + new_data['telephone'] = apprenant_data['telephone'] + else: + new_data['telephone'] = "" + + if ("type_apprenant" in apprenant_data.keys()): + new_data['type_apprenant'] = apprenant_data['type_apprenant'] + else: + new_data['type_apprenant'] = "" + + + if ("ville" in apprenant_data.keys()): + new_data['ville'] = apprenant_data['ville'] + else: + new_data['ville'] = "" + + if ("adresse" in apprenant_data.keys()): + new_data['adresse'] = apprenant_data['adresse'] + else: + new_data['adresse'] = "" + + + if ("code_postal" in apprenant_data.keys()): + new_data['code_postal'] = apprenant_data['code_postal'] + else: + new_data['code_postal'] = "" + + + if ("date_naissance" in apprenant_data.keys()): + new_data['date_naissance'] = apprenant_data['date_naissance'] + else: + new_data['date_naissance'] = "01/01/1900" + + + if ("ine" in apprenant_data.keys()): + new_data['ine'] = apprenant_data['ine'] + else: + new_data['ine'] = "" + + + + """ + Important : 08/06/2025 + Si on ne fourni pas diction['tab_ue_ids'], on va aller regarder si la formation concernée + a des eu, auquel cas on les prends tous + """ + if( "tab_ue_ids" in diction.keys()): + new_data['tab_ue_ids'] = str(diction['tab_ue_ids']) + else: + new_data['tab_ue_ids'] = str(list_local_class_eu) + + + + new_data['inscription_validation_date'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + + print('### Inscription_mgt.AddStagiairetoClass new_data = ', new_data) + + if( is_alread_inscrit_id and len(is_alread_inscrit_id) > 3 ): + # Il s'agit d'une mise à jour d'une inscription + new_data['_id'] = str(is_alread_inscrit_id) + local_status, local_retval = Inscription_mgt.UpdateStagiairetoClass(new_data) + if (local_status is False): + return local_status, local_retval, False + else: + local_status, local_retval = Inscription_mgt.AddStagiairetoClass(new_data) + if( local_status is False ): + return local_status, local_retval, False + + + inscription_qry_check = {} + inscription_qry_check['email'] = apprenant_data['email'] + inscription_qry_check['telephone'] = apprenant_data['telephone'] + inscription_qry_check['client_rattachement_id'] = client_rattachement_id + inscription_qry_check['apprenant_id'] = str(apprenant_data['_id']) + inscription_qry_check['session_id'] = str(session_data['_id']) + + inscrit_data = MYSY_GV.dbname['inscription'].find_one(inscription_qry_check, {'_id':1}) + + inscrit_data_id = "" + if( inscrit_data and "_id" in inscrit_data.keys()): + inscrit_data_id = str(inscrit_data['_id']) + + + + ## Add to log history + now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S")) + history_event_dict = {} + history_event_dict['token'] = diction['token'] + history_event_dict['related_collection'] = "apprenant" + history_event_dict['related_collection_recid'] = str(diction['_id']) + history_event_dict['action_date'] = str(now) + history_event_dict['action_description'] = "Inscription session "+str(session_data["code_session"]) + 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, " L'apprenant a été correctement inscrit à la session de formation", str(inscrit_data_id) + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible d'inscrire l'apprenant à la session de formation ", False + + + + """ Inscrire une liste d'apprenant à une session de formation diff --git a/main.py b/main.py index 9a923f7..31e2f9d 100644 --- a/main.py +++ b/main.py @@ -4407,6 +4407,23 @@ def CancelAttendeeInscription(): localStatus, message= inscription.CancelAttendeeInscription(payload) return jsonify(status=localStatus, message=message ) + + +"""" +Cette API annule des inscriptions en masse +""" +@app.route('/myclass/api/Cancel_Tab_Inscription/', methods=['POST','GET']) +@crossdomain(origin='*') +def Cancel_Tab_Inscription(): + # On Cancel_Tab_Inscription le corps (payload) de la requete + payload = mycommon.strip_dictionary (request.form.to_dict()) + print(" ### Cancel_Tab_Inscription : payload = ",payload) + localStatus, message= inscription.Cancel_Tab_Inscription(payload) + return jsonify(status=localStatus, message=message ) + + + + """" Cette API supprime defitivement un inscription qui doit etre au statut 'annulé' ou 'prescrit' """ @@ -5626,6 +5643,22 @@ def Get_Statgaire_List_Partner_with_filter(): + +""" +API qui recupere la liste complete des stagaire d'un partener UPTIMIZED +""" +@app.route('/myclass/api/Get_Statgaire_List_Partner_with_filter_uptimized/', methods=['POST','GET']) +@crossdomain(origin='*') +def Get_Statgaire_List_Partner_with_filter_uptimized(): + # On recupere le corps (payload) de la requete + payload = mycommon.strip_dictionary (request.form.to_dict()) + print(" ### Get_Statgaire_List_Partner_with_filter_uptimized payload = ",payload) + status, retval = inscription.Get_Statgaire_List_Partner_with_filter_uptimized(payload) + return jsonify(status=status, message=retval) + + + + """ API qui recupere la liste complete des stagaire d'un partener - version light pour alleger la recherche """ diff --git a/partner_client.py b/partner_client.py index 639d88f..d05c496 100644 --- a/partner_client.py +++ b/partner_client.py @@ -2508,7 +2508,7 @@ def Add_Partner_Client_mass(file=None, Folder=None, diction=None): # Controle des conditions de paiement : condition_paiement_code invoice_condition_paiement_id = "" - if ("condition_paiement_code" in df.keys()): + if ("condition_paiement_code" in df.keys() and str(df['condition_paiement_code'].values[n]).strip()): condition_paiement_code = str(df['condition_paiement_code'].values[n]).strip() is_valide_cond_paiement_data = MYSY_GV.dbname['base_partner_paiement_condition'].find_one( @@ -2524,7 +2524,7 @@ def Add_Partner_Client_mass(file=None, Folder=None, diction=None): # groupe de client : partner_groupe_client_code partner_groupe_client_id = "" - if ("partner_groupe_client_code" in df.keys()): + if ("partner_groupe_client_code" in df.keys() and str(df['partner_groupe_client_code'].values[n]).strip() ): condition_paiement_code = str(df['partner_groupe_client_code'].values[n]).strip() is_valide_partner_groupe_client_data = MYSY_GV.dbname[ @@ -2543,7 +2543,7 @@ def Add_Partner_Client_mass(file=None, Folder=None, diction=None): # Verifier que l'adresse email du responsable de compte est valide responsable_compte_email = "" responsable_compte_id = "" - if ("responsable_compte_email" in df.keys()): + if ("responsable_compte_email" in df.keys() and str(df['responsable_compte_email'].values[n]).strip()): if (str(df['responsable_compte_email'].values[n]) and str(df['responsable_compte_email'].values[n]) != ""): responsable_compte_email = str(df['responsable_compte_email'].values[n]).strip() @@ -2583,7 +2583,7 @@ def Add_Partner_Client_mass(file=None, Folder=None, diction=None): # type de client : client_type_code client_type_id = "" - if ("client_type_code" in df.keys()): + if ("client_type_code" in df.keys() and str(df['client_type_code'].values[n]).strip()): client_type_code = str(df['client_type_code'].values[n]).strip() is_valide_type_client_data = MYSY_GV.dbname[ @@ -2893,7 +2893,7 @@ def Controle_Add_Partner_Client_mass(saved_file=None, Folder=None, diction=None) # Controle des conditions de paiement : condition_paiement_code - if ("condition_paiement_code" in df.keys()): + if ("condition_paiement_code" in df.keys() and str(df['condition_paiement_code'].values[n]).strip()): condition_paiement_code = str(df['condition_paiement_code'].values[n]).strip() is_valide_cond_paiement_count = MYSY_GV.dbname['base_partner_paiement_condition'].count_documents({'code': re.compile(condition_paiement_code, @@ -2936,7 +2936,7 @@ def Controle_Add_Partner_Client_mass(saved_file=None, Folder=None, diction=None) n + 2) + " est invalide. Les valeurs acceptées '0', '1', ou '[vide]'" # Controle du champ 'is_client': - if ("is_client" in df.keys()): + if ("is_client" in df.keys() ): is_client = str(df['is_client'].values[n]).strip() is_client = str(mycommon.tryInt(is_client)) if (is_client not in ['0', '1', '']): @@ -2995,7 +2995,7 @@ def Controle_Add_Partner_Client_mass(saved_file=None, Folder=None, diction=None) # Controle des conditions de paiement : partner_groupe_client_code - if ("partner_groupe_client_code" in df.keys()): + if ("partner_groupe_client_code" in df.keys() and str(df['partner_groupe_client_code'].values[n]).strip()): condition_paiement_code = str(df['partner_groupe_client_code'].values[n]).strip() is_valide_partner_groupe_client_code_count = MYSY_GV.dbname[ @@ -3015,7 +3015,7 @@ def Controle_Add_Partner_Client_mass(saved_file=None, Folder=None, diction=None) n + 2) + " est invalide. " # Controle des conditions de paiement : client_type_code - if ("client_type_code" in df.keys()): + if ("client_type_code" in df.keys() and str(df['client_type_code'].values[n]).strip()): client_type_code = str(df['client_type_code'].values[n]).strip() diff --git a/session_admission_fi.py b/session_admission_fi.py index 1cd1393..4a41f6c 100644 --- a/session_admission_fi.py +++ b/session_admission_fi.py @@ -2962,6 +2962,8 @@ concernant uniquement cette ue (collection : inscription_liste_ue) Algorithme : 1 - Création ou récupération du dossier de l'apprenant 2 - Inscription de l'apprenant à promotion concernée +3 - Ajouter les pièce jointes : ajouter 'tab_related_collection' au 'download_files' + add : related_collection = {'inscription', 'related_collection_id' : isncription_id} """ def Candidat_Inscrire_To_Session(diction): try: @@ -2972,7 +2974,7 @@ def Candidat_Inscrire_To_Session(diction): """ field_list = ['token', 'list_candidat_id', 'admission_session_id', 'session_id', 'type_apprenant' , 'modefinancement', - 'client_rattachement_id', 'tab_ue_ids'] + 'client_rattachement_id', 'tab_ue_ids', 'statut_inscription'] incom_keys = diction.keys() for val in incom_keys: @@ -2985,7 +2987,7 @@ def Candidat_Inscrire_To_Session(diction): Verification des champs obligatoires """ field_list_obligatoire = ['token', 'list_candidat_id', 'admission_session_id', 'session_id', - 'type_apprenant' ] + 'type_apprenant' , 'statut_inscription'] for val in field_list_obligatoire: if val not in diction: @@ -3034,14 +3036,38 @@ def Candidat_Inscrire_To_Session(diction): - # Verifier que le type d'apprenant est bien valide - type_apprenant = "0" - if( str(diction['type_apprenant']) not in MYSY_GV.INSCRIPTION_TYPE_APPRENANT ): + if( "statut_inscription" in diction.keys() and diction['statut_inscription'] not in ['', '1', '0']): mycommon.myprint( - str(inspect.stack()[0][3]) + " Le type d'apprenant est invalide ") - return False, " Le type d'apprenant est invalide " - else: - type_apprenant = str(diction['type_apprenant']) + str(inspect.stack()[0][3]) + "Le statut d'inscription est invalide ") + return False, " Le statut d'inscription est invalide " + + # Verifier que le type d'apprenant est bien valide + if ( "type_apprenant" in diction.keys() and str(diction['type_apprenant']) ): + is_valide_type_apprenant = MYSY_GV.dbname['type_apprenant'].count_documents({'_id':ObjectId( str(diction['type_apprenant'])), + 'partner_owner_recid':str(my_partner['recid']), + 'valide':'1', + 'locked':'0'}) + + if( is_valide_type_apprenant != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le type d'apprenant est invalide ") + return False, " Le type d'apprenant est invalide " + + + # Verifier que le mode de finance est bien valide + if ("modefinancement" in diction.keys() and str(diction['modefinancement'])): + is_valide_modefinancementt = MYSY_GV.dbname['financement_mode'].count_documents( + {'_id': ObjectId(str(diction['modefinancement'])), + 'partner_owner_recid': str(my_partner['recid']), + 'valide': '1', + 'locked': '0'}) + + if (is_valide_modefinancementt != 1): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le mode de financement est invalide ") + return False, " Le mode de financement est invalide " + + # Verifier la validité du client, s'il ya un client @@ -3183,6 +3209,7 @@ def Candidat_Inscrire_To_Session(diction): candidat_data['matricule'] = str(apprenant_matricule) + candidat_data['admission_session_inscrit_id'] = str(candidat_id) result = MYSY_GV.dbname['apprenant'].find_one_and_update( {'email': candidat_data['email'], @@ -3243,15 +3270,44 @@ def Candidat_Inscrire_To_Session(diction): if( "tab_ue_ids" in diction.keys() ): local_diction['tab_ue_ids'] = str(diction['tab_ue_ids']) - print(" ### local_diction inscription apprenant = ", local_diction) - local_status, local_retval = apprenant_mgt.Apprenant_Inscrire_Session(local_diction) + if( "statut_inscription" in diction.keys() and diction['statut_inscription'] == "1"): + local_diction['statut_inscription'] = "1" + else: + local_diction['statut_inscription'] = "0" + + #print(" ### local_diction inscription apprenant = ", local_diction) + local_status, local_retval, local_inscrit_id = apprenant_mgt.Internal_Apprenant_Inscrire_Session_Ret_id(local_diction) if( local_status is False ): is_warning_message = True - warning_message = "\n impossible d'inscrire l'apprenant : " + str(apprenant_data['email']) + " " + warning_message = "\n Impossible d'inscrire l'apprenant : " + str(apprenant_data['email']) + " " + + else: + + for download_files_data in MYSY_GV.dbname['download_files'].find({'object_owner_collection':'admission_session_inscrit_document', + 'object_owner_id':str(apprenant_data['admission_session_inscrit_id'])}): + new_related_collection = { + "related_collection": "inscription", + "related_collection_id": str(local_inscrit_id) + } + + qry = { + "_id": ObjectId(str(download_files_data['_id'])), + "partner_owner_recid": str(my_partner["recid"]), + "valide": "1" + } + + update = { + "$addToSet": { + "tab_related_collection": new_related_collection + } + } + + result = MYSY_GV.dbname['download_files'].update_one(qry, update) """ Mettre à jour le candidat pour dire qu'il a été inscrit + """ for candidat_id in list_candidat_ids: candidat_data = MYSY_GV.dbname['admission_session_inscrit'].find_one(