07/12/2023 - 11h30

master
cherif 2023-12-07 11:39:44 +01:00
parent 02f8764944
commit 3ce34be67e
7 changed files with 1660 additions and 23 deletions

View File

@ -1,13 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="05/12/2023 - 21h">
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="06/12/2023 - 21h">
<change afterPath="$PROJECT_DIR$/Collection_Historique.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/GlobalVariable.py" beforeDir="false" afterPath="$PROJECT_DIR$/GlobalVariable.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Inscription_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/Inscription_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Log/log_file.log" beforeDir="false" afterPath="$PROJECT_DIR$/Log/log_file.log" afterDir="false" />
<change beforePath="$PROJECT_DIR$/agenda.py" beforeDir="false" afterPath="$PROJECT_DIR$/agenda.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/partner_document_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/partner_document_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/prj_common.py" beforeDir="false" afterPath="$PROJECT_DIR$/prj_common.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -77,13 +78,6 @@
<option name="presentableId" value="Default" />
<updated>1680804787304</updated>
</task>
<task id="LOCAL-00114" summary="26/09/23 - 23h">
<created>1695805016861</created>
<option name="number" value="00114" />
<option name="presentableId" value="LOCAL-00114" />
<option name="project" value="LOCAL" />
<updated>1695805016862</updated>
</task>
<task id="LOCAL-00115" summary="28/09/23 - 23h">
<created>1695932550732</created>
<option name="number" value="00115" />
@ -420,7 +414,14 @@
<option name="project" value="LOCAL" />
<updated>1701809248689</updated>
</task>
<option name="localTasksCounter" value="163" />
<task id="LOCAL-00163" summary="06/12/2023 - 21h">
<created>1701892535755</created>
<option name="number" value="00163" />
<option name="presentableId" value="LOCAL-00163" />
<option name="project" value="LOCAL" />
<updated>1701892535756</updated>
</task>
<option name="localTasksCounter" value="164" />
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
@ -435,7 +436,6 @@
</option>
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="23/10/2023 - 16h" />
<MESSAGE value="30/10/23 - 16h" />
<MESSAGE value="08/11/2023 - 23h" />
<MESSAGE value="09/11/2023 - 23h" />
@ -460,6 +460,7 @@
<MESSAGE value="01/12/2023 - 23h" />
<MESSAGE value="04/12/2023 - 21h" />
<MESSAGE value="05/12/2023 - 21h" />
<option name="LAST_COMMIT_MESSAGE" value="05/12/2023 - 21h" />
<MESSAGE value="06/12/2023 - 21h" />
<option name="LAST_COMMIT_MESSAGE" value="06/12/2023 - 21h" />
</component>
</project>

232
Collection_Historique.py Normal file
View File

