Ela_Back/Dashbord_queries/ressources_humaines_tbd_qri...

1249 lines
56 KiB
Python

"""
Ce fichier permet de traiter les tableaux de bord associées aux ressources humaines
"""
import ast
import dateutil
import pymongo
import xlsxwriter
from dateutil.relativedelta import relativedelta
from flask import send_file
from pymongo import MongoClient
import json
from bson import ObjectId
import re
from datetime import datetime, timezone, date
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 GlobalVariable as MYSY_GV
from datetime import timedelta
from datetime import timedelta
from operator import itemgetter
"""
Recupération du tableau des ressources humaines en lien avec leur planification
"""
def Get_Humain_Ressource_With_Planning(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'session_start_date', 'session_end_date', 'filter_value', 'tab_rh_id', 'event_type' ]
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', 'session_start_date', 'session_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
"""
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
# Verfication de la validité du type d'evenement
event_type_filter = {}
if( "event_type" in diction.keys() and diction['event_type']):
if( diction['event_type'] not in MYSY_GV.AGENDA_EVENT_TYPE):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le type d'évènement est invalide ")
return False, " Le type d'évènement est invalide "
event_type_filter = {'$eq': ["$event_type", str(diction['event_type'])]}
print(" ### event_type_filter = ", event_type_filter)
"""
/!\ : si 'tab_rh_id' == 'all', cela veut dire qu'on prend touts les employés
si non, on va aller filtrer selon les contenus de la tab tab_rh_id
"""
tab_rh_id = []
tab_rh_object_id = []
if( str(diction['tab_rh_id']) == "all" ):
for val in MYSY_GV.dbname['ressource_humaine'].find({'valide': '1',
'locked': '0',
'partner_recid': str(my_partner['recid'])}):
tab_rh_object_id.append(val['_id'])
else : # Verification de la validité de toutes les ressources humaines dans tab_rh_id
tab_rh_id = str(diction['tab_rh_id']).split(',')
for rh_id in tab_rh_id:
if (MYSY_GV.dbname['ressource_humaine'].count_documents({'_id': ObjectId(str(rh_id)),
'valide': '1',
'locked': '0',
'partner_recid': str(
my_partner['recid'])}) != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " La ressource humaine :" + str(rh_id) + " n'est pas valide ")
return False, " La session_id :" + str(rh_id) + " n'est pas valide "
tab_rh_object_id.append(ObjectId(str(rh_id)))
filt_session_start_date = ""
if ("session_start_date" in diction.keys() and diction['session_start_date']):
filt_session_start_date = str(diction['session_start_date'])[0:10]
local_status = mycommon.CheckisDate(filt_session_start_date)
if (local_status is False):
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le filtre : 'date de debut de session' n'est pas au format jj/mm/aaaa.")
return False, " Le filtre : 'date de debut de session' n'est pas au format jj/mm/aaaa."
filt_session_end_date = ""
if ("session_end_date" in diction.keys() and diction['session_end_date']):
filt_session_end_date = str(diction['session_end_date'])[0:10]
local_status = mycommon.CheckisDate(filt_session_end_date)
if (local_status is False):
mycommon.myprint(str(
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."
"""
Si la valeur de 'filter_value' est m0 ou m1, on va aller recuperer les date du mois correspondant.
On ecrase les valeur de filt_session_start_date et filt_session_end_date
"""
if( 'filter_value' in diction.keys() ):
if( str(diction['filter_value']) == "m0"):
# On recupere les date du mois en cours
local_status, start_current_month_date, end_current_month_date = mycommon.Get_Current_Month_Start_End_Date()
if (local_status is False):
return local_status, start_current_month_date
filt_session_start_date = start_current_month_date
filt_session_end_date = end_current_month_date
elif (str(diction['filter_value']) == "m1"):
# On recupere les date du mois en cours
local_status, start_current_month_date, end_current_month_date = mycommon.Get_Previous_Month_Start_End_Date()
if (local_status is False):
return local_status, start_current_month_date
filt_session_start_date = start_current_month_date
filt_session_end_date = end_current_month_date
RetObject = []
val_tmp = 1
filt_session_start_date_ISODATE = datetime.strptime(str(filt_session_start_date), '%d/%m/%Y')
filt_session_end_date_ISODATE = datetime.strptime(str(filt_session_end_date), '%d/%m/%Y')
filt_session_start_date_ISODATE_work = filt_session_start_date_ISODATE
filt_session_end_date_ISODATE_work = filt_session_end_date_ISODATE
interval_date = []
pipe_qry = ( [
{ "$match": {'_id':{'$in':tab_rh_object_id} }},
{'$lookup': {
'from': 'agenda',
"let": {"rh_id": {'$toString': "$_id"}, 'rh_partner_owner_recid':'$partner_recid'},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
event_type_filter,
{'$eq': ["$valide", "1"]},
{'$eq': ["$related_collection_recid", '$$rh_id']},
{'$eq': ["$partner_owner_recid", '$$rh_partner_owner_recid']},
{'$gte': [{'$toDate': "$event_start" },filt_session_start_date_ISODATE]},
{'$lte': [{'$toDate': "$event_start"}, filt_session_end_date_ISODATE]}
]
}
}
},
],
'as': 'collection_agenda'
}
}
])
print(" ### Get_Humain_Ressource_With_Planning ici pipe_qry = ", pipe_qry)
new_retval_titles = []
new_retval_data = []
local_id = 0
total_duration = 0
for retval in MYSY_GV.dbname['ressource_humaine'].aggregate(pipe_qry):
## Recuperation des agenda
if( "collection_agenda" in retval.keys() and len(retval['collection_agenda']) > 0 ):
for agenda_retval in retval['collection_agenda'] :
local_id = local_id + 1
new_node = {}
new_node['id'] = str(local_id)
new_node['_id'] = str(retval['_id'])
if ("civilite" in retval.keys()):
new_node['civilite'] = str(retval['civilite']).lower()
else:
new_node['civilite'] = ""
if ("nom" in retval.keys()):
new_node['nom'] = str(retval['nom'])
else:
new_node['nom'] = ""
if ("prenom" in retval.keys()):
new_node['prenom'] = str(retval['prenom'])
else:
new_node['prenom'] = ""
if ("email" in retval.keys()):
new_node['email'] = str(retval['email'])
else:
new_node['email'] = ""
if ("ismanager" in retval.keys()):
new_node['ismanager'] = str(retval['ismanager'])
else:
new_node['ismanager'] = "0"
if ("fonction" in retval.keys()):
new_node['fonction'] = str(retval['fonction'])
else:
new_node['fonction'] = ""
if ("_id" in agenda_retval.keys()):
new_node['agenda_id'] = str(agenda_retval['_id'])
else:
new_node['agenda_id'] = ""
if ("event_title" in agenda_retval.keys()):
new_node['agenda_event_title'] = str(agenda_retval['event_title'])
else:
new_node['agenda_event_title'] = ""
if ("comment" in agenda_retval.keys()):
new_node['agenda_event_code_session'] = str(agenda_retval['comment'])
else:
new_node['agenda_event_code_session'] = ""
if ("sequence_session_id" in agenda_retval.keys()):
new_node['agenda_event_sequence_session_id'] = str(agenda_retval['sequence_session_id'])
else:
new_node['agenda_event_sequence_session_id'] = ""
if ("event_type" in agenda_retval.keys()):
new_node['agenda_event_type'] = str(agenda_retval['event_type'])
else:
new_node['agenda_event_type'] = ""
if ("event_start" in agenda_retval.keys()):
new_node['agenda_date_jour'] = str(datetime.strptime(str(agenda_retval['event_start'])[0:16], '%Y-%m-%dT%H:%M').strftime("%d/%m/%Y"))
new_node['agenda_event_start'] = str(datetime.strptime(str(agenda_retval['event_start'])[0:16], '%Y-%m-%dT%H:%M').strftime("%d/%m/%Y %H:%M"))
else:
new_node['agenda_date_jour'] = ""
new_node['agenda_event_start'] = ""
if ("event_end" in agenda_retval.keys()):
new_node['agenda_event_end'] = str(datetime.strptime(str(agenda_retval['event_end'])[0:16], '%Y-%m-%dT%H:%M').strftime("%d/%m/%Y %H:%M"))
else:
new_node['agenda_event_end'] = ""
event_duration_second = datetime.strptime(str(agenda_retval['event_end'])[0:16], '%Y-%m-%dT%H:%M') - datetime.strptime(str(agenda_retval['event_start'])[0:16],'%Y-%m-%dT%H:%M')
"""
Gerer les eventuels cas d'erreur sur une date de fin event < debut event
"""
if (event_duration_second.total_seconds() < 0):
event_duration_second = 0
event_duration_second = event_duration_second.total_seconds()
event_duration_hour = round(divmod(event_duration_second, 3600)[0]+divmod(event_duration_second, 3600)[1]/3600, 2)
total_duration = total_duration + event_duration_hour
new_node['event_duration_second'] = str(event_duration_second)
new_node['event_duration_hour'] = str(event_duration_hour)
#print(" ### new_node = ", new_node)
RetObject.append(mycommon.JSONEncoder().encode(new_node))
node_duration = {"total_duration":str(total_duration)}
#print(' ### node_duration = ', node_duration)
RetObject.append(mycommon.JSONEncoder().encode(node_duration))
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 "
"""
Cette fonction permet d'experter un dashbord en csv
"""
def TBD_RH_01_Export_Dashbord_To_Csv(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'user_dashbord_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', 'user_dashbord_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
# Recuperation des données du user_dashbord
my_user_dashbord = MYSY_GV.dbname['user_dashbord'].find_one({'_id': ObjectId(str(diction['user_dashbord_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (my_user_dashbord is None):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - L'identifiant du tableau de bord est invalide ")
return False, " L'identifiant du tableau de bord est invalide",
new_retval_data = {}
my_new_diction = {}
my_new_diction['token'] = diction['token']
session_start_date = ""
session_end_date = ""
local_default_filter = ast.literal_eval(str(my_user_dashbord['default_filter']))
if ("session_start_date" in local_default_filter.keys() and "session_end_date" in local_default_filter.keys()):
session_start_date = local_default_filter['session_start_date']
session_end_date = local_default_filter['session_end_date']
elif ("periode" in local_default_filter.keys()):
my_new_diction['filter_value'] = str(local_default_filter['periode'])
if (str(local_default_filter['periode']) == "m0"):
# On recupere les date du mois en cours
local_status, start_current_month_date, end_current_month_date = mycommon.Get_Current_Month_Start_End_Date()
if (local_status is False):
return local_status, start_current_month_date
session_start_date = start_current_month_date
session_end_date = end_current_month_date
elif (str(local_default_filter['periode']) == "m1"):
# On recupere les date du mois en cours
local_status, start_current_month_date, end_current_month_date = mycommon.Get_Previous_Month_Start_End_Date()
if (local_status is False):
return local_status, start_current_month_date
session_start_date = start_current_month_date
session_end_date = end_current_month_date
my_new_diction['session_start_date'] = session_start_date
my_new_diction['session_end_date'] = session_end_date
my_new_diction['tab_rh_id'] = "all"
if (my_user_dashbord['dashbord_internal_code'] == "tbd_rh_01"):
local_status, local_retval = Get_Humain_Ressource_With_Planning(my_new_diction)
if (local_status is False):
return local_status, local_retval
new_retval_data = local_retval
elif (my_user_dashbord['dashbord_internal_code'] == "tbd_rh_02"):
local_status, local_retval = Get_Humain_Ressource_With_Planning_And_Cost(my_new_diction)
if (local_status is False):
return local_status, local_retval
new_retval_data = local_retval
else:
mycommon.myprint(
str(inspect.stack()[0][3]) + " Requête inconnue ")
return False, " Requête inconnue ",
# Recuperation des colonne à exporter
base_config_dashbord_data = MYSY_GV.dbname['base_config_dashbord'].find_one(
{'dashbord_internal_code': str(my_user_dashbord['dashbord_internal_code'])})
tab_exported_fields = []
if ("exported_fields" in base_config_dashbord_data):
tab_exported_fields = base_config_dashbord_data['exported_fields']
# Remettres les dates de filtres en debut de liste
if ("filtre_date_fin" in tab_exported_fields):
tab_exported_fields.remove("filtre_date_fin")
tab_exported_fields.insert(0, "filtre_date_fin")
if ("filtre_date_debut" in tab_exported_fields):
tab_exported_fields.remove("filtre_date_debut")
tab_exported_fields.insert(0, "filtre_date_debut")
tab_exported_fields.insert(0, "date_extraction")
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-5:]
orig_file_name = "Export_csv_" + str(my_partner['recid']) + "_" + str(ts) + ".csv"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)
with open(outputFilename, 'w', newline='') as outfile:
fields = tab_exported_fields
write = csv.DictWriter(outfile, fieldnames=fields)
write.writeheader()
for answers_record in new_retval_data: # Here we are using 'cursor' as an iterator
flattened_record = {}
for local_fiels in tab_exported_fields:
answers_record_JSON = ast.literal_eval(str(answers_record))
if (str(local_fiels) in answers_record_JSON.keys()):
flattened_record[str(local_fiels)] = answers_record_JSON[str(local_fiels)]
flattened_record['filtre_date_debut'] = str(session_start_date)
flattened_record['filtre_date_fin'] = str(session_end_date)
flattened_record['date_extraction'] = str(todays_date)
write.writerow(flattened_record)
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 (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 données "
"""
Cette fonction permet de calculer les cout
par employé, par tache, selon le contrat
"""
def Get_Humain_Ressource_With_Planning_And_Cost(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'session_start_date', 'session_end_date', 'filter_value', 'tab_rh_id', 'event_type']
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', 'session_start_date', 'session_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
"""
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
# Verfication de la validité du type d'evenement
event_type_filter = {}
if ("event_type" in diction.keys() and diction['event_type']):
if (diction['event_type'] not in MYSY_GV.AGENDA_EVENT_TYPE):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le type d'évènement est invalide ")
return False, " Le type d'évènement est invalide "
event_type_filter = {'$eq': ["$event_type", str(diction['event_type'])]}
"""
/!\ : si 'tab_rh_id' == 'all', cela veut dire qu'on prend touts les employés
si non, on va aller filtrer selon les contenus de la tab tab_rh_id
"""
tab_rh_id = []
tab_rh_object_id = []
if (str(diction['tab_rh_id']) == "all"):
for val in MYSY_GV.dbname['ressource_humaine'].find({'valide': '1',
'locked': '0',
'partner_recid': str(my_partner['recid'])}):
tab_rh_object_id.append(val['_id'])
else: # Verification de la validité de toutes les ressources humaines dans tab_rh_id
tab_rh_id = str(diction['tab_rh_id']).split(',')
for rh_id in tab_rh_id:
if (MYSY_GV.dbname['ressource_humaine'].count_documents({'_id': ObjectId(str(rh_id)),
'valide': '1',
'locked': '0',
'partner_recid': str(
my_partner['recid'])}) != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " La ressource humaine :" + str(rh_id) + " n'est pas valide ")
return False, " La session_id :" + str(rh_id) + " n'est pas valide "
tab_rh_object_id.append(ObjectId(str(rh_id)))
filt_session_start_date = ""
if ("session_start_date" in diction.keys() and diction['session_start_date']):
filt_session_start_date = str(diction['session_start_date'])[0:10]
local_status = mycommon.CheckisDate(filt_session_start_date)
if (local_status is False):
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le filtre : 'date de debut de session' n'est pas au format jj/mm/aaaa.")
return False, " Le filtre : 'date de debut de session' n'est pas au format jj/mm/aaaa."
filt_session_end_date = ""
if ("session_end_date" in diction.keys() and diction['session_end_date']):
filt_session_end_date = str(diction['session_end_date'])[0:10]
local_status = mycommon.CheckisDate(filt_session_end_date)
if (local_status is False):
mycommon.myprint(str(
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."
"""
Si la valeur de 'filter_value' est m0 ou m1, on va aller recuperer les date du mois correspondant.
On ecrase les valeur de filt_session_start_date et filt_session_end_date
"""
if ('filter_value' in diction.keys()):
if (str(diction['filter_value']) == "m0"):
# On recupere les date du mois en cours
local_status, start_current_month_date, end_current_month_date = mycommon.Get_Current_Month_Start_End_Date()
if (local_status is False):
return local_status, start_current_month_date
filt_session_start_date = start_current_month_date
filt_session_end_date = end_current_month_date
elif (str(diction['filter_value']) == "m1"):
# On recupere les date du mois en cours
local_status, start_current_month_date, end_current_month_date = mycommon.Get_Previous_Month_Start_End_Date()
if (local_status is False):
return local_status, start_current_month_date
filt_session_start_date = start_current_month_date
filt_session_end_date = end_current_month_date
"""
Algorithme :
1 - Pour chaque employé, aller chercher ses contrats valides de la periode. Completer ce tableaux avec les données du contrat
mettre dans une tableau en local
2 - Pour chaque tache de l'employée, aller chercher le contrat qui correspond à la periode de la tache
- Peupler ce tableau avec : tache (agenda), contrat (data), employé (data)
"""
tab_lines_employe_by_contract = []
"""
Etape 1: Récuperation des donnée employé avec les contrat associés
"""
#print(" #### tab_rh_object_id = ", tab_rh_object_id)
# { "$match": {'_id':{'$in':tab_rh_object_id} }},
# {'$match': {'_id': ObjectId('6509a1adaca6e5023d7af487')}},
qry_employe_contrat = ([
{"$match": {'_id': {'$in': tab_rh_object_id}}},
{'$lookup': {
'from': 'ressource_humaine_contrat',
'let': {'rh_id': {'$toString': '$_id'}, 'rh_partner_owner_recid': '$partner_recid'},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ['$valide', '1']},
{'$eq': ['$rh_id', '$$rh_id']},
{'$eq': ['$partner_owner_recid', '$$rh_partner_owner_recid']}
]
}
}
},
{"$project": {"_id": 0, }}
],
'as': 'collection_ressource_humaine_contrat'
}
},
{
'$unwind': '$collection_ressource_humaine_contrat'
}
])
cpt = 0
for retval in MYSY_GV.dbname['ressource_humaine'].aggregate(qry_employe_contrat):
# print(" ### retval = ", retval)
cpt = cpt + 1
rh_id_Object = ObjectId(str(retval['_id']))
retval['_id'] = str(rh_id_Object)
"""
Si le contrat est lié à un groupe de prix, alors aller chercher les elements du groupe de prix
"""
if ("groupe_prix_achat_id" in retval['collection_ressource_humaine_contrat'].keys() and
retval['collection_ressource_humaine_contrat']['groupe_prix_achat_id']):
price_grp_data = MYSY_GV.dbname['purchase_prices'].find_one(
{'_id': ObjectId(str(retval['collection_ressource_humaine_contrat']['groupe_prix_achat_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(retval['collection_ressource_humaine_contrat']['partner_owner_recid']),
})
if (price_grp_data and "prix" in price_grp_data.keys() and "periodicite" in price_grp_data.keys()):
retval['collection_ressource_humaine_contrat']['groupe_prix_achat_code'] = str(price_grp_data['code_groupe_prix'])
retval['collection_ressource_humaine_contrat']['groupe_prix_achat_cout'] = str(
price_grp_data['prix'])
retval['collection_ressource_humaine_contrat']['groupe_prix_achat_periodicite'] = str(
price_grp_data['periodicite'])
else:
retval['collection_ressource_humaine_contrat']['groupe_prix_achat_code'] = ""
retval['collection_ressource_humaine_contrat']['groupe_prix_achat_cout'] = ""
retval['collection_ressource_humaine_contrat']['groupe_prix_achat_periodicite'] = ""
else:
retval['collection_ressource_humaine_contrat']['groupe_prix_achat_code'] = ""
retval['collection_ressource_humaine_contrat']['groupe_prix_achat_cout'] = ""
retval['collection_ressource_humaine_contrat']['groupe_prix_achat_periodicite'] = ""
retval['Tab_agenda'] = []
"""
Aller chercher toutes taches valides entre les date du contrat
"""
date_debut_contrat = ""
date_fin_contrat = ""
if ("collection_ressource_humaine_contrat" in retval.keys() and "date_debut" in retval[
'collection_ressource_humaine_contrat'].keys()):
date_debut_contrat = retval['collection_ressource_humaine_contrat']['date_debut']
if ("collection_ressource_humaine_contrat" in retval.keys() and "date_fin" in retval[
'collection_ressource_humaine_contrat'].keys()):
date_fin_contrat = retval['collection_ressource_humaine_contrat']['date_fin']
if (mycommon.CheckisDate(date_debut_contrat) is False or mycommon.CheckisDate(date_fin_contrat) is False):
mycommon.myprint(str(
inspect.stack()[0][3]) + " Les dates de debut et/ou fin de contrat de l'employé " + str(
retval['nom'] + " " + retval['prenom']) + " ne sont au format jj/mm/aaaa.")
return False, " Les dates de debut et/ou fin de contrat de l'employé " + str(
retval['nom'] + " " + retval['prenom']) + " ne sont au format jj/mm/aaaa. "
"""
Etape 2 :
Aller recuperer les taches dans les agendas
"""
filt_session_start_date_ISODATE = datetime.strptime(str(date_debut_contrat), '%d/%m/%Y')
filt_session_end_date_ISODATE = datetime.strptime(str(date_fin_contrat), '%d/%m/%Y')
local_qry_tache_agenda = ([
{"$match": {'_id': rh_id_Object}},
{'$lookup': {
'from': 'agenda',
"let": {"rh_id": {'$toString': "$_id"}, 'rh_partner_owner_recid': '$partner_recid'},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
event_type_filter,
{'$eq': ["$valide", "1"]},
{'$eq': ["$related_collection_recid", '$$rh_id']},
{'$eq': ["$partner_owner_recid", '$$rh_partner_owner_recid']},
{'$gte': [{'$toDate': "$event_start"}, filt_session_start_date_ISODATE]},
{'$lte': [{'$toDate': "$event_start"}, filt_session_end_date_ISODATE]}
]
}
}
},
],
'as': 'collection_agenda'
}
},
{
'$unwind': '$collection_agenda'
}
])
#print(" ### local_qry_tache_agenda ici pipe_qry = ", local_qry_tache_agenda)
for retval_agenda in MYSY_GV.dbname['ressource_humaine'].aggregate(local_qry_tache_agenda):
# print(" ### retval_agenda Trouvé = ", retval_agenda)
agenda_id_Object = ObjectId(str(retval_agenda['_id']))
retval_agenda['_id'] = str(agenda_id_Object)
retval_agenda['collection_agenda']['_id'] = str(retval_agenda['collection_agenda']['_id'])
if ("event_start" in retval_agenda['collection_agenda'].keys()):
retval_agenda['collection_agenda']['agenda_date_jour'] = str(
datetime.strptime(str(retval_agenda['collection_agenda']['event_end'])[0:16],
'%Y-%m-%dT%H:%M').strftime("%d/%m/%Y"))
else:
retval_agenda['collection_agenda']['agenda_date_jour'] = ""
event_duration_second = datetime.strptime(str(retval_agenda['collection_agenda']['event_end'])[0:16],
'%Y-%m-%dT%H:%M') - datetime.strptime(
str(retval_agenda['collection_agenda']['event_start'])[0:16], '%Y-%m-%dT%H:%M')
event_duration_second = event_duration_second.total_seconds()
event_duration_hour = round(
divmod(event_duration_second, 3600)[0] + divmod(event_duration_second, 3600)[1] / 3600, 2)
retval_agenda['collection_agenda']['event_duration_second'] = str(event_duration_second)
retval_agenda['collection_agenda']['event_duration_hour'] = str(event_duration_hour)
#json_agenda_formatted_str = json.dumps(retval_agenda, indent=2)
if ("collection_agenda" in retval_agenda.keys() and "partner_owner_recid" in retval_agenda[
'collection_agenda'].keys()):
new_node = retval_agenda['collection_agenda']
retval['Tab_agenda'].append(new_node)
# print(" ### NODE ADDED = ", new_node)
#json_formatted_str = json.dumps(retval, indent=2)
#print(" ### Final Line : ", json_formatted_str)
tab_lines_employe_by_contract.append(retval)
local_status, local_retval = Format_employee_contrat_agenda_events(tab_lines_employe_by_contract)
if (local_status is False):
return local_status, local_retval
RetObject = []
cpt = 0
for val in local_retval:
val['id'] = str(cpt)
RetObject.append(mycommon.JSONEncoder().encode(val))
cpt = cpt + 1
tab_lines_employe_by_contract_json_formatted_str = json.dumps(val, indent=2)
#print(" ### Final Line " + str(cpt) + " : ", tab_lines_employe_by_contract_json_formatted_str)
#print(" RetObject = ", RetObject)
#print(' on a ' + str(cpt) + ' lignes ')
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 le tableau des tache et avec les cout"
"""
Cette fonction prend un dictionnaire qui rattache chaque evenement (agenda : type planning) au
contrat en cours (+les données de l'employé) et retourne une dictionnaire reformaté de manière
à avoir une ligne par evenement + toutes les data du contrat en face
"""
def Format_employee_contrat_agenda_events(tab_diction):
try:
return_tab = []
total_duration = 0
total_cost = 0
for val in tab_diction:
#print(" #### Debut traitement de la ligne " + str(val))
for event_data in val['Tab_agenda']:
new_node = {}
new_node['rh_id'] = val['_id']
new_node['rh_partner_recid'] = val['partner_recid']
new_node['rh_civilite'] = val['civilite']
new_node['rh_nom'] = val['nom']
new_node['rh_prenom'] = val['prenom']
new_node['rh_email'] = val['email']
new_node['rh_telephone_mobile'] = val['telephone_mobile']
new_node['rh_ismanager'] = val['ismanager']
new_node['rh_fonction'] = val['fonction']
new_node['rh_telephone'] = val['telephone']
if( "purchase_price_group_id" in val.keys() ):
new_node['rh_purchase_price_group_id'] = val['purchase_price_group_id']
else:
new_node['rh_purchase_price_group_id'] = ""
if ("date_naissance" in val.keys()):
new_node['rh_date_naissance'] = val['date_naissance']
else:
new_node['rh_date_naissance'] = ""
if ("adr_adresse" in val.keys()):
new_node['rh_adr_adresse'] = val['adr_adresse']
else:
new_node['rh_date_naissance'] = ""
if ("adr_code_postal" in val.keys()):
new_node['rh_adr_code_postal'] = val['adr_code_postal']
else:
new_node['rh_date_naissance'] = ""
if ("adr_ville" in val.keys()):
new_node['rh_adr_ville'] = val['adr_ville']
else:
new_node['rh_adr_ville'] = ""
if ("adr_pays" in val.keys()):
new_node['rh_adr_pays'] = val['adr_pays']
else:
new_node['rh_adr_pays'] = ""
if ("collection_ressource_humaine_contrat" in val.keys()):
if ("date_debut" in val['collection_ressource_humaine_contrat'].keys()):
new_node['rh_contrat_date_debut'] = val['collection_ressource_humaine_contrat']['date_debut']
else:
new_node['rh_contrat_date_debut'] = ""
if ("date_fin" in val['collection_ressource_humaine_contrat'].keys()):
new_node['rh_contrat_date_fin'] = val['collection_ressource_humaine_contrat']['date_fin']
else:
new_node['rh_contrat_date_fin'] = ""
if ("type_contrat" in val['collection_ressource_humaine_contrat'].keys()):
new_node['rh_contrat_type_contrat'] = val['collection_ressource_humaine_contrat'][
'type_contrat']
else:
new_node['rh_contrat_type_contrat'] = ""
if ("type_employe" in val['collection_ressource_humaine_contrat'].keys()):
new_node['rh_contrat_type_employe'] = val['collection_ressource_humaine_contrat'][
'type_employe']
else:
new_node['rh_contrat_type_employe'] = ""
if ("cout" in val['collection_ressource_humaine_contrat'].keys()):
new_node['rh_contrat_cout'] = val['collection_ressource_humaine_contrat']['cout']
else:
new_node['rh_contrat_cout'] = ""
if ("periodicite" in val['collection_ressource_humaine_contrat'].keys()):
new_node['rh_contrat_periodicite'] = val['collection_ressource_humaine_contrat']['periodicite']
else:
new_node['rh_contrat_periodicite'] = ""
if ("quantite" in val['collection_ressource_humaine_contrat'].keys()):
new_node['rh_contrat_quantite'] = val['collection_ressource_humaine_contrat']['quantite']
else:
new_node['rh_contrat_quantite'] = ""
if ("groupe_prix_achat_id" in val['collection_ressource_humaine_contrat'].keys()):
new_node['rh_contrat_groupe_prix_achat_id'] = val['collection_ressource_humaine_contrat'][
'groupe_prix_achat_id']
else:
new_node['rh_contrat_groupe_prix_achat_id'] = ""
if ("comment" in val['collection_ressource_humaine_contrat'].keys()):
new_node['rh_contrat_comment'] = val['collection_ressource_humaine_contrat']['comment']
else:
new_node['rh_contrat_comment'] = ""
if ("groupe_prix_achat_code" in val['collection_ressource_humaine_contrat'].keys()):
new_node['rh_contrat_groupe_prix_achat_code'] = val['collection_ressource_humaine_contrat'][ 'groupe_prix_achat_code']
else:
new_node['rh_contrat_groupe_prix_achat_code'] = ""
if ("groupe_prix_achat_cout" in val['collection_ressource_humaine_contrat'].keys()):
new_node['rh_contrat_groupe_prix_achat_cout'] = val['collection_ressource_humaine_contrat']['groupe_prix_achat_cout']
else:
new_node['rh_contrat_groupe_prix_achat_cout'] = ""
if ("groupe_prix_achat_periodicite" in val['collection_ressource_humaine_contrat'].keys()):
new_node['rh_contrat_groupe_prix_achat_periodicite'] = \
val['collection_ressource_humaine_contrat']['groupe_prix_achat_periodicite']
else:
new_node['rh_contrat_groupe_prix_achat_periodicite'] = ""
# Traitement des données de l'evement dans l'agenda
new_node['rh_event_planning_event_type'] = event_data['event_type']
new_node['rh_event_planning_event_title'] = event_data['event_title']
new_node['rh_event_planning_event_start'] = str(datetime.strptime(str(event_data['event_start'] )[0:16], '%Y-%m-%dT%H:%M').strftime("%d/%m/%Y %H:%M"))
new_node['rh_event_planning_event_end'] = str(datetime.strptime(str(event_data['event_end'] )[0:16], '%Y-%m-%dT%H:%M').strftime("%d/%m/%Y %H:%M"))
new_node['rh_event_planning_agenda_date_jour'] = event_data['agenda_date_jour']
new_node['rh_event_planning_event_duration_hour'] = event_data['event_duration_hour']
total_duration = total_duration + mycommon.tryFloat(str(event_data['event_duration_hour']))
new_node['rh_event_planning_event_duration_second'] = event_data['event_duration_second']
if ("comment" in event_data.keys()):
new_node['rh_event_planning_even_comment'] = event_data['comment']
else:
new_node['rh_event_planning_even_comment'] = ""
"""
# Calcul du cout total d'une tache
/!\ Le prix du contrat prend toujours le pas sur le prix rentré à la main.
C'est a dire que si un pour quelque raison que ce soit, sur la même période un employé
a un groupe de prix d'achat et une prix saisie à la main, alors les totaux seront calculés en se basant
sur le prix qui est dans le contrat
"""
if ("rh_contrat_groupe_prix_achat_id" in new_node.keys() and new_node['rh_contrat_groupe_prix_achat_id']
and "rh_contrat_groupe_prix_achat_periodicite" in new_node.keys() and new_node[
'rh_contrat_groupe_prix_achat_periodicite']
and "rh_event_planning_event_duration_hour" in new_node.keys() and new_node[
'rh_event_planning_event_duration_hour']
and "rh_contrat_groupe_prix_achat_cout" in new_node.keys() and new_node[
'rh_contrat_groupe_prix_achat_cout']):
if (str(new_node['rh_contrat_groupe_prix_achat_periodicite']) == "heure"):
new_node['rh_event_planning_event_cost'] = str( mycommon.tryFloat(new_node['rh_contrat_groupe_prix_achat_cout']) * mycommon.tryFloat( new_node['rh_event_planning_event_duration_hour']))
total_cost = total_cost + mycommon.tryFloat((str(new_node['rh_event_planning_event_cost'])))
elif (str(new_node['rh_contrat_groupe_prix_achat_periodicite']) == "fixe"):
new_node['rh_event_planning_event_cost'] = str((new_node['rh_contrat_groupe_prix_achat_cout']))
total_cost = total_cost + mycommon.tryFloat((str(new_node['rh_event_planning_event_cost'])))
elif ("rh_contrat_groupe_prix_achat_id" in new_node.keys() and str(
new_node['rh_contrat_groupe_prix_achat_id']) == ""
and "rh_contrat_periodicite" in new_node.keys() and new_node['rh_contrat_periodicite']
and "rh_event_planning_event_duration_hour" in new_node.keys() and new_node[
'rh_event_planning_event_duration_hour']
and "rh_contrat_cout" in new_node.keys() and new_node['rh_contrat_cout']):
if (str(new_node['rh_contrat_periodicite']) == "heure"):
new_node['rh_event_planning_event_cost'] = str(
mycommon.tryFloat(new_node['rh_contrat_cout']) * mycommon.tryFloat(
new_node['rh_event_planning_event_duration_hour']))
total_cost = total_cost + mycommon.tryFloat((str(new_node['rh_event_planning_event_cost'])))
elif (str(new_node['rh_contrat_periodicite']) == "fixe"):
new_node['rh_event_planning_event_cost'] = str((new_node['rh_contrat_cout']))
total_cost = total_cost + mycommon.tryFloat((str(new_node['rh_event_planning_event_cost'])))
else:
new_node['rh_event_planning_event_cost'] = "Impossible a calculer"
return_tab.append(new_node)
node_total_duration = {'total_duration':str(total_duration)}
return_tab.append(node_total_duration)
node_total_cost = {'total_cost':str(total_cost)}
return_tab.append(node_total_cost)
#print(" #### total_duration = ", total_duration)
#print(" #### total_cost = ", total_cost)
return True, return_tab
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 reformater et de normer le tableau des tâches et coûts "
"""
Cette fonction permet d'experter un dashbord en Excel
"""
def TBD_RH_01_Export_Dashbord_To_Excel(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'user_dashbord_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', 'user_dashbord_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
# Recuperation des données du user_dashbord
my_user_dashbord = MYSY_GV.dbname['user_dashbord'].find_one({'_id': ObjectId(str(diction['user_dashbord_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (my_user_dashbord is None):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - L'identifiant du tableau de bord est invalide ")
return False, " L'identifiant du tableau de bord est invalide",
new_retval_data = {}
my_new_diction = {}
my_new_diction['token'] = diction['token']
session_start_date = ""
session_end_date = ""
local_default_filter = ast.literal_eval(str(my_user_dashbord['default_filter']))
if ("session_start_date" in local_default_filter.keys() and "session_end_date" in local_default_filter.keys()):
session_start_date = local_default_filter['session_start_date']
session_end_date = local_default_filter['session_end_date']
elif ("periode" in local_default_filter.keys()):
my_new_diction['filter_value'] = str(local_default_filter['periode'])
if (str(local_default_filter['periode']) == "m0"):
# On recupere les date du mois en cours
local_status, start_current_month_date, end_current_month_date = mycommon.Get_Current_Month_Start_End_Date()
if (local_status is False):
return local_status, start_current_month_date
session_start_date = start_current_month_date
session_end_date = end_current_month_date
elif (str(local_default_filter['periode']) == "m1"):
# On recupere les date du mois en cours
local_status, start_current_month_date, end_current_month_date = mycommon.Get_Previous_Month_Start_End_Date()
if (local_status is False):
return local_status, start_current_month_date
session_start_date = start_current_month_date
session_end_date = end_current_month_date
my_new_diction['session_start_date'] = session_start_date
my_new_diction['session_end_date'] = session_end_date
my_new_diction['tab_rh_id'] = "all"
if (my_user_dashbord['dashbord_internal_code'] == "tbd_rh_01"):
local_status, local_retval = Get_Humain_Ressource_With_Planning(my_new_diction)
if (local_status is False):
return local_status, local_retval
new_retval_data = local_retval
if (my_user_dashbord['dashbord_internal_code'] == "tbd_rh_02"):
local_status, local_retval = Get_Humain_Ressource_With_Planning_And_Cost(my_new_diction)
if (local_status is False):
return local_status, local_retval
new_retval_data = local_retval
else:
mycommon.myprint(
str(inspect.stack()[0][3]) + " Requête inconnue ")
return False, " Requête inconnue ",
# Recuperation des colonne à exporter
base_config_dashbord_data = MYSY_GV.dbname['base_config_dashbord'].find_one(
{'dashbord_internal_code': str(my_user_dashbord['dashbord_internal_code'])})
tab_exported_fields = []
if ("exported_fields" in base_config_dashbord_data):
tab_exported_fields = base_config_dashbord_data['exported_fields']
# Remettres les dates de filtres en debut de liste
if ("filtre_date_fin" in tab_exported_fields):
tab_exported_fields.remove("filtre_date_fin")
tab_exported_fields.insert(0, "filtre_date_fin")
if ("filtre_date_debut" in tab_exported_fields):
tab_exported_fields.remove("filtre_date_debut")
tab_exported_fields.insert(0, "filtre_date_debut")
tab_exported_fields.insert(0, "date_extraction")
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-5:]
orig_file_name = "Export_csv_" + str(my_partner['recid']) + "_" + str(ts) + ".csv"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)
# Create a workbook and add a worksheet.
workbook = xlsxwriter.Workbook(outputFilename)
worksheet = workbook.add_worksheet()
row = 0
column = 0
# Ecrire l'entete
for header_item in tab_exported_fields:
worksheet.write(row, column, header_item)
column += 1
# Ecrire le reste des lignes
for answers_record in new_retval_data: # Here we are using 'cursor' as an iterator
column = 0
row = row + 1
worksheet.write(row, column, str(session_start_date))
column += 1
worksheet.write(row, column, str(session_end_date))
column += 1
worksheet.write(row, column, str(todays_date))
column += 1
flattened_record = {}
for local_fiels in tab_exported_fields:
answers_record_JSON = ast.literal_eval(str(answers_record))
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
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 (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 données "