03/06/2025 - 20h

Signed-off-by: Cherif <cbalde@mysy-training.com>
master_Elyos_FI
Cherif 2025-06-03 22:30:33 +02:00
parent 8b0f29583a
commit 2a5327fc88
6 changed files with 577 additions and 44 deletions

View File

@ -4,29 +4,12 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="31/05/2025 - 20h">
<change afterPath="$PROJECT_DIR$/reference_pedagogique_mgt.py" afterDir="false" />
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="02/06/2025 - 20h">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Activite.py" beforeDir="false" afterPath="$PROJECT_DIR$/Activite.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Doc_tech/spec.txt" beforeDir="false" afterPath="$PROJECT_DIR$/Doc_tech/spec.txt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/E_Sign_Document.py" beforeDir="false" afterPath="$PROJECT_DIR$/E_Sign_Document.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Inscription_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/Inscription_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Job_Cron_Common.py" beforeDir="false" afterPath="$PROJECT_DIR$/Job_Cron_Common.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Session_Formation.py" beforeDir="false" afterPath="$PROJECT_DIR$/Session_Formation.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/attached_file_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/attached_file_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/base_class_calcul_note.py" beforeDir="false" afterPath="$PROJECT_DIR$/base_class_calcul_note.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/base_document_automatic_setup.py" beforeDir="false" afterPath="$PROJECT_DIR$/base_document_automatic_setup.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/class_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/class_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/competence.py" beforeDir="false" afterPath="$PROJECT_DIR$/competence.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/crm_opportunite.py" beforeDir="false" afterPath="$PROJECT_DIR$/crm_opportunite.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/financial_caracteristique_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/financial_caracteristique_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/formulaire_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/formulaire_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/jury_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/jury_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lms_chamilo/mysy_lms.py" beforeDir="false" afterPath="$PROJECT_DIR$/lms_chamilo/mysy_lms.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/note_evaluation_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/note_evaluation_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/partner_client.py" beforeDir="false" afterPath="$PROJECT_DIR$/partner_client.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/prj_common.py" beforeDir="false" afterPath="$PROJECT_DIR$/prj_common.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/survey_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/survey_mgt.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
@ -72,7 +55,7 @@
&quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;git-widget-placeholder&quot;: &quot;master__Elyos__FI&quot;,
&quot;last_opened_file_path&quot;: &quot;C:/Users/Cherif/Documents/myclass.com/Siteweb/Elyos_Ftion_Initiale/Ela_back/Back_Office_FI&quot;,
&quot;last_opened_file_path&quot;: &quot;C:/Users/Cherif/Documents/myclass.com/Siteweb/Elyos_Ftion_Continue/Ela_back/Back_Office&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;project.propVCSSupport.CommitDialog&quot;
}
}</component>
@ -468,7 +451,7 @@
<option name="project" value="LOCAL" />
<updated>1747251650255</updated>
</task>
<option name="localTasksCounter" value="465" />
<option name="localTasksCounter" value="466" />
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
@ -510,7 +493,6 @@
</option>
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="10/02/205 - 21h" />
<MESSAGE value="11/02/2025 - 15h30" />
<MESSAGE value="11/02/2025 - 21h" />
<MESSAGE value="18/02/2025 - 21h" />
@ -535,6 +517,7 @@
<MESSAGE value="Init - 29/05/2025" />
<MESSAGE value="Init - 29/05/2025 - FI" />
<MESSAGE value="31/05/2025 - 20h" />
<option name="LAST_COMMIT_MESSAGE" value="31/05/2025 - 20h" />
<MESSAGE value="02/06/2025 - 20h" />
<option name="LAST_COMMIT_MESSAGE" value="02/06/2025 - 20h" />
</component>
</project>

View File

