21/11/2023 - 12h00

master
cherif 2023-11-21 12:35:21 +01:00
parent 5c476e29d9
commit 3fc4dac28b
7 changed files with 2102 additions and 11 deletions

View File

@ -1,11 +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="18/11/2023 - 17h00">
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="20/11/2023 - 21h00">
<change afterPath="$PROJECT_DIR$/base_config_modele_journee.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Log/log_file.log" beforeDir="false" afterPath="$PROJECT_DIR$/Log/log_file.log" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Session_Formation_Sequence.py" beforeDir="false" afterPath="$PROJECT_DIR$/Session_Formation_Sequence.py" 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$/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" />
@ -75,13 +78,6 @@
<option name="presentableId" value="Default" />
<updated>1680804787304</updated>
</task>
<task id="LOCAL-00105" summary="14/09/2023 - 21h">
<created>1694717319294</created>
<option name="number" value="00105" />
<option name="presentableId" value="LOCAL-00105" />
<option name="project" value="LOCAL" />
<updated>1694717319295</updated>
</task>
<task id="LOCAL-00106" summary="15/09/2023 - 12h">
<created>1694773383427</created>
<option name="number" value="00106" />
@ -418,7 +414,14 @@
<option name="project" value="LOCAL" />
<updated>1700322992178</updated>
</task>
<option name="localTasksCounter" value="154" />
<task id="LOCAL-00154" summary="20/11/2023 - 21h00">
<created>1700513271611</created>
<option name="number" value="00154" />
<option name="presentableId" value="LOCAL-00154" />
<option name="project" value="LOCAL" />
<updated>1700513271611</updated>
</task>
<option name="localTasksCounter" value="155" />
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
@ -433,7 +436,6 @@
</option>
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="07/10/2023 - 22h40" />
<MESSAGE value="08/10/2023 - 22h40" />
<MESSAGE value="17/10/2023 - 22h40" />
<MESSAGE value="17/10/2023 - 22h45" />
@ -458,6 +460,7 @@
<MESSAGE value="15/11/2023 - 21h" />
<MESSAGE value="17/11/2023 - 16h" />
<MESSAGE value="18/11/2023 - 17h00" />
<option name="LAST_COMMIT_MESSAGE" value="18/11/2023 - 17h00" />
<MESSAGE value="20/11/2023 - 21h00" />
<option name="LAST_COMMIT_MESSAGE" value="20/11/2023 - 21h00" />
</component>
</project>

File diff suppressed because it is too large Load Diff

View File