@ -0,0 +1,232 @@
"""
Ce fichier permet de gerer les historique des evenements pour une collection.
L'idée est qu'a travers ce module on puisse voir toutes les actions loggué pour une collection id.
Ce module permet de logguer et de recuperer des event.
"""
import bson
import pymongo
from pymongo import MongoClient
import json
from bson import ObjectId
import re
from datetime import datetime
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
import ela_index_bdd_classes as eibdd
import email_mgt as email
import jinja2
from flask import send_file
from xhtml2pdf import pisa
from email.message import EmailMessage
from email.mime.text import MIMEText
from email import encoders
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
"""
Pour un ajout, sont pris en compte :
- related_collection ==> Collection concercée
- l'id de l'entité dans la collection
- attached_doc_id (si une pièce jointe est enregistrée dans la collection : download_files)
- action_date : Date à la quelle l'action a été faite. La date doit etre au format : d/%m/%Y %H:%M:%S
/!\ : Il n'y pas d'update. Pour corriger un event, il faut logguer un autre event
"""
def Add_Historique_Event(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'related_collection', 'related_collection_recid', 'attached_doc_id', 'action_date',
'action_description']
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', 'related_collection', 'related_collection_recid', 'action_date',
'action_description']
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 liste ")
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 l'action_date est bien au format: %d/%m/%Y %H:%M:%S
if( mycommon.CheckisDate_Hours_Second(str(diction['action_date'])) is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " La date de l'action doit être au format jj/mm/aaaa hh:mm:ss")
return False, " La date de l'action doit être au format jj/mm/aaaa hh:mm:ss"
# Verifier que 'related_collection_recid' existe et est valide dans la collection 'related_collection'
is_existe_valide_related_collection_recid = MYSY_GV.dbname[str(diction['related_collection'])].count_documents({'_id':ObjectId(str(diction['related_collection_recid'])),
'partner_owner_recid':str(my_partner['recid']),
})
if( is_existe_valide_related_collection_recid <= 0):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - L'identifiant du 'related_collection_recid' n'est pas valide ")
return False, " L'identifiant du 'related_collection_recid' n'est pas valide "
# Verifier l'existance de la pièce jointe (si pièce jointe) : attached_doc_id
if( 'attached_doc_id' in diction.keys() and diction['attached_doc_id']):
is_existe_valide_attached_doc_id = MYSY_GV.dbname['download_files'].count_documents(
{'_id': ObjectId(str(diction['attached_doc_id'])),
'partner_recid': str(my_partner['recid']),
'valide': '1',
'locked': '0'})
if (is_existe_valide_attached_doc_id <= 0):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - L'identifiant du 'is_existe_valide_attached_doc_id' n'est pas valide ")
return False, " L'identifiant du 'is_existe_valide_attached_doc_id' n'est pas valide "
# La description ne doit pas faire plus de 255 caractère
action_description = ""
if('action_description' in diction.keys() and diction['action_description']):
action_description = diction['action_description']
if(len(str(action_description)) > 255 ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La description de l'historique d'évènement fait plus de 255 caractères ")
return False, " La description de l'historique d'évènement fait plus de 255 caractères "
mydata = diction
if 'token' in mydata:
del mydata['token']
mydata['partner_owner_recid'] = my_partner['recid']
mydata['connected_user_id'] = str(my_partner['_id'])
mydata['valide'] = "1"
mydata['locked'] = "0"
mydata['date_update'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
mydata['update_by'] = str(my_partner['_id'])
inserted_id = ""
inserted_id = MYSY_GV.dbname['historique_action'].insert_one(mydata).inserted_id
if (not inserted_id):
mycommon.myprint(
" Impossible d'ajouter l'historique d'évènement (1) ")
return False, " Impossible d'ajouter l'historique d'évènement (1) "
return True, " L'événement a été ajouté à l'historique"
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'ajouter l'historique d'évènement "
"""
Recupération de l'historique des actions associé à un element.
Un element est defini par :
- related_collection
- related_collection_recid
"""
def Get_Action_Historique_List(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'related_collection', 'related_collection_recid']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas")
return False, " Les informations fournies sont incorrectes",
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', 'related_collection', 'related_collection_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 liste ")
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 = 1
for New_retVal in MYSY_GV.dbname['historique_action'].find({'related_collection':str(diction['related_collection']), 'related_collection_recid':str(diction['related_collection_recid']),
'partner_owner_recid':str(my_partner['recid']), 'valide':'1', 'locked':'0'}).sort([("_id", pymongo.DESCENDING)]):
user = New_retVal
user['id'] = str(val_tmp)
# Recuperation de l'email du user qui fait l'action
connected_user_data = MYSY_GV.dbname['partnair_account'].find_one({'_id':ObjectId(str(New_retVal['connected_user_id'])), 'recid':str(my_partner['recid'])}, {'nom':1,'email':1 })
if( connected_user_data ):
user['connected_user_nom'] = connected_user_data['nom']
user['connected_user_email'] = connected_user_data['email']
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 évènements "

File diff suppressed because it is too large Load Diff

View File

@ -168,6 +168,8 @@ def Add_Update_Agenda_Event(diction):
mydata['locked'] = "0"
insert = MYSY_GV.dbname['agenda'].insert_one(mydata)
return True, " L'événement a été ajouté"
@ -192,7 +194,7 @@ def Add_Update_Agenda_Event_Stagiaire(diction):
Verification des input acceptés
"""
field_list = ['token', '_id', 'related_collection', 'event_title', 'event_start', 'event_end', 'comment',
'event_type', 'justified', 'related_collection_email']
'event_type', 'justified', 'related_collection_email', 'inscription_id']
incom_keys = diction.keys()
for val in incom_keys:
@ -244,6 +246,7 @@ def Add_Update_Agenda_Event_Stagiaire(diction):
str(inspect.stack()[0][3]) + " - L'identifiant du 'related_collection_recid' n'est pas valide ")
return False, " L'identifiant du 'related_collection_recid' n'est pas valide "
if (datetime.strptime(str(diction['event_start'])[0:16], '%Y-%m-%dT%H:%M') >= datetime.strptime(str(diction['event_end'])[0:16],
'%Y-%m-%dT%H:%M')):
mycommon.myprint(
@ -310,6 +313,31 @@ def Add_Update_Agenda_Event_Stagiaire(diction):
mydata['locked'] = "0"
insert = MYSY_GV.dbname['agenda'].insert_one(mydata)
# Recup de l'id de l'apprenant
inscription_id = ""
if( "inscription_id" in diction.keys() ):
inscription_id = str(diction['inscription_id'])
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(inscription_id)
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Absence du "+str( mydata['event_start'] )+" au "+str(mydata['event_end'])+" "
print(" ### 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))
return True, " L'événement a été ajouté"
@ -383,7 +411,7 @@ def get_Agenda_Event_List(diction):
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 evenement "
return False, " Impossible de récupérer la liste des evenements "
@ -444,7 +472,7 @@ def get_Agenda_Event_List_Stagiaire(diction):
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 evenement "
return False, " Impossible de récupérer la liste des évènements "
"""
@ -571,7 +599,7 @@ def get_Agenda_Event_List_With_Filter(diction):
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 evenement "
return False, " Impossible de récupérer la liste des evenements "
"""
@ -716,7 +744,7 @@ def get_Ressource_Info_Data(diction):
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 evenement "
return False, " Impossible de récupérer la liste des evenements "
"""
@ -782,4 +810,4 @@ def get_Ressource_Info_Data_Satgiaire(diction):
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 evenement "
return False, " Impossible de récupérer la liste des evenements "

33
main.py
View File

@ -65,6 +65,7 @@ import base_config_modele_journee as base_config_modele_journee
import Dashbord_queries.session_tbd_qries as session_tbd_qries
import Dashbord_queries.common_tdb_qries as common_tdb_qries
import Dashbord_queries.formation_tbd_qries as formation_tbd_qries
import Collection_Historique as Collection_Historique
app = Flask(__name__)
cors = CORS(app, resources={r"/foo": {"origins": "*"}})
@ -5507,7 +5508,7 @@ def Get_Collection_Eligible_Champ_Specific():
"""
API de la recuperation de la liste des evenement dans l'agenda
API de la recuperation de la liste des evenements dans l'agenda
"""
@app.route('/myclass/api/get_Agenda_Event_List/', methods=['POST','GET'])
@crossdomain(origin='*')
@ -5520,7 +5521,7 @@ def get_Agenda_Event_List():
"""
API de la recuperation de la liste des evenement dans l'agenda pour un stagiaire
API de la recuperation de la liste des evenements dans l'agenda pour un stagiaire
"""
@app.route('/myclass/api/get_Agenda_Event_List_Stagiaire/', methods=['POST','GET'])
@crossdomain(origin='*')
@ -5534,7 +5535,7 @@ def get_Agenda_Event_List_Stagiaire():
"""
API de la recuperation de la liste des evenement dans l'agenda avec des filtre
API de la recuperation de la liste des evenements dans l'agenda avec des filtre
"""
@app.route('/myclass/api/get_Agenda_Event_List_With_Filter/', methods=['POST','GET'])
@crossdomain(origin='*')
@ -6041,6 +6042,32 @@ def Get_Qery_Formation_By_Session_By_Periode_Export_CSV(token, user_dashbord_id)
"""
API qui permet d'ajouter une action dans l'historique des évènements d'une entité
"""
@app.route('/myclass/api/Add_Historique_Event/', methods=['POST','GET'])
@crossdomain(origin='*')
def Add_Historique_Event():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Add_Historique_Event payload = ",payload)
status, retval = Collection_Historique.Add_Historique_Event(payload)
return jsonify(status=status, message=retval)
"""
API qui permet de recupérer la liste des actions l'historique des évènements d'une entité
"""
@app.route('/myclass/api/Get_Action_Historique_List/', methods=['POST','GET'])
@crossdomain(origin='*')
def Get_Action_Historique_List():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Get_Action_Historique_List payload = ",payload)
status, retval = Collection_Historique.Get_Action_Historique_List(payload)
return jsonify(status=status, message=retval)
if __name__ == '__main__':

View File

@ -165,6 +165,7 @@ def Add_Partner_Document(diction):
# Verifier qu'il n'existe pas un document avec le meme code code interne
exist_doc_count = MYSY_GV.dbname['courrier_template'].count_documents({'ref_interne':str(ref_interne), 'valide':'1',
'partner_owner_recid':str(my_partner['recid']),
'nom': str(nom),
'type_doc':str(diction['type_doc'])})
if( exist_doc_count > 0 ):

View File

@ -42,6 +42,7 @@ import pysftp
import html
import mariadb
from datetime import timedelta
import Collection_Historique as Collection_Historique
class JSONEncoder(json.JSONEncoder):
def default(self, o):
@ -746,7 +747,7 @@ def CheckisDate(mydate):
Cette fonction verifie si une chaine est de type date time jj/mm/aaaa hh:mm
'''
def CheckisDate_Hours(mydate):
# mydate doit etre au format : jj/mm/aaaa
# mydate doit etre au format : %d/%m/%Y %H:%M
try:
#print(" analyse de "+mydate)
val = datetime.strptime(str(mydate).strip(), '%d/%m/%Y %H:%M')
@ -758,6 +759,22 @@ def CheckisDate_Hours(mydate):
return False
'''
Cette fonction verifie si une chaine est de type date time jj/mm/aaaa hh:mm:ss
'''
def CheckisDate_Hours_Second(mydate):
# mydate doit etre au format :jj/mm/aaaa hh:mm:ss
try:
#print(" analyse de "+mydate)
val = datetime.strptime(str(mydate).strip(), '%d/%m/%Y %H:%M:%S')
return True
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False
'''