@ -63,7 +63,7 @@ def Add_Update_SessionFormation(diction):
'class_internal_url', 'session_status', 'date_debut_inscription', 'date_fin_inscription',
'attestation_certif', "distantiel", "presentiel", "prix_session", 'contenu_ftion', 'lms_class_code',
'session_ondemande', 'source', 'session_id', 'session_etape', 'pays', 'formateur_id',
'titre', 'location_type', 'is_bpf', 'site_formation_id', 'price_by', 'mode_animation']
'titre', 'location_type', 'is_bpf', 'site_formation_id', 'price_by', 'mode_animation', 'archive']
incom_keys = diction.keys()
for val in incom_keys:
@ -223,6 +223,12 @@ def Add_Update_SessionFormation(diction):
mydata['session_ondemande'] = "0"
if ("archive" in diction.keys()):
mydata['archive'] = str(diction['archive'])
else:
mydata['archive'] = "0"
if ("nb_participant" in diction.keys()):
nb_particants = str(mycommon.tryInt(str(diction['nb_participant'])))
if( nb_particants == "0" ):
@ -880,6 +886,9 @@ def GetSessionFormation(diction):
if ("automatic_traitement" not in user.keys() ):
user['automatic_traitement'] = []
if ("archive" not in user.keys() ):
user['archive'] = "0"
if ('myclass' in retval.keys() and len(retval['myclass']) > 0):
if ("_id" in retval['myclass'][0].keys()):
@ -1079,6 +1088,9 @@ def Get_Given_SessionFormation_From_Id(diction):
class_ispublished = "0"
class_lms_class_code = ""
if( "archive" not in user.keys() ):
user['user'] = "0"
if ('myclass' in retval.keys() and len(retval['myclass']) > 0):
if ("_id" in retval['myclass'][0].keys()):
@ -1110,7 +1122,6 @@ def Get_Given_SessionFormation_From_Id(diction):
if ("invoiced_statut" in retval.keys() ):
user['invoiced_statut'] = retval['invoiced_statut']
else:
user['invoiced_statut'] = "0"
@ -1195,7 +1206,7 @@ Donc faire attention au controle de la connexion
def GetActiveSessionFormation_List(diction):
try:
field_list = ['token', 'class_internal_url']
field_list = ['token', 'class_internal_url', 'archive']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
@ -1219,6 +1230,12 @@ def GetActiveSessionFormation_List(diction):
if (local_status is not True):
return local_status, my_partner
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'}
# Recuperation du recid du partner
mydata = {}
@ -1240,9 +1257,13 @@ def GetActiveSessionFormation_List(diction):
RetObject = []
print(" ### GetActiveSessionFormation_List myquery = ", myquery)
for retval in coll_session.find(myquery):
for retval in coll_session.find({"$and":[myquery,filt_archive]} ):
local_tmp = retval
if ("archive" not in local_tmp.keys()):
local_tmp['user'] = "0"
## Verification des conditions supplementaires :
# en realité c'est parce que c'est chaud de le faire avec pymongo
tmp_debut_inscritp = str(local_tmp['date_debut_inscription']).strip().split(" ")
@ -1320,14 +1341,18 @@ def Get_Partner_Session_Ftion_Reduice_Fields(diction):
my_partner['scope']['class_id']) > 0):
filt_scope_class_id['class_id'] = {'$in': my_partner['scope']['class_id']}
filt_archive = {}
if ("archive" in diction.keys() and (diction["archive"] == "0" or diction["archive"] == "")):
filt_archive = {'archive': {'$ne': '1'}}
RetObject = []
elif ("archive" in diction.keys() and diction["archive"] == "1"):
filt_archive = {'archive': '1'}
RetObject = []
val_tmp = 0
for retval in MYSY_GV.dbname['session_formation'].find({ "$and" : [ {'partner_owner_recid':str(my_partner['recid']),
'valide':'1',},filt_scope_class_id]},
'valide':'1',},filt_scope_class_id, filt_archive]},
{'_id':1, 'code_session':1, 'titre':1,
'class_internal_url':1, 'date_debut':1,
'date_fin':1}):
@ -1460,7 +1485,7 @@ Qu'elles soient cloturées ou pas."""
def GetAllValideSessionFormation_List(diction):
try:
field_list = ['token', 'class_internal_url']
field_list = ['token', 'class_internal_url', 'archive']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
@ -1490,6 +1515,17 @@ def GetAllValideSessionFormation_List(diction):
if diction['class_internal_url']:
class_internal_url = diction['class_internal_url']
filt_archive = {}
if ("archive" in diction.keys() and str(diction['archive']) == "1"):
filt_archive = {'archive': '1'}
elif ("archive" in diction.keys() and (str(diction['archive']) == "0" or str(diction['archive']) == "")):
filt_archive = {'archive': {'$ne': '1'}}
elif ("archive" not in diction.keys()):
filt_archive = {'archive': {'$ne': '1'}}
coll_session = MYSY_GV.dbname['session_formation']
myquery = {}
myquery['class_internal_url'] = class_internal_url
@ -1499,7 +1535,7 @@ def GetAllValideSessionFormation_List(diction):
print(" ##### myquery tt = "+str(myquery))
RetObject = []
for retval in coll_session.find(myquery):
for retval in coll_session.find({"$and": [myquery,filt_archive]}):
#print(" ##### retval = " + str(retval))
RetObject.append(mycommon.JSONEncoder().encode(retval))
@ -1518,7 +1554,7 @@ Cette fonction recupere toutes les sessions de formation d'un partenaire
def GetAllValideSessionPartner_List(diction):
try:
field_list = ['token']
field_list = ['token', 'archive']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
@ -1548,8 +1584,16 @@ def GetAllValideSessionPartner_List(diction):
if (local_status is not True):
return local_status, my_partner
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'}
"""
Filtre uniquement pour la Formation continue
Filtre uniquement pour la Formation Initiale
"""
filt_scope_class_id = {}
if ("scope" in my_partner.keys() and "class_id" in my_partner['scope'].keys() and len(
@ -1560,7 +1604,7 @@ def GetAllValideSessionPartner_List(diction):
filt_class_partner_recid = {'partner_owner_recid': str(my_partner['recid'])}
query = [{'$match':{ "$and" : [{'partner_owner_recid':str(my_partner['recid'])},filt_scope_class_id]} },
query = [{'$match':{ "$and" : [{'partner_owner_recid':str(my_partner['recid'])},filt_scope_class_id, filt_archive]} },
{ '$sort': {'_id': -1}},
{'$lookup':
{
@ -1615,6 +1659,11 @@ def GetAllValideSessionPartner_List(diction):
else:
val['is_bpf'] = ""
if ("archive" in retVal.keys()):
val['archive'] = retVal['archive']
else:
val['archive'] = ""
if ("session_status" in retVal.keys()):
val['session_status'] = retVal['session_status']
@ -1855,7 +1904,7 @@ def GetAllValideSessionPartner_List_filter_like(diction):
field_list = ['token','class_title', 'code_session', 'class_external_code',
'session_start_date', 'session_end_date',
'class_internal_url']
'class_internal_url', 'archive']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
@ -1926,8 +1975,18 @@ def GetAllValideSessionPartner_List_filter_like(diction):
inspect.stack()[0][3]) + " Le filtre : 'date de fin de session' n'est pas au format jj/mm/aaaa.")
return False, " Le filtre : 'date de fin de session' n'est pas au format jj/mm/aaaa."
filt_archive = {}
if ("archive" in diction.keys() and str(diction['archive']) == "1"):
filt_archive = {'archive': '1'}
elif ("archive" in diction.keys() and (str(diction['archive']) == "0" or str(diction['archive']) == "")):
filt_archive = {'archive': {'$ne': '1'}}
elif ("archive" not in diction.keys()):
filt_archive = {'archive': {'$ne': '1'}}
"""
Filtre uniquement pour la Formation continue
Filtre uniquement pour la Formation Initiale
"""
filt_scope_class_id = {}
if ("scope" in my_partner.keys() and "class_id" in my_partner['scope'].keys() and len(
@ -1937,7 +1996,7 @@ def GetAllValideSessionPartner_List_filter_like(diction):
coll_session = MYSY_GV.dbname['session_formation']
query = [ {'$match':{ '$and' : [ filt_code_session,{'partner_owner_recid':str(my_partner['recid'])}, filt_scope_class_id] }} ,
query = [ {'$match':{ '$and' : [ filt_code_session,{'partner_owner_recid':str(my_partner['recid'])}, filt_scope_class_id, filt_archive] }} ,
{'$sort': {'_id': -1}},
{'$lookup':
{
@ -1984,6 +2043,10 @@ def GetAllValideSessionPartner_List_filter_like(diction):
else:
val['is_bpf'] = ""
if ("archive" in retVal.keys()):
val['archive'] = retVal['archive']
else:
val['archive'] = ""
if( "session_etape" in retVal.keys()):
val['session_etape'] = retVal['session_etape']
@ -2260,7 +2323,7 @@ Recuperation de la liste sans filtre
def GetAllValideSessionPartner_List_no_filter(diction):
try:
field_list = ['token','class_title', 'code_session']
field_list = ['token','class_title', 'code_session', 'archive']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
@ -2290,10 +2353,19 @@ def GetAllValideSessionPartner_List_no_filter(diction):
if (local_status is not True):
return local_status, my_partner
filt_archive = {}
if ("archive" in diction.keys() and str(diction['archive']) == "1"):
filt_archive = {'archive': '1'}
elif ("archive" in diction.keys() and (str(diction['archive']) == "0" or str(diction['archive']) == "")):
filt_archive = {'archive': {'$ne': '1'}}
elif ("archive" not in diction.keys()):
filt_archive = {'archive': {'$ne': '1'}}
coll_session = MYSY_GV.dbname['session_formation']
query = [{'$match':{'partner_owner_recid': str(my_partner['recid'])} },
query = [{'$match':{"$and": [{'partner_owner_recid': str(my_partner['recid'])}, filt_archive]} },
{'$lookup':
{
'from': 'myclass',
@ -2337,6 +2409,10 @@ def GetAllValideSessionPartner_List_no_filter(diction):
else:
val['is_bpf'] = ""
if ("archive" in retVal.keys()):
val['archive'] = retVal['archive']
else:
val['archive'] = ""
if( "session_etape" in retVal.keys()):
val['session_etape'] = retVal['session_etape']
@ -10663,6 +10739,7 @@ def Prepare_and_Send_Facture_From_Session_By_Inscription_Id(tab_files, Folder, d
if (local_status is not True):
return local_status, my_partner, False
liste_client_client_rattachement_id = []
my_inscription_ids = ""
tab_my_inscription_ids = []
tab_my_inscription_ids_Object = []
@ -14910,3 +14987,198 @@ def Get_Given_SessionFormation_List_Automatic_Traitement_From(diction):
return False, "Impossible de récupérer La promotion de formation"
"""
02/06/2025 : Archivage d'une session
"""
def archive_session(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_session_id', '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, Creation formation annulée")
return False, " Impossible de mettre à jour la formation"
'''
Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
On controle que les champs obligatoires sont presents dans la liste
'''
field_list_obligatoire = ['tab_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, " 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_session_ids = []
tab_session_ids_ObjectId = []
if ("tab_session_id" in diction.keys()):
tab_session_ids = str(diction['tab_session_id']).split(",")
for tmp in tab_session_ids:
if (tmp):
tab_session_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['date_update'] = str(datetime.now())
mydata['update_by'] = str(my_partner['_id'])
mydata['archive'] = '1'
coll_name = MYSY_GV.dbname['session_formation']
# seules les formations avec locked = 0 et valide=1 sont modifiables
ret_val = coll_name.update_many(
{'_id': {'$in': tab_session_ids_ObjectId}, 'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])},
{"$set": mydata},
)
for session_id in tab_session_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'] = "session_formation"
history_event_dict['related_collection_recid'] = str(session_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, " Promotion(s) archivé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'archiver les sessions "
"""
02/06/2025 : De-Archivage d'une session
"""
def unarchive_session(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_session_id', '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, Creation formation annulée")
return False, " Impossible de mettre à jour la formation"
'''
Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
On controle que les champs obligatoires sont presents dans la liste
'''
field_list_obligatoire = ['tab_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, " 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_session_ids = []
tab_session_ids_ObjectId = []
if ("tab_session_id" in diction.keys()):
tab_session_ids = str(diction['tab_session_id']).split(",")
for tmp in tab_session_ids:
if (tmp):
tab_session_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['date_update'] = str(datetime.now())
mydata['update_by'] = str(my_partner['_id'])
mydata['archive'] = '0'
coll_name = MYSY_GV.dbname['session_formation']
# seules les formations avec locked = 0 et valide=1 sont modifiables
ret_val = coll_name.update_many(
{'_id': {'$in': tab_session_ids_ObjectId}, 'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])},
{"$set": mydata},
)
for session_id in tab_session_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'] = "session_formation"
history_event_dict['related_collection_recid'] = str(session_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, " Promotion(s) desarchivé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'archiver les sessions "

View File

@ -3771,6 +3771,9 @@ def find_partner_class_like(diction):
elif ("archive" in diction.keys() and (str(diction['archive']) == "0" or str(diction['archive']) == "") ):
filt_archive = {'archive':{'$ne':'1'}}
elif( "archive" not in diction.keys()):
filt_archive = {'archive': {'$ne': '1'}}
filt_internal_url = {}
if ("internal_url" in diction.keys()):
@ -3781,7 +3784,7 @@ def find_partner_class_like(diction):
{'partner_owner_recid': user_recid},
filt_external_code, filt_title, filt_internal_url, filt_archive]}
#print(" ### find_partner_class_like_local_qry = ", find_partner_class_like_local_qry)
print(" ### find_partner_class_like_local_qry = ", find_partner_class_like_local_qry)
"""
Recuperation du nombre d'heure par jour depuis la confif du partner

View File

@ -152,7 +152,7 @@ def Add_Update_Question_Formulaire(diction):
Verification des input acceptés
"""
field_list = ['token', 'form_id', 'question_id', 'question', 'type', 'commentaire', 'list_choix', 'max_note',
'list_qcm', 'list_case_cocher', 'is_statistic' ]
'list_qcm', 'list_case_cocher', 'is_statistic', 'is_alert', 'alert_seuil' ]
incom_keys = diction.keys()
for val in incom_keys:
@ -274,6 +274,16 @@ def Add_Update_Question_Formulaire(diction):
else:
new_data['is_statistic'] = "0"
if ("is_alert" in diction.keys() and str(diction['is_alert']).strip() in ['0', '1'] ):
new_data['is_alert'] = str(diction['is_alert']).strip()
else:
new_data['is_alert'] = "0"
if ("alert_seuil" in diction.keys()):
new_data['alert_seuil'] = str(diction['alert_seuil'])
else:
new_data['alert_seuil'] = ""
tab_list_choix = []
if ("list_choix" in diction.keys() and str(diction['type']) == "qcm"):

27
main.py
View File

@ -2296,6 +2296,33 @@ def Get_Given_SessionFormation_List_Automatic_Traitement_From():
return jsonify(status=localStatus, message=message )
"""
API qui permet d'archiver une liste de session de formation
"""
@app.route('/myclass/api/archive_session/', methods=['POST','GET'])
@crossdomain(origin='*')
def archive_session():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### archive_session : payload = ",str(payload))
localStatus, message= SF.archive_session(payload)
return jsonify(status=localStatus, message=message )
"""
API qui permet de déarchiver une liste de session de formation
"""
@app.route('/myclass/api/unarchive_session/', methods=['POST','GET'])
@crossdomain(origin='*')
def unarchive_session():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### unarchive_session : payload = ",str(payload))
localStatus, message= SF.unarchive_session(payload)
return jsonify(status=localStatus, message=message )
"""
API de recuperation de toutes les sessions de formation valides et actives

View File

@ -303,6 +303,10 @@ def Record_Survey_Data_No_Token(diction):
"""
question_is_statistic = ""
question_type = ""
question_is_alert = ""
question_alert_seuil = ""
for local_question in form_list_question :
if( str(local_question['_id']) == str(question_id) and "is_statistic" in local_question.keys() ):
question_is_statistic = local_question['is_statistic']
@ -310,15 +314,21 @@ def Record_Survey_Data_No_Token(diction):
if (str(local_question['_id']) == str(question_id) and "type" in local_question.keys()):
question_type = local_question['type']
if (str(local_question['_id']) == str(question_id) and "is_alert" in local_question.keys()):
question_is_alert = local_question['is_alert']
if (str(local_question['_id']) == str(question_id) and "alert_seuil" in local_question.keys()):
question_alert_seuil = local_question['alert_seuil']
node['is_statistic'] = question_is_statistic
node['type'] = question_type
node['is_alert'] = question_is_alert
node['alert_seuil'] = question_alert_seuil
global_response.append(node)
"""
On va enregister les reponse et changer le statut
"""
@ -339,6 +349,15 @@ def Record_Survey_Data_No_Token(diction):
" Impossible de mettre à jour le formulaire (2) ")
return False, " Impossible de mettre à jour le formulaire (2) "
local_diction = {}
local_diction['global_response'] = global_response
local_diction['class_id'] = str(survey_data['class_id'])
local_diction['session_id'] = str(survey_data['session_id'])
local_diction['survey_type'] = str(survey_data['_id'])
local_diction['formulaire_id'] = str(survey_data['formulaire_id'])
local_diction['partner_owner_recid'] = str(survey_data['partner_owner_recid'])
retval_status, retval = Survey_Send_Notification_Sur_Seuil_Alert(local_diction)
return True, " Le formulaire a été correctement mis à jour"
@ -349,13 +368,232 @@ def Record_Survey_Data_No_Token(diction):
return False, " Impossible d'enregister les informations "
"""
Cette fonction permet de declencer l'envoie d'un email de notification si
un seuil d'alert est atteint dans un questionnaire
"""
def Survey_Send_Notification_Sur_Seuil_Alert(diction):
try:
field_list_obligatoire = ['global_response', 'class_id', 'session_id', 'survey_type', 'formulaire_id', 'partner_owner_recid']
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"
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
"""
Recuperation des données du formulaire
"""
form_data_qry = {'valide': '1', 'locked': '0', '_id': ObjectId(str(diction['formulaire_id'])),
'partner_owner_recid': str(diction['partner_owner_recid'])}
form_data = MYSY_GV.dbname['formulaire'].find_one(form_data_qry)
if (form_data is None):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant du formulaire est invalide ")
return False, " L'identifiant du formulaire est invalide "
"""
Recuperer les données questionnaire
"""
session_data_qry = {'valide': '1', 'locked': '0', '_id': ObjectId(str(diction['session_id'])),
'partner_owner_recid': str(diction['partner_owner_recid'])}
session_data = MYSY_GV.dbname['session_formation'].find_one(session_data_qry)
if (form_data 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 "
# Creation du dictionnaire d'information à utiliser pour la creation du doc
convention_dictionnary_data = {}
new_diction = {}
new_diction['token'] = str(my_partner['token'])
new_diction['list_stagiaire_id'] = []
new_diction['list_session_id'] = [ObjectId(str(diction['session_id']))]
new_diction['list_class_id'] = [ObjectId(str(diction['class_id']))]
new_diction['list_client_id'] = []
new_diction['list_apprenant_id'] = []
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
survey_type = ""
if( diction['survey_type'] == "pos"):
survey_type = "Questionnaire de positionnement"
elif (diction['survey_type'] == "cold_eval"):
survey_type = "Questionnaire d'évaluation à froid"
elif (diction['survey_type'] == "hot_eval"):
survey_type = "Questionnaire d'évaluation à chaud"
elif (diction['survey_type'] == "human_eval"):
survey_type = "Questionnaire d'évaluation personnel"
convention_dictionnary_data['survey_type'] = survey_type
convention_dictionnary_data['partner_owner_recid'] = str(diction['partner_owner_recid'])
diction_notif_mail = convention_dictionnary_data
for val in diction['global_response']:
if("is_alert" in val.keys() and val['is_alert'] == "1" ):
print(" ## on fait un controle")
if( val['type'] == "bool" ):
seuil = val['alert_seuil']
valeur = ""
if( val['response'] == "oui"):
valeur = "1"
else:
valeur = "0"
if( seuil == valeur):
print(" ### DECLENCHEMENT MESSAGE D'ALERT")
convention_dictionnary_data['user_question_reponse'] = val
notif_status, notif_retval = Send_Survey_Alert_Notif(convention_dictionnary_data)
elif( val['type'] == "note" ):
seuil = mycommon.tryFloat(val['alert_seuil'])
valeur = mycommon.tryFloat(val['response'])
if( valeur <= seuil):
print(" ### DECLENCHEMENT MESSAGE D'ALERT")
convention_dictionnary_data['user_question_reponse'] = val
notif_status, notif_retval = Send_Survey_Alert_Notif(convention_dictionnary_data)
return True, " Traitement Survey_Send_Notification_Sur_Seuil_Alert"
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 formulaire "
"""
Cette fonction envoi l'email de notification en cas d'alert sur
seuil de réponse
"""
def Send_Survey_Alert_Notif(diction):
try:
field_list_obligatoire = [ 'user_question_reponse', 'partner_owner_recid']
print(" ### Send_Survey_Alert_Notif diction = ", diction)
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"
body = {
"params": diction,
}
"""
Recuperer le modèle de document
"""
local_diction = {}
local_diction['ref_interne'] = "SURVEY_RESPONSE_NOTIF"
local_diction['type_doc'] = "email"
local_diction['partner_owner_recid'] = str(diction['partner_owner_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
if ("corps_mail" not in courrier_data_retval.keys() or str(courrier_data_retval['corps_mail']) == ""):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Le modèle de courrier 'SURVEY_RESPONSE_NOTIF' n'est pas correctement configuré - corps_mail ")
return False, " Le modèle de courrier 'SURVEY_RESPONSE_NOTIF' n'est pas correctement configuré - corps_mail "
# 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(str(diction['partner_owner_recid']))
if (local_stpm_status is False):
return local_stpm_status, partner_own_smtp_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)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.login(MYSY_GV.O365_SMTP_COUNT_user, MYSY_GV.O365_SMTP_COUNT_password)
# 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_corp_mail_Template = jinja2.Template(str(courrier_data_retval['corps_mail']))
sourceHtml_corps_mail = contenu_corp_mail_Template.render(params=body["params"])
html_mime = MIMEText(sourceHtml_corps_mail, 'html')
email_to = ['cbalde@mysy-training.com']
# 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
toaddrs = ",".join(email_to)
msg['to'] = str(toaddrs)
val = smtpserver.send_message(msg)
print(" Email de notification envoyé " + str(val))
else:
msg.attach(html_mime)
msg['From'] = MYSY_GV.O365_SMTP_COUNT_From_User
msg['Bcc'] = 'contact@mysy-training.com'
msg['Subject'] = sujetHtml
toaddrs = ",".join(email_to)
msg['to'] = str(toaddrs)
val = smtpserver.send_message(msg)
print(" Email de notification envoyé " + str(val))
smtpserver.close()
return True, " Send_Survey_Alert_Notif "
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 formulaire "
"""
Survey for enduser : Cette fonction créer une enquete en prenant à partir d'une liste d'inscrit
/!\ : Cette fonction ne concerne uniquement et exclusibement les inscriptions validées (status = 1)
"""
def Add_Survey_Tab_Inscrit(diction):