@ -24,6 +24,7 @@ from pymongo import ReturnDocument
import GlobalVariable as MYSY_GV
from math import isnan
import GlobalVariable as MYSY_GV
from datetime import timedelta
import ela_index_bdd_classes as eibdd
import email_mgt as email
import jinja2
@ -38,6 +39,8 @@ from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import base_config_modele_journee as base_config_modele_journee
"""
Regles :
@ -126,6 +129,17 @@ def Add_Session_Sequence(diction):
date_fin_seq) + " n'est pas au format 'jj/mm/aaaa hh:mm'"
if (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)+" "
for retVal in MYSY_GV.dbname['session_formation_sequence'].find({'session_id': str(diction['session_id']),
'partner_owner_recid': str(my_partner['recid']),
'valide':'1',
@ -185,6 +199,222 @@ def Add_Session_Sequence(diction):
return False, " Impossible d'ajouter la séquence "
"""
Fonction de Creation automatique de sequence.
Pour certains utilisteurs, au lieu de créer manuellement chaque sequence,
ils laisse le système créer toutes les sequence.
Alogo :
1 - Si la session est valide, on supprime toutes les sequences existantes pour cette session (y compris les plannings)
2 - on prend en entrée le modele de journé à appliquer (heures de la journée, jours de la semaine)
"""
def Create_Automatic_Sequence(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'session_id', 'jounree_modele_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', 'session_id', 'jounree_modele_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 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
# Verification de l'existence et de la session
is_existe_valide_session_id = MYSY_GV.dbname["session_formation"].count_documents({'_id':ObjectId(str(diction['session_id'])),
'partner_owner_recid':str(my_partner['recid']),
'valide':'1'})
if( is_existe_valide_session_id <= 0):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - L'identifiant de la session n'est pas valide ")
return False, "L'identifiant de la session n'est pas valide "
# Verification de l'existence du modele de journée
is_existe_valide_journee_model_id = MYSY_GV.dbname["base_config_modele_journee"].count_documents(
{'_id': ObjectId(str(diction['jounree_modele_id'])),
'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked':'0'})
if (is_existe_valide_journee_model_id <= 0):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - L'identifiant du modèle de journee n'est pas valide ")
return False, " L'identifiant du modèle de journee n'est pas valide "
# Recuperation des data
is_existe_valide_journee_model_data= MYSY_GV.dbname["base_config_modele_journee"].find_one(
{'_id': ObjectId(str(diction['jounree_modele_id'])),
'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0'})
"""
for local_val in is_existe_valide_journee_model_data['tab_sequence']:
model_heure_debut = local_val['heure_debut']
model_heure_fin = local_val['heure_fin']
local_status = mycommon.CheckisDate_Hours(model_heure_debut)
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La date de debut de séquence " + str(
model_heure_debut) + " n'est pas au format 'jj/mm/aaaa hh:mm' ")
return False, " La date de debut de séquence " + str(
model_heure_debut) + " n'est pas au format 'jj/mm/aaaa hh:mm'"
local_status = mycommon.CheckisDate_Hours(model_heure_fin)
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La date de fin de séquence " + str(
model_heure_fin) + " n'est pas au format 'jj/mm/aaaa hh:mm' ")
return False, " La date de fin de séquence " + str(
model_heure_fin) + " n'est pas au format 'jj/mm/aaaa hh:mm'"
"""""
is_existe_valide_session_data = MYSY_GV.dbname["session_formation"].find_one(
{'_id': ObjectId(str(diction['session_id'])),
'partner_owner_recid': str(my_partner['recid']),
'valide': '1'})
date_debut_session = ""
if ("date_debut" in is_existe_valide_session_data.keys()):
if is_existe_valide_session_data['date_debut']:
date_debut_session = str(is_existe_valide_session_data['date_debut'])[0:10]
local_status = mycommon.CheckisDate(date_debut_session)
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La date de debut de session " + str(
date_debut_session) + " n'est pas au format 'jj/mm/aaaa' ")
return False, " La date de debut de session " + str(
date_debut_session) + " n'est pas au format 'jj/mm/aaaa' "
date_fin_session = ""
if ("date_fin" in is_existe_valide_session_data.keys()):
if is_existe_valide_session_data['date_fin']:
date_fin_session = str(is_existe_valide_session_data['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 " + str(
date_fin_session) + " n'est pas au format 'jj/mm/aaaa'")
return False, " La date de fin de session " + str(
date_fin_session) + " n'est pas au format 'jj/mm/aaaa'"
date_debut_session = datetime.strptime(str(date_debut_session), '%d/%m/%Y')
date_fin_session = datetime.strptime(str(date_fin_session), '%d/%m/%Y')
print(" les jours travaillé ")
liste_jours_travaille = []
liste_jours_travaille_code_day = []
if ("jours" in is_existe_valide_journee_model_data.keys()):
for jour in is_existe_valide_journee_model_data['jours']:
if (str(jour['travail']) == "1"):
liste_jours_travaille.append(str(jour['jour']))
liste_jours_travaille_code_day.append(str(jour['day_name']))
"""
/!\ Suppression des sequences qui existe et reservation par rapport à cette session
"""
for local_retval in MYSY_GV.dbname['session_formation_sequence'].find({'session_id': str(diction['session_id']),
'partner_owner_recid': str(my_partner['recid']),}):
deleted_data_agenda = MYSY_GV.dbname['agenda'].delete_many({'sequence_session_id': str(local_retval['_id']),
'partner_owner_recid': str(my_partner['recid']), })
deleted_data_affectation = MYSY_GV.dbname['session_formation_sequence_affectation'].delete_many({'sequence_session_id': str(local_retval['_id']),
'partner_owner_recid': str(my_partner['recid']),})
deleted_data_sequence = MYSY_GV.dbname['session_formation_sequence'].delete_many({'session_id': str(local_retval['session_id']),
'partner_owner_recid': str(my_partner['recid']),})
cpt = 10
for single_date in mycommon.daterange(date_debut_session, date_fin_session):
print(single_date.strftime("%Y-%m-%d"))
print(single_date.strftime("%A"))
if( str(single_date.strftime("%A")).lower() in liste_jours_travaille):
print(" OK TRAVAILLE")
# Pour chaque sequence de la journée
for local_val in is_existe_valide_journee_model_data['tab_sequence']:
sequence_data = {}
sequence_data['token'] = diction['token']
sequence_data['session_id'] = diction['session_id']
sequence_data['sequence_title'] = "Seq_Auto_" + str(cpt)
sequence_data['sequence_start'] = str(single_date.strftime("%d/%m/%Y"))+" "+str(local_val['heure_debut']).strip()
sequence_data['sequence_end'] = str(single_date.strftime("%d/%m/%Y"))+" "+str(local_val['heure_fin']).strip()
print(" ### sequence_data = ", sequence_data)
local_status, local_val = Add_Session_Sequence(sequence_data)
if( local_status is False):
mycommon.myprint(
str(inspect.stack()[0][ 3]) + " WARNING : " + str(local_val))
cpt = cpt + 1
else:
print(" KO NON TRAVAILLE ")
return True, " Les séquences ont été automatiquement créé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 de créer automatiquement les séquences "
"""
Mise à jour d'une sequence
"""
@ -279,6 +509,17 @@ def Update_Session_Sequence(diction):
return False, " La date de fin de séquence " + str(
date_fin_seq) + " n'est pas au format 'jj/mm/aaaa hh:mm'"
if (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) + " "
for retVal in MYSY_GV.dbname['session_formation_sequence'].find({'session_id': str(diction['session_id']),
'partner_owner_recid': str(
my_partner['recid']),
@ -531,6 +772,18 @@ def Delete_Given_Session_Sequence(diction):
'valide': '1',
'locked': '0'})
"""
Apres la suppression de la sequence, on supprime les eventuels reservations dans les agenda pour tout event rattaché à cette sequence
"""
deleted_data_qry = {'sequence_session_id':str(diction['_id']),
'partner_owner_recid': str(my_partner['recid']),}
#print(" ### deleted_data_qry = ", deleted_data_qry)
deleted_data = MYSY_GV.dbname['agenda'].delete_many(deleted_data_qry)
return True, "La sequence a été supprimée "
except Exception as e:
@ -939,6 +1192,12 @@ def Delete_Sequence_Affectation_Ressource_Poste(diction):
mycommon.myprint(str(inspect.stack()[0][3]) + " - L'affectation est incohérente. il a plusieurs affectations avec le meme id ")
return False, " L'affectation est incohérente. il a plusieurs affectations avec le meme id "
affectation_sequence_session_data = MYSY_GV.dbname[
'session_formation_sequence_affectation'].find_one(
{'_id': ObjectId(str(diction['_id'])), 'partner_owner_recid': str(partner_recid),
'valide': '1', 'locked': '0'})
inserted_data = MYSY_GV.dbname['session_formation_sequence_affectation'].delete_one(
{'_id': ObjectId(str(diction['_id'])), 'valide': "1", "locked": "0",
@ -948,7 +1207,16 @@ def Delete_Sequence_Affectation_Ressource_Poste(diction):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de supprimer à jour cette affectation (3)")
return False, " Impossible de supprimer cette affectation (3) "
"""
A present que la ressource a été supprimée, il faut egalement supprimer la reservation de la ressource
"""
qry_for_delete = {'sequence_session_id':str(diction['_id']), 'partner_owner_recid': str(affectation_sequence_session_data['partner_owner_recid']),
'related_collection_recid':str(affectation_sequence_session_data['related_target_collection_id']),
'related_target_collection':str(affectation_sequence_session_data['related_target_collection']),}
#print(" #### qry_for_delete = ", qry_for_delete)
MYSY_GV.dbname['agenda'].delete_many(qry_for_delete)
return True, " L'affectation a bien été supprimée"

View File

@ -106,6 +106,18 @@ def Add_Update_Agenda_Event(diction):
return False, " L'identifiant du 'related_collection_recid' n'est pas valide "
if (datetime.strptime(str(diction['event_start']), '%d/%m/%Y %H:%M') >= datetime.strptime(str(diction['event_end']),
'%d/%m/%Y %H:%M')):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La date de fin de séquence " + str(
diction['event_end']) + " doit être postérieure à la date de début de séquence " + str(
diction['event_end']) + " ")
return False, " La date de fin de séquence " + str(
diction['event_end']) + " doit être postérieure à la date de début de séquence " + str(diction['event_end']) + " "
mydata = {}
mydata['related_collection'] = str(diction['related_collection'])
mydata['related_collection_recid'] = str(diction['related_collection_recid'])

View File

@ -0,0 +1,100 @@
"""
Ce fichier permet de gerer la configuration des journée type
"""
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
"""
Recuperation d'un journée type en partant de l'_id
"""
def Get_Given_Modele_Journee(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'existe pas")
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 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 = []
qry = {'partner_owner_recid': str(my_partner['recid']), 'valide': '1',
'locked': '0', '_id': ObjectId(str(diction['_id']))}
New_retVal = MYSY_GV.dbname['base_config_modele_journee'].find_one( qry)
RetObject.append(mycommon.JSONEncoder().encode(New_retVal))
# print(" ### retval_json =", retval_json)
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 points de paramétrage "

11
main.py
View File

@ -5641,6 +5641,17 @@ def Get_List_Sequence_Ressource_Affectation():
return jsonify(status=status, message=retval)
"""
API Creation automatique des sequence selon les modeles de jounée de travail
"""
@app.route('/myclass/api/Create_Automatic_Sequence/', methods=['POST','GET'])
@crossdomain(origin='*')
def Create_Automatic_Sequence():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Create_Automatic_Sequence payload = ",payload)
status, retval = Session_Formation_Sequence.Create_Automatic_Sequence(payload)
return jsonify(status=status, message=retval)
if __name__ == '__main__':

View File

@ -41,6 +41,7 @@ import ftplib
import pysftp
import html
import mariadb
from datetime import timedelta
class JSONEncoder(json.JSONEncoder):
def default(self, o):
@ -3579,3 +3580,8 @@ def Is_User_Has_Right_To_Action(diction):
exc_type, exc_obj, exc_tb = sys.exc_info()
myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de verifier les droits d'acces de l'utilisateur "
def daterange(start_date, end_date):
for n in range(int((end_date - start_date).days)):
yield start_date + timedelta(n)