"""
Ce fichier permet de gerer de tout ce qui a atrait aux ressources humaines.
c'est dire :
- enseignent
- cadre administratif
- employés,
etc

Une ressource humaine a toujours un profil (enseignant, cadre admin) et une fonction.
"""

import pymongo
from pymongo import MongoClient
import json
from bson import ObjectId
import re
from datetime import datetime

import partners
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 email_inscription_mgt as email_inscription_mgt
import lms_chamilo.mysy_lms as mysy_lms
"""
Cette fonction crée le compte employé administrateur.
Ceci est fait à l'activation du compte, donc à ce moment il n'y pas de token de connexion.
D'ou la creation d'une fonction à part.

Apers la creation du compte, il faut ajouter les droits sur tous les module en read/read
dans la collection : 'user_access_right'
"""
def Add_Partner_Admin_Ressource_Humaine_No_Toke(diction):

    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['partner_recid',  "nom",  "email",  "comment", 'is_partner_admin_account', 'account_partner_id',
                      'is_partner_admin_account']

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'est pas autorisé")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = [ "partner_recid",  "email", ]

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification de l'identité et autorisation de l'entité qui
        appelle cette API
        """
        partner_recid = ""
        if ("partner_recid" in diction.keys()):
            if diction['partner_recid']:
                partner_recid = diction['partner_recid']

        """
                Recuperation des données fournies en entrée
                """
        data = {}
        data['partner_recid'] = partner_recid

        nom = ""
        if ("nom" in diction.keys()):
            if diction['nom']:
                nom = diction['nom']
                data['nom'] = diction['nom']

        is_partner_admin_account = "0"
        if ("is_partner_admin_account" in diction.keys()):
            if (diction['is_partner_admin_account'] and str(diction['is_partner_admin_account']) in ['0', '1']):
                is_partner_admin_account = diction['is_partner_admin_account']
        data['is_partner_admin_account'] = is_partner_admin_account


        data['ismanager'] = "0"

        email = ""
        if ("email" in diction.keys()):
            if diction['email']:
                email = diction['email']
                data['email'] = diction['email']
                if( mycommon.isEmailValide(email) is False):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - L'adresse email "+str(email)+" n'est pas valide")

                    return False, " - - L'adresse email "+str(email)+" n'est pas valide  "

        comment = ""
        if ("comment" in diction.keys()):
            if diction['comment']:
                comment = diction['comment']
                data['comment'] = diction['comment']

        account_partner_id = ""
        if ("account_partner_id" in diction.keys()):
            if diction['account_partner_id']:
                account_partner_id = diction['account_partner_id']
                data['account_partner_id'] = diction['account_partner_id']



        data['profil'] = "partner_admin"

        data['valide'] = '1'
        data['locked'] = '0'
        data['date_update'] = str(datetime.now())


        inserted_id = ""
        inserted_id = MYSY_GV.dbname['ressource_humaine'].insert_one(data).inserted_id
        if (not inserted_id):
            mycommon.myprint(
                " Impossible de créer la compte adminstrateur du partenaire ")
            return False, " Impossible de créer la compte adminstrateur du partenaire   "

        """
               Un fois le compte rh créer, on met à jour la collection partner_account, champ : 'ressource_humaine_id' avec le bon is 
               """
        MYSY_GV.dbname['partnair_account'].update_one({'recid': str(diction['partner_recid'])},
                                                      {'$set': {'ressource_humaine_id': str(inserted_id),
                                                                'is_partner_admin_account':is_partner_admin_account}})


        """
        Apres la creation de l'employé, il faut ajouter les droit admin au compte
        """
        for retval in MYSY_GV.dbname['application_modules'].find({'valide':'1', 'locked':'0'}):
            data_to_add = {}
            data_to_add['partner_owner_recid'] = str(partner_recid)
            data_to_add['module_name'] = retval['module_name']
            data_to_add['module'] = retval['module_name']
            data_to_add['user_id'] = str(inserted_id)
            data_to_add['read'] = True
            data_to_add['write'] = True
            data_to_add['valide'] = "1"
            data_to_add['locked'] = "0"
            data_to_add['date_update'] = str(datetime.now())



            MYSY_GV.dbname['user_access_right'].find_one_and_update(
                {'user_id': str(inserted_id), 'module_name': str(retval['module_name'])},
                {"$set": data_to_add},
                return_document=ReturnDocument.AFTER,
                upsert=True,
            )

        return True, str(inserted_id)

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de créer la compte administrateur du partenaire (2) "

#### PROD MIGRATION AND DELETE
def PROD_Add_Partner_Admin_Ressource_Humaine_No_Toke(diction):

    try:
        diction = mycommon.strip_dictionary(diction)


        CONNECTION_STRING = "mongodb://localhost:27017"
        client = MongoClient(CONNECTION_STRING)
        PROD_dbname = client['cherifdb']

        """
        Verification des input acceptés
        """
        field_list = ['partner_recid',  "nom",  "email",  "comment", 'is_partner_admin_account', 'account_partner_id',
                      'is_partner_admin_account']

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'est pas autorisé")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = [ "partner_recid",  "email", ]

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification de l'identité et autorisation de l'entité qui
        appelle cette API
        """
        partner_recid = ""
        if ("partner_recid" in diction.keys()):
            if diction['partner_recid']:
                partner_recid = diction['partner_recid']

        """
                Recuperation des données fournies en entrée
                """
        data = {}
        data['partner_recid'] = partner_recid

        nom = ""
        if ("nom" in diction.keys()):
            if diction['nom']:
                nom = diction['nom']
                data['nom'] = diction['nom']

        is_partner_admin_account = "0"
        if ("is_partner_admin_account" in diction.keys()):
            if (diction['is_partner_admin_account'] and str(diction['is_partner_admin_account']) in ['0', '1']):
                is_partner_admin_account = diction['is_partner_admin_account']
        data['is_partner_admin_account'] = is_partner_admin_account


        data['ismanager'] = "0"

        email = ""
        if ("email" in diction.keys()):
            if diction['email']:
                email = diction['email']
                data['email'] = diction['email']
                if( mycommon.isEmailValide(email) is False):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - L'adresse email "+str(email)+" n'est pas valide")

                    return False, " - - L'adresse email "+str(email)+" n'est pas valide  "

        comment = ""
        if ("comment" in diction.keys()):
            if diction['comment']:
                comment = diction['comment']
                data['comment'] = diction['comment']

        account_partner_id = ""
        if ("account_partner_id" in diction.keys()):
            if diction['account_partner_id']:
                account_partner_id = diction['account_partner_id']
                data['account_partner_id'] = diction['account_partner_id']



        data['profil'] = "partner_admin"

        data['valide'] = '1'
        data['locked'] = '0'
        data['date_update'] = str(datetime.now())


        inserted_id = ""
        #inserted_id = MYSY_GV.dbname['ressource_humaine'].insert_one(data).inserted_id
        inserted_id = PROD_dbname["ressource_humaine"].insert_one(data).inserted_id
        if (not inserted_id):
            mycommon.myprint(
                " Impossible de créer la compte adminstrateur du partenaire ")
            return False, " Impossible de créer la compte adminstrateur du partenaire   "

        """
               Un fois le compte rh créer, on met à jour la collection partner_account, champ : 'ressource_humaine_id' avec le bon is 
               """
        PROD_dbname["partnair_account"].update_one({'recid': str(diction['partner_recid'])},
                                                      {'$set': {'ressource_humaine_id': str(inserted_id),
                                                                'is_partner_admin_account':is_partner_admin_account}})


        """
        Apres la creation de l'employé, il faut ajouter les droit admin au compte
        """
        for retval in MYSY_GV.dbname['application_modules'].find({'valide':'1', 'locked':'0'}):
            data_to_add = {}
            data_to_add['partner_owner_recid'] = str(partner_recid)
            data_to_add['module_name'] = retval['module_name']
            data_to_add['module'] = retval['module_name']
            data_to_add['user_id'] = str(inserted_id)
            data_to_add['read'] = True
            data_to_add['write'] = True
            data_to_add['valide'] = "1"
            data_to_add['locked'] = "0"
            data_to_add['date_update'] = str(datetime.now())



            PROD_dbname["user_access_right"].find_one_and_update(
                {'user_id': str(inserted_id), 'module_name': str(retval['module_name'])},
                {"$set": data_to_add},
                return_document=ReturnDocument.AFTER,
                upsert=True,
            )

        return True, str(inserted_id)

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de créer la compte administrateur du partenaire (2) "

####

def Add_Ressource_Humaine(diction):

    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token',  "nom",  "email", "telephone", "website", "comment",'adr_adresse', 'adr_code_postal',
                      'adr_ville', 'adr_pays',  'profil', 'telephone_mobile', 'linkedin',
                      'facebook', 'twitter',  'prenom', 'fonction', 'civilite', 'superieur_hierarchie_id', 'ismanager',
                      'groupe_prix_achat_id', 'prix_achat', 'type_contrat', 'gategorie', 'date_naissance', 'competence'
                      ]

        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',  "email", ]

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans 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 s'il n'existe pas un cient du partenaire qui porte la meme adresse email
         """

        tmp_count = MYSY_GV.dbname['ressource_humaine'].count_documents({'email': str(diction['email']),
                                                               'valide': '1', 'partner_recid': my_partner['recid']})
        if (tmp_count > 0):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " - Il existe déjà une personne qui porte le même email principal  = " +str(diction['email']))

            return False, " - Vous avez  déjà une personne qui a le même email principal  " +str(diction['email'])+" "



        """
                Recuperation des données fournies en entrée
                """
        data = {}
        data['partner_recid'] = my_partner['recid']


        nom = ""
        if ("nom" in diction.keys()):
            if diction['nom']:
                nom = diction['nom']
        data['nom'] = nom


        prenom = ""
        if ("prenom" in diction.keys()):
            if diction['prenom']:
                prenom = diction['prenom']
        data['prenom'] = prenom

        date_naissance = ""
        if ("date_naissance" in diction.keys()):
            if diction['date_naissance']:
                date_naissance = str(diction['date_naissance']).strip()

                local_status = mycommon.CheckisDate(date_naissance)
                if (local_status is False):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " La date de naissance n'est pas au format 'jj/mm/aaaa' ")
                    return False, " La date de naissance n'est pas au format 'jj/mm/aaaa' "

        data['date_naissance'] = str(date_naissance)



        groupe_prix_achat_id = ""
        if ("groupe_prix_achat_id" in diction.keys()):
            if diction['groupe_prix_achat_id']:
                groupe_prix_achat_id = diction['groupe_prix_achat_id']

                if( MYSY_GV.dbname['purchase_prices'].count_documents({'_id':ObjectId(str(diction['groupe_prix_achat_id'])),
                                                                       'valide':'1',
                                                                       'locked':'0',
                                                                       'partner_owner_recid':str(my_partner['recid'])}) != 1):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - L'identifiant du groupe d'achat est invalide ")

                    return False, " L'identifiant du groupe d'achat est invalide  "


        data['groupe_prix_achat_id'] = groupe_prix_achat_id


        prix_achat = ""
        if ("prix_achat" in diction.keys()):
            if diction['prix_achat']:
                prix_achat = diction['prix_achat']
                local_status, local_retval = mycommon.IsFloat(prix_achat)
                if (local_status is False ):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " Le prix d'achat n'est pas pas valide ")

                    return False, "Le prix d'achat n'est pas pas valide  "

        data['prix_achat'] = prix_achat


        type_contrat = ""
        if ("type_contrat" in diction.keys()):
            if diction['type_contrat']:
                type_contrat = diction['type_contrat']
        data['type_contrat'] = type_contrat


        gategorie = ""
        if ("gategorie" in diction.keys()):
            if diction['gategorie']:
                gategorie = diction['gategorie']
        data['gategorie'] = gategorie



        ismanager = "0"
        if ("ismanager" in diction.keys()):
            if diction['ismanager']:
                ismanager = diction['ismanager']
                if( str(ismanager).lower() not in ['1', '0', 'oui', 'non']):
                    mycommon.myprint(str(inspect.stack()[0][3]) + " - Valeur du champ 'manager' invalide : "+str(ismanager)+". Les valeurs acceptée : '1', '0', 'oui', 'non'")
                    return False, str(inspect.stack()[0][3]) + " - Valeur du champ 'manager' invalide : "+str(ismanager)+". Les valeurs acceptée : '1', '0', 'oui', 'non'"

                if( str(ismanager).lower() == "oui"):
                    ismanager = "1"
                elif (str(ismanager).lower() == "non"):
                    ismanager = "0"

                ismanager = diction['ismanager']

        data['ismanager'] = ismanager

        fonction = ""
        if ("fonction" in diction.keys()):
            if diction['fonction']:
                fonction = diction['fonction']
        data['fonction'] = fonction

        superieur_hierarchie_id = ""
        if ("superieur_hierarchie_id" in diction.keys()):
            if diction['superieur_hierarchie_id']:
                superieur_hierarchie_id = diction['superieur_hierarchie_id']
        data['superieur_hierarchie_id'] = superieur_hierarchie_id

        civilite = ""
        if ("civilite" in diction.keys()):
            if diction['civilite']:
                civilite = str(diction['civilite']).lower()
        data['civilite'] = civilite



        adr_adresse = ""
        if ("adr_adresse" in diction.keys()):
            if diction['adr_adresse']:
                adr_adresse = diction['adr_adresse']
        data['adr_adresse'] = adr_adresse

        adr_code_postal = ""
        if ("adr_code_postal" in diction.keys()):
            if diction['adr_code_postal']:
                adr_code_postal = diction['adr_code_postal']
        data['adr_code_postal'] = adr_code_postal

        adr_ville = ""
        if ("adr_ville" in diction.keys()):
            if diction['adr_ville']:
                adr_ville = diction['adr_ville']
        data['adr_ville'] = adr_ville


        adr_pays = ""
        if ("adr_pays" in diction.keys()):
            if diction['adr_pays']:
                adr_pays = diction['adr_pays']
        data['adr_pays'] = adr_pays


        email = ""
        if ("email" in diction.keys()):
            if diction['email']:
                email = diction['email']
                if( mycommon.isEmailValide(email) is False):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - L'adresse email "+str(email)+" n'est pas valide")

                    return False, " - - L'adresse email "+str(email)+" n'est pas valide  "
        data['email'] = email


        telephone = ""
        if ("telephone" in diction.keys()):
            if diction['telephone']:
                telephone = diction['telephone']
        data['telephone'] = telephone

        telephone_mobile = ""
        if ("telephone_mobile" in diction.keys()):
            if diction['telephone_mobile']:
                telephone_mobile = diction['telephone_mobile']
        data['telephone_mobile'] = telephone_mobile


        website = ""
        if ("website" in diction.keys()):
            if diction['website']:
                website = diction['website']
        data['website'] = website

        comment = ""
        if ("comment" in diction.keys()):
            if diction['comment']:
                comment = diction['comment']
        data['comment'] = comment

        linkedin = ""
        if ("linkedin" in diction.keys()):
            if diction['linkedin']:
                linkedin = diction['linkedin']
        data['linkedin'] = linkedin

        facebook = ""
        if ("facebook" in diction.keys()):
            if diction['facebook']:
                facebook = diction['facebook']
        data['facebook'] = facebook

        twitter = ""
        if ("twitter" in diction.keys()):
            if diction['twitter']:
                twitter = diction['twitter']
        data['twitter'] = twitter

        competence = ""
        if ("competence" in diction.keys()):
            if diction['competence']:
                competence = diction['competence']
        data['competence'] = competence


        profil = ""
        if ("profil" in diction.keys()):
            if diction['profil']:
                profil = diction['profil']

                Rh_profil_count = MYSY_GV.dbname['ressource_humaine_profil'].count_documents({'profil_nom':str(profil), 'valide':'1', 'locked':'0'})

                qry = {'profil_nom':str(profil), 'valide':'1', 'locked':'0'}

                if( Rh_profil_count != 1):
                    mycommon.myprint(
                        "- Le type de profil  "+str(profil)+" n'est pas autorisé")
                    return False, "- Le type de profil  "+str(profil)+" n'est pas autorisé"
        data['profil'] = profil

        """
                Update du 22/10/2023 - Gestion des champs spécifiques ajoutés par le partenaire
                """

        # Recuperation des champs spécifiques se trouvant dans le dictionnaire. ils commencent tous par 'my_'
        for val in diction.keys():
            if (val.startswith('my_')):
                if (MYSY_GV.dbname['base_specific_fields'].count_documents(
                        {'partner_owner_recid': str(my_partner['recid']),
                         'related_collection': 'ressource_humaine',
                         'field_name': str(val),
                         'valide': '1',
                         'locked': '0'}) != 1):
                    mycommon.myprint(str(
                        inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'est pas autorisé ")
                    return False, " Les informations fournies sont incorrectes"

                data[str(val)] = diction[str(val)]


        data['valide'] = '1'
        data['locked'] = '0'
        data['date_update'] = str(datetime.now())
        data['update_by'] = str(my_partner['_id'])
        data['is_partner_admin_account'] = "0"

        # Creation du RecId
        data['recid'] = mycommon.create_user_recid()


        inserted_id = ""
        inserted_id = MYSY_GV.dbname['ressource_humaine'].insert_one(data).inserted_id
        if (not inserted_id):
            mycommon.myprint(
                " Impossible de créer la ressource ")
            return False, " Impossible de créer la ressource   "


        return True, " La ressource a été correctement créée"

    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 la ressource "


"""
Mise à jour d'une personne en se basant sur sont _id
"""
def Update_Ressource_Humaine(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
               Verification des input acceptés
               """
        field_list = ['token', "nom", "prenom",  "email",
                      "telephone", "website", "comment",'adr_adresse', 'adr_code_postal',
                      'adr_ville', 'adr_pays',  'profil', 'telephone_mobile', 'linkedin',
                      'facebook', 'twitter', '_id', 'prenom', 'fonction', 'civilite',
                      'superieur_hierarchie_id', 'ismanager', 'groupe_prix_achat_id', 'prix_achat', 'type_contrat',
                      'gategorie', 'date_naissance', 'competence']


        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'est pas autorisé")
                return False, " Les informations fournies sont incorrectes",



        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token',  '_id', 'email']

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans 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']

        # Verifier la validité du token
        retval = mycommon.check_partner_token_validity("", token)

        if retval is False:
            return "Err_Connexion", " La session de connexion n'est pas valide"

        partner_recid = mycommon.get_parnter_recid_from_token(token)
        if (partner_recid is False):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - partner_recid est KO. Les données de connexion sont incorrectes ")
            return False, " Vous n'etes pas autorisé à utiliser cette API "

        # Recuperation des données du partenaire
        local_status, my_partner = mycommon.get_partner_data_from_recid(partner_recid)
        if (local_status is False):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données du partenaire")
            return False, str(inspect.stack()[0][3]) + "  - impossible de récupérer les données du partenaire. "

        """
               Verification si cette adresse email n'existe pas deja pour ce partner
                 """

        qry_update =  {'_id': ObjectId(str(diction['_id'])), 'valide': '1', 'locked': '0', 'partner_recid': str(my_partner['recid']),}


        tmp_count = MYSY_GV.dbname['ressource_humaine'].count_documents(qry_update)
        if (tmp_count <= 0):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " - Cette personne n'existe pas: nom = "+str(diction['nom']))

            return False, " -  Cette personne n'est pas reconnue dans le système "

        stocked_rh_data = MYSY_GV.dbname['ressource_humaine'].find_one(qry_update)

        """
        Recuperation des données fournies en entrée
        """

        data_update = {}
        """
                        Recuperation des données fournies en entrée
                        """



        nom = ""
        if ("nom" in diction.keys()):
            data_update['nom'] = diction['nom']

        fonction = ""
        if ("fonction" in diction.keys()):
            data_update['fonction'] = diction['fonction']

        civilite = ""
        if ("civilite" in diction.keys()):
            data_update['civilite'] = str(diction['civilite']).lower()

        date_naissance = ""
        if ("date_naissance" in diction.keys()):
            if diction['date_naissance']:
                date_naissance = str(diction['date_naissance']).strip()

                local_status = mycommon.CheckisDate(date_naissance)
                if (local_status is False):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " La date de naissance n'est pas au format 'jj/mm/aaaa' ")
                    return False, " La date de naissance n'est pas au format 'jj/mm/aaaa' "

            data_update['date_naissance'] = str(date_naissance)


        groupe_prix_achat_id = ""
        if ("groupe_prix_achat_id" in diction.keys()):
            groupe_prix_achat_id = diction['groupe_prix_achat_id']

            if (MYSY_GV.dbname['purchase_prices'].count_documents(
                    {'_id': ObjectId(str(diction['groupe_prix_achat_id'])),
                     'valide': '1',
                     'locked': '0',
                     'partner_owner_recid': str(my_partner['recid'])}) != 1):
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " - L'identifiant du groupe d'achat est invalide ")

                return False, " L'identifiant du groupe d'achat est invalide  "

            data_update['groupe_prix_achat_id'] = groupe_prix_achat_id

        prix_achat = ""
        if ("prix_achat" in diction.keys()):
            prix_achat = diction['prix_achat']
            local_status, local_retval = mycommon.IsFloat(prix_achat)
            if (local_status is False):
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " Le prix d'achat n'est pas pas valide ")

                return False, "Le prix d'achat n'est pas pas valide  "

            data_update['prix_achat'] = prix_achat

        type_contrat = ""
        if ("type_contrat" in diction.keys()):
            type_contrat = diction['type_contrat']
            data_update['type_contrat'] = type_contrat

        gategorie = ""
        if ("gategorie" in diction.keys()):
            gategorie = diction['gategorie']
            data_update['gategorie'] = gategorie


        ismanager = "0"
        if ("ismanager" in diction.keys()):
            ismanager = diction['ismanager']
            if (ismanager != "0" and ismanager != "1"):
                mycommon.myprint(str(inspect.stack()[0][3]) + " - Valeur du champ 'manager' invalide : " + str(
                    ismanager) + ". Les valeurs acceptée : 1 ou 0")
                return False, str(inspect.stack()[0][3]) + " - Valeur du champ 'manager' invalide : " + str(
                    ismanager) + ". Les valeurs acceptée : 1 ou 0"

            ismanager = diction['ismanager']

        data_update['ismanager'] = ismanager



        prenom = ""
        if ("prenom" in diction.keys()):
            data_update['prenom'] = diction['prenom']

        superieur_hierarchie_id = ""
        if ("superieur_hierarchie_id" in diction.keys()):
            data_update['superieur_hierarchie_id'] = diction['superieur_hierarchie_id']



        profil = ""
        if ("profil" in diction.keys()):
            if diction['profil']:
                profil = diction['profil']

                Rh_profil_count = MYSY_GV.dbname['ressource_humaine_profil'].count_documents(
                    {'profil_nom': str(profil), 'valide': '1', 'locked': '0'})

                qry = {'profil_nom': str(profil), 'valide': '1', 'locked': '0'}

                if (Rh_profil_count != 1):
                    mycommon.myprint(
                        "- Le type de profil  " + str(profil) + " n'est pas autorisé")
                    return False, "- Le type de profil  " + str(profil) + " n'est pas autorisé"
            data_update['profil'] = profil

        fonction = ""
        if ("fonction" in diction.keys()):
            fonction = diction['fonction']
            data_update['fonction'] = diction['fonction']

        civilite = ""
        if ("civilite" in diction.keys()):
            civilite = diction['civilite']
            data_update['civilite'] = diction['civilite']

        adr_adresse = ""
        if ("adr_adresse" in diction.keys()):
            adr_adresse = diction['adr_adresse']
            data_update['adr_adresse'] = diction['adr_adresse']

        adr_code_postal = ""
        if ("adr_code_postal" in diction.keys()):
            adr_code_postal = diction['adr_code_postal']
            data_update['adr_code_postal'] = diction['adr_code_postal']

        adr_ville = ""
        if ("adr_ville" in diction.keys()):
            adr_ville = diction['adr_ville']
            data_update['adr_ville'] = diction['adr_ville']

        adr_pays = ""
        if ("adr_pays" in diction.keys()):
            adr_pays = diction['adr_pays']
            data_update['adr_pays'] = diction['adr_pays']


        telephone = ""
        if ("telephone" in diction.keys()):
            telephone = diction['telephone']
            data_update['telephone'] = diction['telephone']


        """
        21/01/24 - on ne modifie pas l'email s'il y a déjà une compte utilisateur
        """
        is_user_account_exist = 0
        email = ""
        if ("email" in diction.keys()):
            email = diction['email']
            if( email != stocked_rh_data['email'] ):
                """
                Verifier que l'email stocké n'est pas utilisé comme compte utilisateur
                """
                is_user_account_exist = MYSY_GV.dbname['partnair_account'].count_documents({'email':stocked_rh_data['email'], 'partner_owner_recid':str(my_partner['recid'])})
                if( is_user_account_exist <= 0  ):
                    if( mycommon.isEmailValide(email) is False ):
                        mycommon.myprint( " L'adresse email " + str(email) + " est invalide ")
                        return False, " L'adresse email " + str(email) + " est invalide "

                    data_update['email'] = email

                else:
                    mycommon.myprint(" L'adresse email " + str(email) + " est associée à un compte utilisateur. Mise à jour annulée ")
                    return False, "  L'adresse email " + str(email) + " est associée à un compte utilisateur. Mise à jour annulée  "

        telephone_mobile = ""
        if ("telephone_mobile" in diction.keys()):
            telephone_mobile = diction['telephone_mobile']
            data_update['telephone_mobile'] = diction['telephone_mobile']

        website = ""
        if ("website" in diction.keys()):
            website = diction['website']
            data_update['website'] = diction['website']

        comment = ""
        if ("comment" in diction.keys()):
            comment = diction['comment']
            data_update['comment'] = diction['comment']

        linkedin = ""
        if ("linkedin" in diction.keys()):
            linkedin = diction['linkedin']
            data_update['linkedin'] = diction['linkedin']

        facebook = ""
        if ("facebook" in diction.keys()):
            facebook = diction['facebook']
            data_update['facebook'] = diction['facebook']

        twitter = ""
        if ("twitter" in diction.keys()):
            twitter = diction['twitter']
            data_update['twitter'] = diction['twitter']

        competence = ""
        if ("competence" in diction.keys()):
            data_update['competence'] = diction['competence']



        """
        Update du 22/10/2023 - Gestion des champs spécifiques ajoutés par le partenaire
        """

        # Recuperation des champs spécifiques se trouvant dans le dictionnaire. ils commencent tous par 'my_'
        for val in diction.keys():
            if( val.startswith('my_') ):
                if( MYSY_GV.dbname['base_specific_fields'].count_documents({'partner_owner_recid':str(my_partner['recid']),
                                                                            'related_collection':'ressource_humaine',
                                                                             'field_name':str(val),
                                                                            'valide':'1',
                                                                            'locked':'0'}) != 1):
                    mycommon.myprint(str(
                        inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'est pas autorisé ")
                    return False, " Les informations fournies sont incorrectes"



                data_update[str(val)] = diction[str(val)]



        data_update['valide'] = '1'
        data_update['locked'] = '0'
        data_update['date_update'] = str(datetime.now())
        data_update['update_by'] = str(my_partner['_id'])

        """
                Clés de mise à jour 
        """
        data_cle = {'_id': ObjectId(str(diction['_id'])), 'valide': '1', 'is_partner_admin_account':'0', 'locked': '0', 'partner_recid': str(my_partner['recid']),}


        inserted_id = ""
        result = MYSY_GV.dbname['ressource_humaine'].find_one_and_update(
            data_cle,
            {"$set": data_update},
            upsert=False,
            return_document=ReturnDocument.AFTER
        )
        if (result is None or "_id" not in result.keys()):
            mycommon.myprint(
                " Impossible de mettre à jour les information : email = " + str(diction['email']))
            return False, " Impossible de mettre à jour les informations "

        return True, " Les données a été correctement mises à jour"

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de mettre à jour les données "


"""
Suppression d'une ressource humaine.

"""

def Delete_Ressource_Humaine(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
               Verification des input acceptés
               """
        field_list = ['token',  '_id', 'prenom', ]


        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']

        # Verifier la validité du token
        retval = mycommon.check_partner_token_validity("", token)

        if retval is False:
            return "Err_Connexion", " La session de connexion n'est pas valide"

        partner_recid = mycommon.get_parnter_recid_from_token(token)
        if (partner_recid is False):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - partner_recid est KO. Les données de connexion sont incorrectes ")
            return False, " Vous n'etes pas autorisé à utiliser cette API "

        # Recuperation des données du partenaire
        local_status, my_partner = mycommon.get_partner_data_from_recid(partner_recid)
        if (local_status is False):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données du partenaire")
            return False, str(inspect.stack()[0][3]) + "  - impossible de récupérer les données du partenaire. "


        """
        Verification de l'existance de l'employée a supprimer
        """
        existe_employee_count = MYSY_GV.dbname['ressource_humaine'].count_documents({'_id': ObjectId(str(diction['_id'])),
                                                                                     'partner_recid': str(my_partner['recid']),})

        if( existe_employee_count <= 0 ):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Cet employé est invalide")
            return False, str(inspect.stack()[0][3]) + "  -Cet employé est invalide "

        """
        Suppression des eventuels affectation de cet employé
        """
        MYSY_GV.dbname['ressource_humaine_affectation'].delete_many({'related_collection_recid': (str(diction['_id'])),
                                                                                     'partner_recid': str(my_partner['recid']),
                                                                     'related_collection':'ressource_humaine'})



        """
        Si cet employé est manager d'autres employés, alors mettre à vide le champ 'superieur_hierarchie_id'
        """
        MYSY_GV.dbname['ressource_humaine'].update_many({'superieur_hierarchie_id': str(diction['_id']),
                                                                     'partner_recid': str(my_partner['recid']),},
                                                        {"$set":{"superieur_hierarchie_id":""}})


        """
        Suppression de l'employé
        """
        MYSY_GV.dbname['ressource_humaine'].delete_many({'_id': ObjectId(str(diction['_id'])),
                                                         'is_partner_admin_account': '0',
                                                                     'partner_recid': str(my_partner['recid']),})



        return True, " L'employé a été correctement supprimé "

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de supprimer l'employé "



"""
Recuperation de la liste des ressources humaines d'une entité en se basant sur 
- token (partner_recid)

"""
def Get_List_Ressource_Humaine(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', ]

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'existe pas")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', ]
        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans 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']

        # Verifier la validité du token
        retval = mycommon.check_partner_token_validity("", token)

        if retval is False:
            return "Err_Connexion", " La session de connexion n'est pas valide"

        # Recuperation des données du partenaire
        local_status, my_partner = mycommon.get_partner_data_from_token(token)
        if (local_status is False):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données de l'utilisateur ")
            return False, str(inspect.stack()[0][3]) + "  - impossible de récupérer les données de l'utilisateur. "

        """
                Clés de mise à jour 
                """
        data_cle = {}
        data_cle['partner_recid'] = str(my_partner['recid'])

        data_cle['locked'] = "0"
        data_cle['valide'] = "1"
        data_cle['is_partner_admin_account'] = "0"

        RetObject = []
        val_tmp = 1

        for retval in MYSY_GV.dbname['ressource_humaine'].find(data_cle):
            user = retval
            user['id'] = str(val_tmp)
            val_tmp = val_tmp + 1

            """
            Si l'employé a un superieur_hierarchie_id, alors on va aller récupérer son nom et prenom.
            ce superieur est une ressource humaime
            """
            superieur_hierarchie_nom = ""
            superieur_hierarchie_prenom = ""
            if( "superieur_hierarchie_id" in retval.keys() and retval['superieur_hierarchie_id']):
                hierarchi_data = MYSY_GV.dbname['ressource_humaine'].find_one({'_id':ObjectId(str(retval['superieur_hierarchie_id'])),
                                                                               'valide':'1', 'locked':'0'}, {'nom':1, 'prenom':1})
                if( hierarchi_data is None):
                    superieur_hierarchie_nom = ""
                    superieur_hierarchie_prenom = ""

                else:
                    if ("superieur_hierarchie_nom" in hierarchi_data.keys()):
                        superieur_hierarchie_nom = hierarchi_data['superieur_hierarchie_nom']

                    if ("superieur_hierarchie_prenom" in hierarchi_data.keys()):
                        superieur_hierarchie_prenom = hierarchi_data['superieur_hierarchie_prenom']

            user['superieur_hierarchie_nom'] = superieur_hierarchie_nom
            user['superieur_hierarchie_prenom'] = superieur_hierarchie_prenom

            # Recuperation du groupe de prix d'achat si il existe.
            groupe_prix_achat_code = ""
            if ("groupe_prix_achat_id" in retval.keys() and retval['groupe_prix_achat_id']):
                groupe_prix_achat_id_data = MYSY_GV.dbname['purchase_prices'].find_one(
                    {'_id': ObjectId(str(diction['groupe_prix_achat_id'])),
                     'valide': '1',
                     'locked': '0',
                     'partner_owner_recid': str(my_partner['recid'])})
                if( groupe_prix_achat_id_data and "code_groupe_prix" in groupe_prix_achat_id_data.keys()):
                    groupe_prix_achat_code = groupe_prix_achat_id_data['code_groupe_prix']

            user['groupe_prix_achat_code'] = groupe_prix_achat_code


            RetObject.append(mycommon.JSONEncoder().encode(user))

        return True, RetObject


    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de récupérer les données des employés "

"""
Recuperation de la liste des profils de ressources humaines
"""
def Get_List_Profil_Ressource_Humaine(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', ]

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'existe pas")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', ]
        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans 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']

        # Verifier la validité du token
        retval = mycommon.check_partner_token_validity("", token)

        if retval is False:
            return "Err_Connexion", " La session de connexion n'est pas valide"

        # Recuperation des données du partenaire
        local_status, my_partner = mycommon.get_partner_data_from_token(token)
        if (local_status is False):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données de l'utilisateur ")
            return False, str(inspect.stack()[0][3]) + "  - impossible de récupérer les données de l'utilisateur. "

        """
                Clés de mise à jour 
                """
        data_cle = {}
        data_cle['locked'] = "0"
        data_cle['valide'] = "1"

        RetObject = []
        val_tmp = 1

        for retval in MYSY_GV.dbname['ressource_humaine_profil'].find(data_cle):
            user = retval
            user['id'] = str(val_tmp)
            val_tmp = val_tmp + 1


            RetObject.append(mycommon.JSONEncoder().encode(user))

        return True, RetObject


    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de récupérer la liste des contact "


"""
Recuperation de la liste des ressources humaines avec des filtres sur 
- nom
- email
"""
def Get_List_Ressource_Humaine_with_filter(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', 'nom', 'email', 'formation', 'session']

        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', ]
        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']

        # Verifier la validité du token
        retval = mycommon.check_partner_token_validity("", token)

        if retval is False:
            return "Err_Connexion", " La session de connexion n'est pas valide"

        # Recuperation des données du partenaire
        local_status, my_partner = mycommon.get_partner_data_from_token(token)
        if (local_status is False):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données de l'utilisateur ")
            return False, str(inspect.stack()[0][3]) + "  - impossible de récupérer les données de l'utilisateur. "

        filt_nom = {}
        if ("nom" in diction.keys()):
            filt_nom = {'nom': {'$regex': str(diction['nom']), "$options": "i"}}

        filt_email = {}
        if ("email" in diction.keys()):
            filt_email = {
                'email': {'$regex': str(diction['email']), "$options": "i"}}

        sub_filt_formation = {}
        if ("formation" in diction.keys()):
            sub_filt_formation = {
                'external_code': {'$regex': str(diction['formation']), "$options": "i"}, 'partner_owner_recid':str(my_partner['recid'])}

        sub_filt_session = {}
        if ("session" in diction.keys()):
            sub_filt_session = { 'code_session': {'$regex': str(diction['session']), "$options": "i"}, 'partner_owner_recid':str(my_partner['recid'])}



        """
        Recuperation des id des codes session pouvant correspondre a la valeur fournie par le user
        (regexp bien sur)
        """
        filt_session = {}
        Lists_session_id = []
        if ("session" in diction.keys()):
            for Lists_session in  MYSY_GV.dbname['session_formation'].find(sub_filt_session, {'_id':1}):
                Lists_session_id.append(str(Lists_session['_id']))

            if( len(Lists_session_id) > 0):
                filt_session = {'related_target_collection_id': {'$in': Lists_session_id, },
                                  'related_collection': 'ressource_humaine',
                                  'related_target_collection': 'session_formation',
                                  }


        """
       Recuperation des id des formation pouvant correspondre a la valeur fournie par le user
       (regexp bien sur)
        """
        filt_formation = {}
        Lists_formation_id = []
        if ("formation" in diction.keys()):
            for Lists_formation in MYSY_GV.dbname['myclass'].find(sub_filt_formation, {'_id': 1}):
                Lists_formation_id.append(str(Lists_formation['_id']))


            if(len(Lists_formation_id) > 0 ):
                filt_formation = {'related_target_collection_id': {'$in': Lists_formation_id, },
                                  'related_collection':'ressource_humaine',
                                  'related_target_collection':'myclass',
                                  }


        """
        Clés de mise à jour 
        """

        data_cle = {}
        data_cle['partner_recid'] = str(my_partner['recid'])

        data_cle['locked'] = "0"
        data_cle['valide'] = "1"

        find_qry = {'$and':[{'partner_recid': str(my_partner['recid']), 'valide':'1', 'locked':'0', 'is_partner_admin_account':'0' }, filt_nom, filt_email] }


        new_myquery = [{'$match': find_qry},
                   {"$addFields": {"ressource_humaine_Id": {"$toString": "$_id"}}},
                       {'$sort': {'_id': 1}},
                   {'$lookup':
                       {
                           'from': 'ressource_humaine_affectation',
                           'localField': "ressource_humaine_Id",
                           'foreignField': 'related_collection_recid',
                           'pipeline': [{'$match':{ '$and' : [ filt_formation, filt_session, {'partner_owner_recid': str(my_partner['recid'])}, {'valide':'1'}] } }, {'$project': {'poste': 1,
                                                                                                                                                     'date_du': 1,
                                                                                                                                                     'date_au':1,
                                                                                                                                                     'related_target_collection':1
                                                                                                                                                     }}],
                           'as': 'ressource_humaine_affectation_collection'
                       }
                   }
                   ]

        #print(" ##### new_myquery aa = ", new_myquery)
        #print(" ##### find_qry aa = ", find_qry)

        New_RetObject = []
        New_val_tmp = 1


        """"
        Si dans la requette on a les champ : 'formation'  ou 'session' on utiliser la requete ci-dessous.
        Cela veut dire qu'on cherche des ressources qui sont des affectation avec une formation ou une session.
        """
        if( "formation" in diction.keys() or "session" in diction.keys()):
            for New_retVal in MYSY_GV.dbname['ressource_humaine'].aggregate(new_myquery):
                if ('ressource_humaine_affectation_collection' in New_retVal.keys() and len(New_retVal['ressource_humaine_affectation_collection']) > 0):
                    #print(" #### RESULT New_retVal for = ", New_retVal['nom'])
                    user = {}
                    user['id'] = str(New_val_tmp)
                    New_val_tmp = New_val_tmp + 1


                    user['_id'] = New_retVal['_id']
                    user['partner_recid'] = New_retVal['partner_recid']
                    user['nom'] = New_retVal['nom']
                    user['email'] = New_retVal['email']

                    if ("prenom" in New_retVal.keys()):
                        user['prenom'] = New_retVal['prenom']
                    else:
                        user['prenom'] = ""

                    if ("civilite" in New_retVal.keys()):
                        user['civilite'] = str(New_retVal['civilite']).lower()
                    else:
                        user['civilite'] = ""

                    if( "telephone" in New_retVal.keys()):
                        user['telephone'] = New_retVal['telephone']
                    else:
                        user['telephone'] = ""

                    if ("adr_adresse" in New_retVal.keys()):
                        user['adr_adresse'] = New_retVal['adr_adresse']
                    else:
                        user['adr_adresse'] = ""

                    if ("adr_code_postal" in New_retVal.keys()):
                        user['adr_code_postal'] = New_retVal['adr_code_postal']
                    else:
                        user['adr_code_postal'] = ""

                    if ("adr_ville" in New_retVal.keys()):
                        user['adr_ville'] = New_retVal['adr_ville']
                    else:
                        user['adr_ville'] = ""

                    if ("adr_pays" in New_retVal.keys()):
                        user['adr_pays'] = New_retVal['adr_pays']
                    else:
                        user['adr_pays'] = ""

                    if ("date_naissance" in New_retVal.keys()):
                        user['date_naissance'] = New_retVal['date_naissance']
                    else:
                        user['date_naissance'] = "01/01/1900"

                    if ("ismanager" in New_retVal.keys()):
                        user['ismanager'] = New_retVal['ismanager']
                    else:
                        user['ismanager'] = ""

                    if ("user_login" in New_retVal.keys()):
                        user['user_login'] = New_retVal['user_login']
                    else:
                        user['user_login'] = ""


                    if ("superieur_hierarchie_id" in New_retVal.keys()):
                        user['superieur_hierarchie_id'] = New_retVal['superieur_hierarchie_id']
                    else:
                        user['superieur_hierarchie_id'] = ""


                    if ("groupe_prix_achat_id" in New_retVal.keys()):
                        user['groupe_prix_achat_id'] = New_retVal['groupe_prix_achat_id']
                    else:
                        user['groupe_prix_achat_id'] = ""


                    if ("prix_achat" in New_retVal.keys()):
                        user['prix_achat'] = New_retVal['prix_achat']
                    else:
                        user['prix_achat'] = ""

                    if ("type_contrat" in New_retVal.keys()):
                        user['type_contrat'] = New_retVal['type_contrat']
                    else:
                        user['type_contrat'] = ""

                    if ("gategorie" in New_retVal.keys()):
                        user['gategorie'] = New_retVal['gategorie']
                    else:
                        user['gategorie'] = ""


                    if ("telephone_mobile" in New_retVal.keys()):
                        user['telephone_mobile'] = New_retVal['telephone_mobile']
                    else:
                        user['telephone_mobile'] = "New_retVal['telephone_mobile']"


                    user['affectation'] = []
                    for local_affectation in New_retVal['ressource_humaine_affectation_collection']:
                        affectation = {}
                        if ("poste" in local_affectation.keys()):
                            affectation['poste'] = local_affectation['poste']
                        else:
                            affectation['poste'] = ""

                        affectation['related_target_collection'] = local_affectation['related_target_collection']
                        affectation['date_du'] = local_affectation['date_du']
                        affectation['date_au'] = local_affectation['date_au']


                        print(" ### AFFACTATION local_affectation = ", local_affectation)

                    New_RetObject.append(mycommon.JSONEncoder().encode(user))

            return True, New_RetObject
        else:
            # Il s'agit d'une recherche sans lien avec des fonctions occupés dans une formation ou une session
            RetObject = []
            val_tmp = 1

            for retval in MYSY_GV.dbname['ressource_humaine'].find(find_qry):
                user = retval
                user['id'] = str(val_tmp)

                if ("prenom" in retval.keys()):
                    user['prenom'] = retval['prenom']
                else:
                    user['prenom'] = ""

                if ("civilite" in retval.keys()):
                    user['civilite'] = str(retval['civilite']).lower()
                else:
                    user['civilite'] = ""

                if ("telephone" in retval.keys()):
                    user['telephone'] = retval['telephone']
                else:
                    user['telephone'] = ""

                if ("adr_adresse" in retval.keys()):
                    user['adr_adresse'] = retval['adr_adresse']
                else:
                    user['adr_adresse'] = ""

                if ("adr_code_postal" in retval.keys()):
                    user['adr_code_postal'] = retval['adr_code_postal']
                else:
                    user['adr_code_postal'] = ""

                if ("adr_ville" in retval.keys()):
                    user['adr_ville'] = retval['adr_ville']
                else:
                    user['adr_ville'] = ""

                if ("adr_pays" in retval.keys()):
                    user['adr_pays'] = retval['adr_pays']
                else:
                    user['adr_pays'] = ""

                if ("date_naissance" in retval.keys()):
                    user['date_naissance'] = retval['date_naissance']
                else:
                    user['date_naissance'] = "01/01/1900"

                if ("ismanager" in retval.keys()):
                    user['ismanager'] = retval['ismanager']
                else:
                    user['ismanager'] = ""

                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 contact "


"""
Recherche sans filter - no_filter
"""
def Get_List_Ressource_Humaine_no_filter(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', ]

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'existe pas")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', ]
        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans 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']

        # Verifier la validité du token
        retval = mycommon.check_partner_token_validity("", token)

        if retval is False:
            return "Err_Connexion", " La session de connexion n'est pas valide"

        # Recuperation des données du partenaire
        local_status, my_partner = mycommon.get_partner_data_from_token(token)
        if (local_status is False):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données de l'utilisateur ")
            return False, str(inspect.stack()[0][3]) + "  - impossible de récupérer les données de l'utilisateur. "



        """
                Clés de mise à jour 
                """
        data_cle = {}
        data_cle['partner_recid'] = str(my_partner['recid'])

        data_cle['locked'] = "0"
        data_cle['valide'] = "1"


        find_qry = {'partner_recid': str(my_partner['recid']), 'valide':'1', 'locked':'0' }


        RetObject = []
        val_tmp = 1

        for retval in MYSY_GV.dbname['ressource_humaine'].find(find_qry).sort([("_id", pymongo.DESCENDING), ]):
            user = retval
            user['id'] = str(val_tmp)
            if ("prenom" in retval.keys()):
                user['prenom'] = retval['prenom']
            else:
                user['prenom'] = ""

            if ("civilite" in retval.keys()):
                user['civilite'] = str(retval['civilite']).lower()
            else:
                user['civilite'] = ""

            if ("telephone" in retval.keys()):
                user['telephone'] = retval['telephone']
            else:
                user['telephone'] = ""

            if ("adr_adresse" in retval.keys()):
                user['adr_adresse'] = retval['adr_adresse']
            else:
                user['adr_adresse'] = ""

            if ("adr_code_postal" in retval.keys()):
                user['adr_code_postal'] = retval['adr_code_postal']
            else:
                user['adr_code_postal'] = ""

            if ("adr_ville" in retval.keys()):
                user['adr_ville'] = retval['adr_ville']
            else:
                user['adr_ville'] = ""

            if ("adr_pays" in retval.keys()):
                user['adr_pays'] = retval['adr_pays']
            else:
                user['adr_pays'] = ""

            if ("date_naissance" in retval.keys()):
                user['date_naissance'] = retval['date_naissance']
            else:
                user['date_naissance'] = "01/01/1900"

            if ("ismanager" in retval.keys()):
                user['ismanager'] = retval['ismanager']
            else:
                user['ismanager'] = ""

            if ("user_login" in retval.keys()):
                user['user_login'] = retval['user_login']
            else:
                user['user_login'] = ""

            val_tmp = val_tmp + 1
            is_admin_account_count = MYSY_GV.dbname['partnair_account'].count_documents({'ressource_humaine_id':str(retval['_id']), 'is_partner_admin_account':'1'}) # exclure les comptes admin
            if( is_admin_account_count <= 0 ):
                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 employés "



"""
Recuperation d'une ressource donnée en se basant sur on token, _id, 
"""
def Get_Given_Ressource_Humaine(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']

        # Verifier la validité du token
        retval = mycommon.check_partner_token_validity("", token)

        if retval is False:
            return "Err_Connexion", " La session de connexion n'est pas valide"

        # Recuperation des données du partenaire
        local_status, my_partner = mycommon.get_partner_data_from_token(token)
        if (local_status is False):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données de l'utilisateur ")
            return False, str(inspect.stack()[0][3]) + "  - impossible de récupérer les données de l'utilisateur. "



        """
                Clés de mise à jour 
                """
        data_cle = {}
        data_cle['partner_recid'] = str(my_partner['recid'])
        data_cle['_id'] = ObjectId(str(diction['_id']))

        data_cle['valide'] = "1"
        data_cle['locked'] = "0"
        data_cle['is_partner_admin_account'] = "0"

        RetObject = []
        val_tmp = 1

        #print(" ### data_cle = ", data_cle)
        for retval in MYSY_GV.dbname['ressource_humaine'].find(data_cle):
            user = retval
            user['id'] = str(val_tmp)
            val_tmp = val_tmp + 1

            if ("civilite" not in retval.keys()):
                user['civilite'] = ""
            elif (retval['civilite'] not in MYSY_GV.CIVILITE):
                # la civilité n'est pas une de celle autorisée, alors je renvoie vide
                user['civilite'] = ""


            """
                        Si l'employé a un superieur_hierarchie_id, alors on va aller récupérer son nom et prenom.
                        ce superieur est une ressource humaime
                        """

            superieur_hierarchie_nom = ""
            superieur_hierarchie_prenom = ""
            if ("superieur_hierarchie_id" in retval.keys() and retval['superieur_hierarchie_id']):
                hierarchi_data_qry =  {'_id': ObjectId(str(retval['superieur_hierarchie_id'])), 'valide': '1', 'locked': '0'}

                hierarchi_data = MYSY_GV.dbname['ressource_humaine'].find_one( hierarchi_data_qry)

                if (hierarchi_data is None):
                    superieur_hierarchie_nom = ""
                    superieur_hierarchie_prenom = ""

                else:
                    if ("nom" in hierarchi_data.keys()):
                        superieur_hierarchie_nom = hierarchi_data['nom']

                    if ("prenom" in hierarchi_data.keys()):
                        superieur_hierarchie_prenom = hierarchi_data['prenom']

            user['superieur_hierarchie_nom'] = superieur_hierarchie_nom
            user['superieur_hierarchie_prenom'] = superieur_hierarchie_prenom

            # Recuperation du groupe de prix d'achat si il existe.
            groupe_prix_achat_code = ""
            if ("groupe_prix_achat_id" in retval.keys() and retval['groupe_prix_achat_id']):
                groupe_prix_achat_id_data = MYSY_GV.dbname['purchase_prices'].find_one(
                    {'_id': ObjectId(str(diction['groupe_prix_achat_id'])),
                     'valide': '1',
                     'locked': '0',
                     'partner_owner_recid': str(my_partner['recid'])})
                if (groupe_prix_achat_id_data and "code_groupe_prix" in groupe_prix_achat_id_data.keys()):
                    groupe_prix_achat_code = groupe_prix_achat_id_data['code_groupe_prix']

            user['groupe_prix_achat_code'] = groupe_prix_achat_code

            # Recuperer les info necessaire sur le compte (login) de l'employe
            if( "account_partner_id" in retval.keys() and retval['account_partner_id']):

                account_data = MYSY_GV.dbname['partnair_account'].find_one({'_id':ObjectId(str(retval['account_partner_id'])),
                                                                            'recid':str(my_partner['recid'])
                                                                            }, {'lms_virtualhost_url':1, 'mysy_lms_user_id':1,
                                                                                'lms_username':1, 'lms_account_disable':1, 'locked':1})

                lms_virtualhost_url = ""
                if(account_data and "lms_virtualhost_url" in account_data.keys() ):
                    lms_virtualhost_url = account_data['lms_virtualhost_url']
                user['lms_virtualhost_url'] = lms_virtualhost_url

                mysy_lms_user_id = ""
                if (account_data and "mysy_lms_user_id" in account_data.keys()):
                    mysy_lms_user_id = account_data['mysy_lms_user_id']
                user['mysy_lms_user_id'] = mysy_lms_user_id

                lms_username = ""
                if (account_data and "lms_username" in account_data.keys()):
                    lms_username = account_data['lms_username']
                user['lms_username'] = lms_username

                lms_account_disable = ""
                if (account_data and "lms_account_disable" in account_data.keys()):
                    lms_account_disable = account_data['lms_account_disable']
                user['lms_account_disable'] = lms_account_disable

                locked = ""
                if (account_data and "locked" in account_data.keys()):
                    locked = account_data['locked']
                user['locked'] = locked


            """
            Si on a des compétences associés, alors on va aller cherche la note dans la collection 'base_competence_type'.
            
            /!\ on a volontaire fait ainsi pour garder la gestion de la note coté serveur.
            en cas de changement de note (donc d'echelle de note), pas de besoin de faire de la data migration
            
            """

            if( "list_competence" in user.keys() ):
                for local_val in user['list_competence'] :
                    local_niveau = str(local_val['niveau']).lower()


                    niveau_data = MYSY_GV.dbname['base_competence_level'].find_one({'code':str(local_niveau),
                                                                                    'partner_owner_recid':'default',
                                                                                    'valide':'1',
                                                                                    'locked':'0'})

                    local_data_note = "0"
                    if( niveau_data and "note" in niveau_data.keys() ):
                        local_data_note = niveau_data['note']

                    local_val['note'] = local_data_note


            RetObject.append(mycommon.JSONEncoder().encode(user))

        #print(" ### RetObject = ", RetObject)
        return True, RetObject


    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de récupérer les données de la  personne "

"""
Cette fonction ajoute une image de profil d'un employé
"""
def Update_Ressource_Humaine_Image(file_img=None, Folder=None, diction=None):
    try:

        # Dictionnaire des champs utilisables
        '''
        # Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
        # Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
        # Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
        # field_list.
        '''
        field_list = ['token', 'file_img_recid',  'rh_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, "  Le champ  '" + val + "' n'est pas accepté "

        '''
        Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
        On controle que les champs obligatoires sont presents dans la liste 
        '''
        field_list_obligatoire = ['token']
        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " La valeur '" + val + "' n'est pas presente dans liste "

        # recuperation des paramettre
        token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                token = diction['token']

        local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
        if (local_status is not True):
            return local_status, my_partner



        rh_id = ""
        if ("rh_id" in diction.keys()):
            if diction['rh_id']:
                rh_id = diction['rh_id']


        if( file_img ):
            recordimage_diction = {}
            recordimage_diction['token'] = diction['token']
            recordimage_diction['related_collection'] = "ressource_humaine"
            recordimage_diction['type_img'] = "user"
            recordimage_diction['related_collection_recid'] = str(rh_id)
            recordimage_diction['image_recid'] = diction['file_img_recid']


            local_status, local_message = mycommon.recordClassImage_v2(file_img, MYSY_GV.upload_folder, recordimage_diction)
            if( local_status is False):
                return local_status, local_message

        return True, "L'image a été correctement enregistrée"

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
        return False, "Impossible d'enregistrer l'image"

"""
Suppresion d'un image d'une ressource humaine
"""
def DeleteImage_Ressource_Humaine(diction=None):
    try:

        # Dictionnaire des champs utilisables
        field_list = ['token', 'image_recid', ]
        incom_keys = diction.keys()

        '''
        # Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
        # Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
        # Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
        # field_list.
        '''
        for val in incom_keys:
            if str(val).lower() not in str(field_list).lower():
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " Le champ  '" + val + "' n'est pas accepté dans cette API")
                return False, " Impossible de se connecter"

        '''
        Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
        On controle que les champs obligatoires sont presents dans la liste 
        '''
        field_list_obligatoire = ['token', 'image_recid']
        for val in field_list_obligatoire:
            if str(val).lower() not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " La valeur '" + val + "' n'est pas presente dans liste des champs")
                return False, "Impossible de se connecter"

        mydata = {}
        mytoken = ""

        # recuperation des paramettre
        if ("token" in diction.keys()):
            if diction['token']:
                mytoken = diction['token']

        image_recid = ""
        if ("image_recid" in diction.keys()):
            if diction['image_recid']:
                image_recid = diction['image_recid']

        local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
        if (local_status is not True):
            return local_status, my_partner

        # " Lecture du fichier "
        # print(" Lecture du fichier : " + saved_file + ".  le token  est :" + str(mytoken))
        nb_line = 0
        coll_name = MYSY_GV.dbname['mysy_images']

        query_delete = {"recid": image_recid,}


        ret_val = coll_name.delete_one({"recid": image_recid,}, )



        print(" ### recordClassImage_v2 :L'image a été correctement supprimée ")
        return True, "L'image a été correctement supprimée"


    except  Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        print(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
        return False, "Impossible de supprimer l'image "


""" Recuperation de l'image d'un employé

/!\ important : on prend le 'related_collection_recid' comme le '_id' de la collection inscription
"""
def getRecoded_Employee_Image_from_front(diction=None):
    try:
        # Dictionnaire des champs utilisables
        field_list = ['token', 'rh_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, requete annulée")
                return False, " Impossible de récupérer les informations"

        '''
        Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
        On controle que les champs obligatoires sont presents dans la liste 
        '''
        field_list_obligatoire = ['token', 'rh_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, " Impossible de récupérer les informations"


        local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
        if (local_status is not True):
            return local_status, my_partner


        qery_images = {'locked': '0', 'valide': '1', 'related_collection': 'ressource_humaine',
                       'related_collection_recid': str(diction['rh_id'])}

        #print(" ### qery_images = ", qery_images)

        RetObject = []
        employee_images = {}
        # Recuperation des image 'logo' et 'cachet' si le partenaire en a
        for retVal in MYSY_GV.dbname['mysy_images'].find(qery_images):
            if ('type_img' in retVal.keys()):
                if (retVal['type_img'] == "user"):
                    employee_images['logo_img'] = retVal['img'].decode()
                    employee_images['logo_img_recid'] = retVal['recid']


        RetObject.append(mycommon.JSONEncoder().encode(employee_images))


        return True, RetObject

    except  Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        print(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de recupérer l'image de l'employé "


"""
Cette fontion retourne la liste des manager
les personne qui ont statut manager à 1
"""
def Get_List_Manager_Ressource_Humaine(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', ]

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'existe pas")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', ]
        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans 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']

        # Verifier la validité du token
        retval = mycommon.check_partner_token_validity("", token)

        if retval is False:
            return "Err_Connexion", " La session de connexion n'est pas valide"

        # Recuperation des données du partenaire
        local_status, my_partner = mycommon.get_partner_data_from_token(token)
        if (local_status is False):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données de l'utilisateur ")
            return False, str(inspect.stack()[0][3]) + "  - impossible de récupérer les données de l'utilisateur. "

        """
                Clés de mise à jour 
                """
        data_cle = {}
        data_cle['partner_recid'] = str(my_partner['recid'])
        data_cle['ismanager'] = "1"
        data_cle['locked'] = "0"
        data_cle['valide'] = "1"
        data_cle['is_partner_admin_account'] = "0"

        RetObject = []
        val_tmp = 1

        for retval in MYSY_GV.dbname['ressource_humaine'].find(data_cle):
            user = retval
            user['id'] = str(val_tmp)
            val_tmp = val_tmp + 1

            """
            Si l'employé a un superieur_hierarchie_id, alors on va aller récupérer son nom et prenom.
            ce superieur est une ressource humaime
            """
            superieur_hierarchie_nom = ""
            superieur_hierarchie_prenom = ""
            if( "superieur_hierarchie_id" in retval.keys() and retval['superieur_hierarchie_id']):
                hierarchi_data = MYSY_GV.dbname['ressource_humaine'].find_one({'_id':ObjectId(str(retval['superieur_hierarchie_id'])),
                                                                               'valide':'1', 'locked':'0'}, {'nom':1, 'prenom':1})
                if( hierarchi_data is None):
                    superieur_hierarchie_nom = ""
                    superieur_hierarchie_prenom = ""

                else:
                    if ("superieur_hierarchie_nom" in hierarchi_data.keys()):
                        superieur_hierarchie_nom = hierarchi_data['superieur_hierarchie_nom']

                    if ("superieur_hierarchie_prenom" in hierarchi_data.keys()):
                        superieur_hierarchie_prenom = hierarchi_data['superieur_hierarchie_prenom']

            user['superieur_hierarchie_nom'] = superieur_hierarchie_nom
            user['superieur_hierarchie_prenom'] = superieur_hierarchie_prenom
            user['superieur_hierarchie_nom_prenom'] = superieur_hierarchie_nom+" "+superieur_hierarchie_prenom

            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 contact "



""" Import des employés en mass
Avec l'import d'un fichier csv
"""
def Add_Ressource_Humaine_mass(file=None, Folder=None, diction=None):
    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 = ['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 participants annulée")
                return False, " Verifier votre API"

        '''
        Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
        On controle que les champs obligatoires sont presents dans la liste 
        '''
        field_list_obligatoire = ['token', ]

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " Verifier votre API, Toutes les informations techniques ne sont pas fournies"

        my_token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                my_token = diction['token']

        partner_recid = mycommon.get_parnter_recid_from_token(my_token)
        if (partner_recid is False):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - partner_recid KO : Impossible d'importer la liste des participants ")
            return False, " Les information de connexion sont incorrectes. Impossible d'importer la liste des participants"

        # Verifier la validité du token
        retval = mycommon.check_partner_token_validity("", my_token)
        if retval is False:
            return "Err_Connexion", " La session de connexion n'est pas valide"

        status, saved_file = mycommon.Upload_Save_CSV_File(file, Folder)
        if (status == False):
            mycommon.myprint("Impossible de récupérer correctement le fichier à importer")
            return False, "Impossible d'importer la liste des participants, le nom du fichier est incorrect "

        """"
         Controle de l'integrité du fichier
        """
        local_controle_status, local_controle_message = Controle_Add_Ressource_Humaine_mass(saved_file,
                                                                                                           Folder,
                                                                                                           diction)

        if (local_controle_status is False):
            return local_controle_status, local_controle_message

        #print(" #### local_controle_message = ", local_controle_message)

        nb_line = 0

        df = pd.read_csv(saved_file, encoding='utf8',  on_bad_lines='skip', sep=';', encoding_errors='ignore')
        df = df.fillna('')

        # Dictionnaire des champs utilisables
        '''
        # Verification que les noms des colonne sont bien corrects"
        '''
        field_list = ['nom', 'prenom', 'email', 'telephone_mobile', 'telephone', 'profil', 'ismanager', 'superieur_hierarchie_email', 'civilite',
                        'adresse', 'code_postal', 'ville', 'pays', 'facebook', 'fonction', 'linkedin', 'twitter', 'date_naissance']


        # Controle du nombre de lignes dans le fichier.
        total_rows = len(df)
        if( total_rows > MYSY_GV.MAX_PARTICIPANT_BY_CSV ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " Le fichier comporte plus de "+str(MYSY_GV.MAX_PARTICIPANT_BY_CSV)+" lignes.")
            return False, " Le fichier comporte plus de "+str(MYSY_GV.MAX_PARTICIPANT_BY_CSV)+" lignes."


        #print(df.columns)
        for val in df.columns:
            if str(val).lower()  not in field_list:
                mycommon.myprint(
                    str(inspect.stack()[0][3])+" : entete du fichier csv. '" + val + "' n'est pas acceptée")
                return False, " Entete du fichier csv. '" + val + "' n'est pas acceptée"

        # Verification des champs obligatoires dans le fichier
        field_list_obligatoire_file = ['prenom', 'nom',  'email', 'ismanager', 'profil', ]

        for val in field_list_obligatoire_file:
            if val not in df.columns:
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " : Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire")
                return False, " Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire "


        x = range(0, total_rows)
        for n in x:
            mydata = {}
            mydata['prenom'] = str(df['prenom'].values[n])
            mydata['nom'] = str(df['nom'].values[n])
            mydata['profil'] = str(df['profil'].values[n])

            rh_profil_count = MYSY_GV.dbname['ressource_humaine_profil'].count_documents({'profil_nom':str(mydata['profil']), 'valide':'1'})
            if( rh_profil_count<= 0):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " Le champ profil " + str(
                        df['profil'].values[n]) + " est invalide. Rapprochez de votre administrateur pour créer ce profil d'employé")
                return False, " Le champ profil  -" + str(
                    df['profil'].values[n]) + "- est invalide.  Rapprochez de votre administrateur pour créer ce profil d'employé"


            ismanager = str(df['ismanager'].values[n])

            if( str(ismanager).lower() not in ['1', '0', 'oui', 'non']):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " Le champ ismanager " + str(df['ismanager'].values[n]) + " est invalide. Les valeurs autorisées : 1, 0, oui, non")
                return False, " Le champ ismanager  -" + str(df['ismanager'].values[n]) + "- est invalide. Les valeurs autorisées : 1, 0, oui, non"

            if(str(ismanager) == "oui" ):
                mydata['ismanager'] = "1"
            elif (str(ismanager) == "non"):
                mydata['ismanager'] = "0"
            else:
                mydata['ismanager'] = ismanager

            mydata['email'] = str(df['email'].values[n])
            regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
            if (not re.fullmatch(regex, str(df['email'].values[n]))):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " l'adresse email " + str(df['email'].values[n]) + " est invalide")
                return False, " L'adresse email  -" + str(df['email'].values[n]) + "- est invalide"


            superieur_hierarchie_id = ""
            superieur_hierarchie_email = ""
            if ("superieur_hierarchie_email" in df.keys()):
                if (str(df['superieur_hierarchie_email'].values[n])):

                    if (not re.fullmatch(regex, str(df['email'].values[n]))):
                        mycommon.myprint(
                            str(inspect.stack()[0][3]) + " L'adresse email du manager " + str(
                                df['email'].values[n]) + " est invalide")
                        return False, " L'adresse email du manager  -" + str(df['email'].values[n]) + "- est invalide"

                    superieur_hierarchie_email = str(df['superieur_hierarchie_email'].values[n])
                    superieur_hierarchie_data_count = MYSY_GV.dbname['ressource_humaine'].count_documents({'email':str(superieur_hierarchie_email),
                                                                                                     'partner_recid':str(partner_recid), 'valide':'1', 'locked':'0'})

                    if( superieur_hierarchie_data_count <= 0):
                        mycommon.myprint(
                            str(inspect.stack()[0][3]) + " Aucun manager avec l'adresse email " + str(
                                df['superieur_hierarchie_email'].values[n]) + " ")
                        return False, " Aucun manager avec l'adresse email  -" + str(df['superieur_hierarchie_email'].values[n]) + ""

                    if (superieur_hierarchie_data_count > 1):
                        mycommon.myprint(
                            str(inspect.stack()[0][3]) + " Il a plusieurs managers avec l'adresse email " + str(
                                df['superieur_hierarchie_email'].values[n]) + " ")
                        return False, " Il a plusieurs managers avec l'adresse email  -" + str(
                            df['superieur_hierarchie_email'].values[n]) + ""

                    superieur_hierarchie_data = MYSY_GV.dbname['ressource_humaine'].find_one(
                        {'email': str(superieur_hierarchie_email),
                         'partner_recid': str(partner_recid), 'valide': '1', 'locked': '0'},{'_id':1})

                    superieur_hierarchie_id = superieur_hierarchie_data['_id']

                mydata['superieur_hierarchie_id'] = superieur_hierarchie_id

            mydata['token'] = str(my_token)

            telephone_mobile = ""
            if ("telephone_mobile" in df.keys()):
                if (str(df['telephone_mobile'].values[n])):
                    telephone_mobile = str(df['telephone_mobile'].values[n])
                mydata['telephone_mobile'] = telephone_mobile

            date_naissance = ""
            if ("date_naissance" in df.keys()):
                if (str(df['date_naissance'].values[n])):
                    date_naissance = str(df['date_naissance'].values[n])

                    local_status = mycommon.CheckisDate(date_naissance)
                    if (local_status is False):
                        mycommon.myprint(
                            str(inspect.stack()[0][
                                    3]) + " La date de naissance n'est pas au format 'jj/mm/aaaa' ")
                        return False, " La date de naissance n'est pas au format 'jj/mm/aaaa' "

                mydata['date_naissance'] = str(date_naissance)


            telephone = ""
            if ("telephone" in df.keys()):
                if (str(df['telephone'].values[n])):
                    telephone = str(df['telephone'].values[n])
                mydata['telephone'] = telephone

            civilite = ""
            if ("civilite" in df.keys()):
                if (str(df['civilite'].values[n])):
                    civilite = str(df['civilite'].values[n])
                    if(str(civilite).lower() not in ['m', 'mme', 'neutre'] ):
                        mycommon.myprint(
                            str(inspect.stack()[0][3]) + " Le champ civilité " + str(
                                df['civilite'].values[n]) + " est invalide. Les valeurs autorisées : 'm', 'mme', 'neutre'")
                        return False, " Le champ civilité  -" + str(
                            df['civilite'].values[n]) + "- est invalide. Les valeurs autorisées : 'm', 'mme', 'neutre' "


                mydata['civilite'] = str(civilite).lower().strip()


            ville = ""
            if ("ville" in df.keys()):
                if (str(df['ville'].values[n])):
                    ville = str(df['ville'].values[n])
                mydata['adr_ville'] = ville

            adresse = ""
            if ("adresse" in df.keys()):
                if (str(df['adresse'].values[n])):
                    pays = str(df['adresse'].values[n])
                mydata['adr_adresse'] = adresse

            code_postal = ""
            if ("code_postal" in df.keys()):
                if (str(df['code_postal'].values[n])):
                    code_postal = str(df['code_postal'].values[n])
                mydata['adr_code_postal'] = code_postal

            ville = ""
            if ("ville" in df.keys()):
                if (str(df['ville'].values[n])):
                    ville = str(df['ville'].values[n])
                mydata['adr_ville'] = ville

            pays = ""
            if ("pays" in df.keys()):
                if (str(df['pays'].values[n])):
                    pays = str(df['pays'].values[n])
                mydata['adr_pays'] = pays

            facebook = ""
            if ("facebook" in df.keys()):
                if (str(df['facebook'].values[n])):
                    facebook = str(df['facebook'].values[n])
                mydata['facebook'] = facebook

            fonction = ""
            if ("fonction" in df.keys()):
                if (str(df['fonction'].values[n])):
                    fonction = str(df['fonction'].values[n])
                mydata['fonction'] = fonction

            linkedin = ""
            if ("linkedin" in df.keys()):
                if (str(df['linkedin'].values[n])):
                    linkedin = str(df['linkedin'].values[n])
                mydata['linkedin'] = linkedin

            twitter = ""
            if ("twitter" in df.keys()):
                if (str(df['twitter'].values[n])):
                    linkedin = str(df['twitter'].values[n])
                mydata['twitter'] = twitter


            clean_dict = {k: mydata[k] for k in mydata if ( str(mydata[k]) != "nan") }

            #print( "####  clean_dict ", clean_dict)

            is_employe_exist_count = MYSY_GV.dbname['ressource_humaine'].count_documents({'email':str(mydata['email']), 'partner_recid':str(partner_recid),
                                                                                    'valide':'1', 'locked':'0'})
            if( is_employe_exist_count > 0):
                ## Si l'adresse email exist deja en base, alors on fait une mise à jour
                is_employe_exist_data = MYSY_GV.dbname['ressource_humaine'].find_one(
                    {'email': str(mydata['email']), 'partner_recid': str(partner_recid),
                     'valide': '1', 'locked': '0'}, {'_id':1})


                clean_dict['_id'] = str(is_employe_exist_data['_id'])
                

                status, retval = Update_Ressource_Humaine(clean_dict)
                if (status is False):
                    return status, retval


            if (is_employe_exist_count <= 0):
                ## Si l'adress email n'hexiste pas en base, on fait une creation
                status, retval =  Add_Ressource_Humaine(clean_dict)
                if( status is False ):
                    return status, retval

        print(str(total_rows)+" employé ont été inserés")

        return True, str(total_rows)+" employés ont été inserées / Mises à jour"

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
        return False, "Impossible d'importer les employés  en masse "

"""
Avant de lancer l'import en masse, cette fonction va verifer que le fichier est bon en entier
Cela evite les imports partielles
"""
def Controle_Add_Ressource_Humaine_mass(saved_file=None, Folder=None, diction=None):
    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 = ['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'est pas autorisé")
                return False, " Verifier votre API"

        '''
        Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
        On controle que les champs obligatoires sont presents dans la liste 
        '''
        field_list_obligatoire = ['token', ]

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " Verifier votre API, Toutes les informations techniques ne sont pas fournies"

        my_token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                my_token = diction['token']

        partner_recid = mycommon.get_parnter_recid_from_token(my_token)
        if (partner_recid is False):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - partner_recid KO : Impossible d'importer la liste des participants ")
            return False, " Les information de connexion sont incorrectes. Impossible d'importer la liste des participants"

        # Verifier la validité du token
        retval = mycommon.check_partner_token_validity("", my_token)
        if retval is False:
            return "Err_Connexion", " La session de connexion n'est pas valide"



        df = pd.read_csv(saved_file, encoding='utf8',  on_bad_lines='skip', sep=';', encoding_errors='ignore')
        df = df.fillna('')

        # Dictionnaire des champs utilisables
        '''
        # Verification que les noms des colonne sont bien corrects"
        '''
        field_list = ['nom', 'prenom', 'email', 'telephone_mobile', 'telephone', 'profil', 'ismanager', 'superieur_hierarchie_email',
                      'civilite', 'adresse', 'code_postal', 'ville', 'pays', 'facebook', 'fonction', 'linkedin', 'twitter', 'date_naissance']


        # Controle du nombre de lignes dans le fichier.
        total_rows = len(df)
        if( total_rows > MYSY_GV.MAX_PARTICIPANT_BY_CSV ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " Le fichier comporte plus de "+str(MYSY_GV.MAX_PARTICIPANT_BY_CSV)+" lignes.")
            return False, " Le fichier comporte plus de "+str(MYSY_GV.MAX_PARTICIPANT_BY_CSV)+" lignes."


        #print(df.columns)
        for val in df.columns:
            if str(val).lower()  not in field_list:
                mycommon.myprint(
                    str(inspect.stack()[0][3])+" : entete du fichier csv. Champ '" + val + "' n'est pas acceptée")
                return False, " Entete du fichier csv. '" + val + "' n'est pas acceptée"

        # Verification des champs obligatoires dans le fichier
        field_list_obligatoire_file = ['prenom', 'nom',  'email', 'ismanager', 'profil', ]

        for val in field_list_obligatoire_file:
            if val not in df.columns:
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " : Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire")
                return False, " Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire "


        x = range(0, total_rows)
        for n in x:
            mydata = {}
            mydata['prenom'] = str(df['prenom'].values[n])
            mydata['nom'] = str(df['nom'].values[n])
            mydata['profil'] = str(df['profil'].values[n])

            rh_profil_count = MYSY_GV.dbname['ressource_humaine_profil'].count_documents({'profil_nom':str(mydata['profil']), 'valide':'1', })
            if( rh_profil_count<= 0):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " Le champ profil " + str(
                        df['profil'].values[n]) + " est invalide.")
                return False, " Le champ profil  -" + str(
                    df['profil'].values[n]) + "- est invalide."


            mydata['ismanager'] = str(df['ismanager'].values[n])

            if( str(mydata['ismanager']).lower() not in ['1', '0', 'oui', 'non']):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " Le champ ismanager " + str(df['ismanager'].values[n]) + " est invalide. Les valeurs autorisées : 1, 0, oui, non")
                return False, " Le champ ismanager  -" + str(df['ismanager'].values[n]) + "- est invalide. Les valeurs autorisées : 1, 0, oui, non"


            mydata['email'] = str(df['email'].values[n])
            regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
            if (not re.fullmatch(regex, str(df['email'].values[n]))):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " l'adresse email " + str(df['email'].values[n]) + " est invalide")
                return False, " L'adresse email  -" + str(df['email'].values[n]) + "- est invalide"


            superieur_hierarchie_id = ""
            superieur_hierarchie_email = ""
            if ("superieur_hierarchie_email" in df.keys()):
                if (str(df['superieur_hierarchie_email'].values[n])):

                    if (not re.fullmatch(regex, str(df['email'].values[n]))):
                        mycommon.myprint(
                            str(inspect.stack()[0][3]) + " L'adresse email du manager " + str(
                                df['email'].values[n]) + " est invalide")
                        return False, " L'adresse email du manager  -" + str(df['email'].values[n]) + "- est invalide"

                    superieur_hierarchie_email = str(df['superieur_hierarchie_email'].values[n])
                    superieur_hierarchie_data_count = MYSY_GV.dbname['ressource_humaine'].count_documents({'email':str(superieur_hierarchie_email),
                                                                                                     'partner_recid':str(partner_recid), 'valide':'1', 'locked':'0'})

                    if( superieur_hierarchie_data_count <= 0):
                        mycommon.myprint(
                            str(inspect.stack()[0][3]) + " Aucun manager avec l'adresse email " + str(
                                df['superieur_hierarchie_email'].values[n]) + ". Vous devez saisir l'adresse email exacte du supérieur hiérarchique ")
                        return False, " Aucun manager avec l'adresse email  -" + str(df['superieur_hierarchie_email'].values[n]) + ". Vous devez saisir l'adresse email exacte du supérieur hiérarchique "

                    if (superieur_hierarchie_data_count > 1):
                        mycommon.myprint(
                            str(inspect.stack()[0][3]) + " Il y a plusieurs managers avec l'adresse email " + str(
                                df['superieur_hierarchie_email'].values[n]) + " ")
                        return False, " Il y a plusieurs managers avec l'adresse email  -" + str(
                            df['superieur_hierarchie_email'].values[n]) + ""

                    superieur_hierarchie_data = MYSY_GV.dbname['ressource_humaine'].find_one(
                        {'email': str(superieur_hierarchie_email),
                         'partner_recid': str(partner_recid), 'valide': '1', 'locked': '0'},{'_id':1})

                    superieur_hierarchie_id = superieur_hierarchie_data['_id']

            mydata['superieur_hierarchie_id'] = superieur_hierarchie_id



            mydata['token'] = str(my_token)


            telephone_mobile = ""
            if ("telephone_mobile" in df.keys()):
                if (str(df['telephone_mobile'].values[n])):
                    telephone_mobile = str(df['telephone_mobile'].values[n])
            mydata['telephone_mobile'] = telephone_mobile


            telephone = ""
            if ("telephone" in df.keys()):
                if (str(df['telephone'].values[n])):
                    telephone = str(df['telephone'].values[n])
            mydata['telephone'] = telephone

            civilite = ""
            if ("civilite" in df.keys()):
                if (str(df['civilite'].values[n])):
                    civilite = str(df['civilite'].values[n])
                    if(str(civilite).lower() not in ['m', 'mme', 'neutre'] ):
                        mycommon.myprint(
                            str(inspect.stack()[0][3]) + " Le champ civilité " + str(
                                df['civilite'].values[n]) + " est invalide. Les valeurs autorisées : 'm', 'mme', 'neutre'")
                        return False, " Le champ civilité  -" + str(
                            df['civilite'].values[n]) + "- est invalide. Les valeurs autorisées : 'm', 'mme', 'neutre' "


            mydata['civilite'] = str(civilite).lower()

            date_naissance = ""
            if ("date_naissance" in df.keys()):
                if (str(df['date_naissance'].values[n])):
                    date_naissance = str(df['date_naissance'].values[n])

                    local_status = mycommon.CheckisDate(date_naissance)
                    if (local_status is False):
                        mycommon.myprint(
                            str(inspect.stack()[0][
                                    3]) + " La date de naissance "+str(date_naissance)+" n'est pas au format 'jj/mm/aaaa' ")
                        return False, " La date de naissance  "+str(date_naissance)+" n'est pas au format 'jj/mm/aaaa' "

                mydata['date_naissance'] = str(date_naissance)

            ville = ""
            if ("ville" in df.keys()):
                if (str(df['ville'].values[n])):
                    ville = str(df['ville'].values[n])
            mydata['adr_ville'] = ville

            adresse = ""
            if ("adresse" in df.keys()):
                if (str(df['adresse'].values[n])):
                    pays = str(df['adresse'].values[n])
            mydata['adr_adresse'] = adresse

            code_postal = ""
            if ("code_postal" in df.keys()):
                if (str(df['code_postal'].values[n])):
                    code_postal = str(df['code_postal'].values[n])
            mydata['adr_code_postal'] = code_postal

            ville = ""
            if ("ville" in df.keys()):
                if (str(df['ville'].values[n])):
                    ville = str(df['ville'].values[n])
            mydata['adr_ville'] = ville

            pays = ""
            if ("pays" in df.keys()):
                if (str(df['pays'].values[n])):
                    pays = str(df['pays'].values[n])
            mydata['adr_pays'] = pays

            facebook = ""
            if ("facebook" in df.keys()):
                if (str(df['facebook'].values[n])):
                    facebook = str(df['facebook'].values[n])
            mydata['facebook'] = facebook

            fonction = ""
            if ("fonction" in df.keys()):
                if (str(df['fonction'].values[n])):
                    fonction = str(df['fonction'].values[n])
            mydata['fonction'] = fonction

            linkedin = ""
            if ("linkedin" in df.keys()):
                if (str(df['linkedin'].values[n])):
                    linkedin = str(df['linkedin'].values[n])
            mydata['linkedin'] = linkedin

            twitter = ""
            if ("twitter" in df.keys()):
                if (str(df['twitter'].values[n])):
                    linkedin = str(df['twitter'].values[n])
            mydata['twitter'] = twitter


            clean_dict = {k: mydata[k] for k in mydata if ( str(mydata[k]) != "nan") }

            print( "####  clean_dict ", clean_dict)



        return True, str(total_rows)+" employés dans le fichier"

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
        return False, "Impossible de controler le fichier des employes à importer en masse "


""""
récupérer les affectations d'un employé
:!\ : Pour le moment une affectation ne peut concerner que 
- Une formation (collection : myclass) ou
- Une session de formation (collection session_formation) ou
- rien du tout (cela veut dire que la fonction concene le partenaire, donc l'ecole.
exemple : Directeur des etude, etc)
"""
def Get_List_Ressource_Humaine_Affectation(diction):
    try:
        field_list_obligatoire = [ 'token', 'rh_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, "  La valeur '" + val + "' n'est pas presente dans liste"

        my_token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                my_token = diction['token']



        # Recuperation 	du 	recid 	du 	partenaire
        partner_recid = mycommon.get_parnter_recid_from_token(str(my_token))
        if partner_recid is False:
            mycommon.myprint(str(inspect.stack()[0][3]) + " -  Impossible d'imprimer la fiche detaillée")
            return False, " Les informations d'identification sont invalides"

        local_status, my_partner_data = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
        if (local_status is not True):
            return local_status, my_partner_data



        qry_affectation = {'partner_owner_recid':str(my_partner_data['recid']),
                           'related_collection':'ressource_humaine', 'related_collection_recid':str(diction['rh_id']),
                           'valide':'1', 'locked':'0'}


        print(" ### qry_affectation = ",qry_affectation)

        RetObject = []
        val_tmp = 1

        for retval in MYSY_GV.dbname['ressource_humaine_affectation'].find(qry_affectation):
            user = retval
            user['id'] = str(val_tmp)
            val_tmp = val_tmp + 1

            related_target_collection_id_nom = ""
            related_target_collection_object = ""

            # Si l'affectation a un 'related_target_collection_id', alors cela veut dire qu'il faut aller chercheer
            # la cible de cette affection.
            if( "related_target_collection_id" in retval.keys() and "related_target_collection" in retval.keys()):
                if( retval["related_target_collection_id"] and retval["related_target_collection"]):

                    # Si l'affectation concerne une formation
                    if( retval["related_target_collection"] == "myclass"):
                        affectation_target_data = MYSY_GV.dbname[retval["related_target_collection"]].find_one({"_id":ObjectId(str( retval["related_target_collection_id"])),
                                                                                                            'partner_owner_recid':str(partner_recid),
                                                                                                            'valide':'1', 'locked':"0"})

                        if(affectation_target_data is not None):
                            related_target_collection_id_nom = affectation_target_data["title"]
                            related_target_collection_object = "Formation"

                    elif (  retval["related_target_collection"] == "session_formation") :
                        # Si l'affectation concerne une session
                        affectation_target_data = MYSY_GV.dbname[retval["related_target_collection"]].find_one(
                            {"_id": ObjectId(str(retval["related_target_collection_id"])),
                             'partner_owner_recid': str(partner_recid),
                             'valide': '1'})

                        if (affectation_target_data is not None):
                            related_target_collection_id_nom = affectation_target_data["code_session"]
                            related_target_collection_object = "Session Formation"




            user['related_target_collection_id_nom'] = related_target_collection_id_nom
            user['related_target_collection_object'] = related_target_collection_object

            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 affectations de l'employé "


"""
Ajout d'une affectation d'une ressource humaine à un poste
"""

def Add_Affectation_Ressource_Humaine_Poste(diction):
    try:

        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', "rh_id", "poste", "date_du", "date_au", "comment", 'related_target_collection', 'related_target_collection_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', 'rh_id', "poste", 'date_du' ]

        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, " Toutes le information obligatoires n'ont pas été fournies"

        token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                token = diction['token']



        # Recuperation 	du 	recid 	du 	partenaire
        partner_recid = mycommon.get_parnter_recid_from_token(str(token))
        if partner_recid is False:
            mycommon.myprint(str(inspect.stack()[0][3]) + " -  Impossible de récupérer le partner_recid")
            return False, " Les informations d'identification sont invalides"

        local_status, my_partner_data = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
        if (local_status is not True):
            return local_status, my_partner_data

        rh_id = ""
        if ("rh_id" in diction.keys()):
            if diction['rh_id']:
                rh_id = diction['rh_id']
        # Verifier que l'employé existe bien
        employee_existe_count = MYSY_GV.dbname['ressource_humaine'].count_documents({'_id':ObjectId(str(rh_id)), 'partner_recid':str(partner_recid),
                                                                                     'valide':'1', 'locked':'0'})

        if( employee_existe_count <= 0 ) :
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Employé invalide ")
            return False, "  Employé invalide "

        if (employee_existe_count > 1):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Employé incohérent. il a plusieurs employés avec le meme id ")
            return False, "  Employé incohérent. il a plusieurs employés avec le meme id "


        date_du = ""
        if ("date_du" in diction.keys()):
            if diction['date_du']:
                date_du = str(diction['date_du'])[0:10]

        # la date_du etant obligatoire, donc normal de faire le controle apres le "IF"
        local_status = mycommon.CheckisDate(date_du)
        if (local_status is False):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " La date de debut d'affectation n'est pas au format 'jj/mm/aaaa' ")
            return False, "La date de debut d'affectation n'est pas au format 'jj/mm/aaaa'"


        date_au = ""
        if ("date_au" in diction.keys()):
            if diction['date_au']:
                date_au = str(diction['date_au'])[0:10]
                local_status = mycommon.CheckisDate(date_au)
                if (local_status is False):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " La date de fin d'affectation n'est pas au format 'jj/mm/aaaa' ")
                    return False, "La date de fin d'affectation n'est pas au format 'jj/mm/aaaa'"


        comment = ""
        if ("comment" in diction.keys()):
            if diction['comment']:
                comment = diction['comment']
                if(len(str(comment)) > 500):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " Le champ 'comment' a plus de 500 caractères ")
                    return False, "Le champ 'comment' a plus de 500 caractères "

        poste = ""
        if ("poste" in diction.keys()):
            poste = diction['poste']
            if (len(str(poste)) > 255):
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " Le champ 'poste' a plus de 255 caractères ")
                return False, "Le champ 'poste' a plus de 255 caractères "


        related_target_collection_id = ""
        related_target_collection = ""
        if ("related_target_collection_id" in diction.keys() and "related_target_collection" in diction.keys()):
            if( diction['related_target_collection_id'] and diction['related_target_collection'] ):
                related_target_collection_id = diction['related_target_collection_id']
                related_target_collection = diction['related_target_collection']
            else:
                if( diction['related_target_collection_id'] != "" or diction['related_target_collection'] != ""):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " Les données related_target_collection_id et related_target_collection sont incohérentes")
                    return False, "Les données related_target_collection_id et related_target_collection sont incohérentes  "




        # Verifier qu'on pas une affectation avec le meme poste qui demarre à la meme date.
        if_affectation_exist_count_qry = {'related_collection':'ressource_humaine', 'related_collection_recid':str(diction['rh_id']),
                                          'partner_owner_recid':str(partner_recid),'valide':'1', 'poste':str(diction['poste']),
                                          'date_du':str(date_du)}

        if_affectation_exist_count = MYSY_GV.dbname['ressource_humaine_affectation'].count_documents(if_affectation_exist_count_qry)
        if(if_affectation_exist_count > 0  ):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " Cet employé occupe déjà ce poste ")
            return False, "Cet employé occupe déjà ce poste "


        my_data = {}
        my_data['related_collection'] = 'ressource_humaine'
        my_data['related_collection_recid'] = str(diction['rh_id'])
        my_data['partner_owner_recid'] = str(partner_recid)
        my_data['poste'] = str(poste)
        my_data['related_target_collection_id'] = str(related_target_collection_id)
        my_data['related_target_collection'] = str(related_target_collection)
        my_data['comment'] = str(diction['comment'])

        my_data['date_du'] = str(date_du)
        my_data['date_au'] = str(date_au)
        my_data['valide'] = "1"
        my_data['locked'] = "0"
        my_data['date_update'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
        my_data['update_by'] = str(my_partner_data['_id'])


        inserted_data = MYSY_GV.dbname['ressource_humaine_affectation'].insert_one(my_data)
        if( inserted_data is None):
            return False," Impossible d'affecter l'employé au poste (2)"


        return True, "L'affectation de l'employé a été correctement faite."

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible d'affecter l'employé au poste "


"""
Mise à jour d'une affectation
"""
def Update_Affectation_Ressource_Humaine_Poste(diction):
    try:

        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', "rh_id", "poste", "date_du", "date_au", "comment", "_id", 'related_target_collection', 'related_target_collection_id']

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'est pas autorisé")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification des champs obligatoires
        """

        field_list_obligatoire = ['token', '_id', 'date_du', 'poste', "rh_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, " Toutes le information obligatoires n'ont pas été fournies"

        token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                token = diction['token']



        # Recuperation 	du 	recid 	du 	partenaire
        partner_recid = mycommon.get_parnter_recid_from_token(str(token))
        if partner_recid is False:
            mycommon.myprint(str(inspect.stack()[0][3]) + " -  Impossible de récupérer le partner_recid")
            return False, " Les informations d'identification sont invalides"

        local_status, my_partner_data = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
        if (local_status is not True):
            return local_status, my_partner_data

        update_data = {}

        rh_id = ""
        if ("rh_id" in diction.keys()):
            if diction['rh_id']:
                rh_id = diction['rh_id']
        # Verifier que l'employé existe bien
        employee_existe_count = MYSY_GV.dbname['ressource_humaine'].count_documents({'_id':ObjectId(str(rh_id)), 'partner_recid':str(partner_recid),
                                                                                     'valide':'1', 'locked':'0'})

        if( employee_existe_count <= 0 ) :
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Employé invalide ")
            return False, "  Employé invalide "

        if (employee_existe_count > 1):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Employé incohérent. il a plusieurs employés avec le meme id ")
            return False, "  Employé incohérent. il a plusieurs employés avec le meme id "


        date_du = ""
        if ("date_du" in diction.keys()):
            if diction['date_du']:
                date_du = str(diction['date_du'])[0:10]

        # la date_du etant obligatoire, donc normal de faire le controle apres le "IF"
        local_status = mycommon.CheckisDate(date_du)
        if (local_status is False):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " La date de debut d'affectation n'est pas au format 'jj/mm/aaaa' ")
            return False, "La date de debut d'affectation n'est pas au format 'jj/mm/aaaa'"
        update_data['date_du'] = date_du


        date_au = ""
        if ("date_fin" in diction.keys()):
            date_au = str(diction['date_fin'])[0:10]
            local_status = mycommon.CheckisDate(date_au)
            if (local_status is False):
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " La date de fin d'affectation n'est pas au format 'jj/mm/aaaa' ")
                return False, "La date de fin d'affectation n'est pas au format 'jj/mm/aaaa'"

            update_data['date_du'] = date_du

        comment = ""
        if ("comment" in diction.keys()):
            comment = diction['comment']
            if(len(str(comment)) > 500):
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " Le champ 'comment' a plus de 500 caractères ")
                return False, "Le champ 'comment' a plus de 500 caractères "
            update_data['comment'] = comment


        poste = ""
        if ("poste" in diction.keys()):
            poste = diction['poste']
            if (len(str(poste)) > 255):
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " Le champ 'poste' a plus de 255 caractères ")
                return False, "Le champ 'poste' a plus de 255 caractères "
        update_data['poste'] = poste


        related_target_collection_id = ""
        related_target_collection = ""
        if ("related_target_collection_id" in diction.keys() and "related_target_collection" in diction.keys()):
            if (diction['related_target_collection_id'] and diction['related_target_collection']):
                related_target_collection_id = diction['related_target_collection_id']
                related_target_collection = diction['related_target_collection']
            else:
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " Les données related_target_collection_id et related_target_collection sont incohérentes")
                return False, "Les données related_target_collection_id et related_target_collection sont incohérentes  "

            update_data['related_target_collection_id'] = str(related_target_collection_id)
            update_data['related_target_collection'] = str(related_target_collection)

        update_data['date_update'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
        update_data['update_by'] = str(my_partner_data['_id'])


        # Verifier l'existance de l'affectation
        affectation_existe_count_qry = {'_id': ObjectId(str(diction['_id'])), 'valide': "1", "locked":"0", 'partner_owner_recid':str(partner_recid)}
        print(" ### affectation_existe_count_qry = ", affectation_existe_count_qry)
        affectation_existe_count = MYSY_GV.dbname['ressource_humaine_affectation'].count_documents( affectation_existe_count_qry)

        if( affectation_existe_count != 1 ):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de mettre à jour cette affectation. Données incohérentes ")
            return False, " Impossible de mettre à jour cette affectation. Données incohérentes   "


        inserted_data = MYSY_GV.dbname['ressource_humaine_affectation'].find_one_and_update(
            {'_id': ObjectId(str(diction['_id'])), 'valide': "1", "locked":"0", 'partner_owner_recid':str(partner_recid)},
            {"$set": update_data},
            return_document=ReturnDocument.AFTER,
            upsert=False,
            )

        if( inserted_data is None ):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de mettre à jour cette affectation (3)")
            return False, " Impossible de mettre à jour cette affectation (3) "



        return True, "L'affectation de l'employé a été correctement mise à jour."

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de mettre à jour cette affectation "


"""
Supprimer une affectation 
"""
def Delete_Affectation_Ressource_Humaine_Poste(diction):
    try:

        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', "rh_id",  "_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', "rh_id",  "_id" ]

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + "  La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " Toutes le information obligatoires n'ont pas été fournies"

        token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                token = diction['token']



        # Recuperation 	du 	recid 	du 	partenaire
        partner_recid = mycommon.get_parnter_recid_from_token(str(token))
        if partner_recid is False:
            mycommon.myprint(str(inspect.stack()[0][3]) + " -  Impossible de récupérer le partner_recid")
            return False, " Les informations d'identification sont invalides"

        local_status, my_partner_data = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
        if (local_status is not True):
            return local_status, my_partner_data

        update_data = {}

        rh_id = ""
        if ("rh_id" in diction.keys()):
            if diction['rh_id']:
                rh_id = diction['rh_id']
        # Verifier que l'employé existe bien
        employee_existe_count = MYSY_GV.dbname['ressource_humaine'].count_documents({'_id':ObjectId(str(rh_id)), 'partner_recid':str(partner_recid),
                                                                                     'valide':'1', 'locked':'0'})

        if( employee_existe_count <= 0 ) :
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Employé invalide ")
            return False, "  Employé invalide "

        if (employee_existe_count > 1):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Employé incohérent. il a plusieurs employés avec le meme id ")
            return False, "  Employé incohérent. il a plusieurs employés avec le meme id "


        # Verifier l'existance de l'affectation
        affectation_existe_count = MYSY_GV.dbname['ressource_humaine_affectation'].count_documents( {'_id': ObjectId(str(diction['_id'])), 'valide': "1",
                                                                                                     "locked":"0", 'partner_owner_recid':str(partner_recid)})

        if( affectation_existe_count != 1 ):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de supprimer cette affectation. Données incohérentes ")
            return False, " Impossible de supprimer cette affectation. Données incohérentes   "


        inserted_data = MYSY_GV.dbname['ressource_humaine_affectation'].delete_one( {'_id': ObjectId(str(diction['_id'])), 'valide': "1", "locked":"0",
                                                                                     'partner_owner_recid':str(partner_recid)},  )

        if( inserted_data is None ):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de supprimer à jour cette affectation (3)")
            return False, " Impossible de supprimer cette affectation (3) "



        return True, "L'affectation de l'employé a été correctement supprimée."

    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 supprimer cette affectation  "


def Get_Given_Affectation_Ressource_Humaine_Poste(diction):
    try:
        field_list_obligatoire = ['token', 'affectation_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, "  La valeur '" + val + "' n'est pas presente dans liste "

        my_token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                my_token = diction['token']

        # Recuperation 	du 	recid 	du 	partenaire
        partner_recid = mycommon.get_parnter_recid_from_token(str(my_token))
        if partner_recid is False:
            mycommon.myprint(str(inspect.stack()[0][3]) + " -  Impossible d'imprimer la fiche detaillée")
            return False, " Les informations d'identification sont invalides"

        local_status, my_partner_data = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
        if (local_status is not True):
            return local_status, my_partner_data

        qry_affectation = {'partner_owner_recid': str(my_partner_data['recid']),
                           '_id': ObjectId(str(diction['affectation_id'])),
                           'valide': '1', 'locked': '0'}

        #print(" ### qry_affectation = ", qry_affectation)

        RetObject = []
        val_tmp = 1

        for retval in MYSY_GV.dbname['ressource_humaine_affectation'].find(qry_affectation):
            user = retval
            user['id'] = str(val_tmp)
            val_tmp = val_tmp + 1

            related_target_collection_id_nom = ""
            related_target_collection_object = ""

            # Si l'affectation a un 'related_target_collection_id', alors cela veut dire qu'il faut aller chercheer
            # la cible de cette affection.
            if ("related_target_collection_id" in retval.keys() and "related_target_collection" in retval.keys()):
                if (retval["related_target_collection_id"] and retval["related_target_collection"]):

                    # Si l'affectation concerne une formation
                    if (retval["related_target_collection"] == "myclass"):
                        affectation_target_data = MYSY_GV.dbname[retval["related_target_collection"]].find_one(
                            {"_id": ObjectId(str(retval["related_target_collection_id"])),
                             'partner_owner_recid': str(partner_recid),
                             'valide': '1', 'locked': "0"})

                        if (affectation_target_data is not None):
                            related_target_collection_id_nom = affectation_target_data["title"]
                            related_target_collection_object = "Formation"

                    elif (retval["related_target_collection"] == "session_formation"):
                        # Si l'affectation concerne une session
                        affectation_target_data = MYSY_GV.dbname[retval["related_target_collection"]].find_one(
                            {"_id": ObjectId(str(retval["related_target_collection_id"])),
                             'partner_owner_recid': str(partner_recid),
                             'valide': '1'})

                        if (affectation_target_data is not None):
                            related_target_collection_id_nom = affectation_target_data["code_session"]
                            related_target_collection_object = "Session de formation"

            user['related_target_collection_id_nom'] = related_target_collection_id_nom
            user['related_target_collection_object'] = related_target_collection_object

            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 l'affectation de l'employé "

"""
Cette API permet de récupérer la liste des 'related_target_collection_object' avec les 'related_target_collection_id_nom'
et de les formater pour une utilisation simple coté front.

les collections cibles sont : 
- les formations et les sessions de formation.

ex :
{
{'related_target_collection':'session_formation', 
 'related_target_collection_id':'64e797fd168e0c57cefe4fd0'
 'related_target_collection_id_nom' : 'ch_Manual_1'
 },
 {'related_target_collection':'myclass', 
 'related_target_collection_id':'64e79630ea7b810a3d835ceb'
 'related_target_collection_id_nom' : 'PRATICIEN EN AROMATHERAPIE INTEGRATIVE'
 },
}

"""
def Get_Related_Target_Collection_Data(diction):
    try:
        field_list_obligatoire = ['token', ]

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + "  La valeur '" + val + "' n'est pas presente dans liste ")
                return False, "  La valeur '" + val + "' n'est pas presente dans liste "

        my_token = ""
        if ("token" in diction.keys()):
            if diction['token']:
                my_token = diction['token']

        # Recuperation 	du 	recid 	du 	partenaire
        partner_recid = mycommon.get_parnter_recid_from_token(str(my_token))
        if partner_recid is False:
            mycommon.myprint(str(inspect.stack()[0][3]) + " -  Impossible d'imprimer la fiche detaillée")
            return False, " Les informations d'identification sont invalides"

        local_status, my_partner_data = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
        if (local_status is not True):
            return local_status, my_partner_data

        RetObject = []

        # Recuperation des données des formations
        for retval in MYSY_GV.dbname['myclass'].find({'partner_owner_recid':str(partner_recid),
                                                      'valide':'1', 'locked':'0'}, {'_id':1, 'title':1}):

            retval_data = {}
            retval_data['related_target_collection'] = "myclass"
            retval_data['related_target_collection_id'] = str(retval['_id'])
            retval_data['related_target_collection_id_nom'] = str(retval['title'])
            RetObject.append(mycommon.JSONEncoder().encode(retval_data))

        # Recuperation des données des sessions
        for retval in MYSY_GV.dbname['session_formation'].find({'partner_owner_recid': str(partner_recid),
                                                      'valide': '1'}, {'_id': 1, 'code_session': 1}):
            retval_data = {}
            retval_data['related_target_collection'] = "session_formation"
            retval_data['related_target_collection_id'] = str(retval['_id'])
            retval_data['related_target_collection_id_nom'] = str(retval['code_session'])
            RetObject.append(mycommon.JSONEncoder().encode(retval_data))

        return True, RetObject

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de récupérer les information des cibles "


"""
Cette Fonction crée ou met à jour le login et passwd d'un employe
"""
def Add_Update_Employee_Login_Pass(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', 'nom', 'email', 'pwd', 'telephone', 'contact_nom', 'contact_prenom', 'contact_tel',
                      'contact_mail', 'ressource_humaine_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',  'email', 'pwd',
                                   'ressource_humaine_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

        mydata = {}

        email = ""
        if ("email" in diction.keys()):
            if diction['email']:
                email = diction['email']

        if (mycommon.isEmailValide(email) is False):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " - L'adresse email " + str(email) + " n'est pas valide")

            return False, " - - L'adresse email " + str(email) + " n'est pas valide  "
        mydata['email'] = email

        pwd = ""
        if ("pwd" in diction.keys()):
            if diction['pwd']:
                pwd = diction['pwd']
        mydata['pwd'] = pwd

        contact_nom = ""
        if ("contact_nom" in diction.keys()):
            if diction['contact_nom']:
                contact_nom = diction['contact_nom']
        mydata['contact_nom'] = contact_nom


        contact_prenom = ""
        if ("contact_prenom" in diction.keys()):
            if diction['contact_prenom']:
                contact_prenom = diction['contact_prenom']
        mydata['contact_prenom'] = contact_prenom

        contact_mail = ""
        if ("contact_mail" in diction.keys()):
            if diction['contact_mail']:
                contact_mail = diction['contact_mail']
        mydata['contact_mail'] = contact_mail

        """
        15/02/2024 - 
        Si c'est un update, c'est seulement le password qu'on modifie.
        """
        is_count_exit = MYSY_GV.dbname['partnair_account'].count_documents({'ressource_humaine_id':str(diction['ressource_humaine_id']),
                                                                     'partner_owner_recid':str(my_partner['recid'])})


        if( is_count_exit > 1 ):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " L'identifiant du compte à modifier est invalide ")

            return False, " L'identifiant du compte à modifier est invalide "

        count_to_update_data = MYSY_GV.dbname['partnair_account'].find_one(
            {'ressource_humaine_id': str(diction['ressource_humaine_id']),
             'partner_owner_recid': str(my_partner['recid'])})



        if (is_count_exit == 0 ):
            # Cas d'une creation d'un compte utilisateur
            mydata['num_nda'] = ''
            mydata['nom'] = str(my_partner['nom'])
            mydata['pack_service'] = str(my_partner['pack_service'])
            mydata['nb_formation'] = str(my_partner['nb_formation'])
            mydata['stripe_account_id'] = str(my_partner['stripe_account_id'])
            mydata['stripe_paymentmethod_id'] = str(my_partner['stripe_paymentmethod_id'])
            mydata['lms_virtualhost_id'] = str(my_partner['lms_virtualhost_id'])
            mydata['recid'] = str(my_partner['recid'])
            mydata['partner_owner_recid'] = str(my_partner['recid'])

            mydata['is_partner_admin_account'] = '0'
            mydata['ispending'] = '0'
            mydata['update_by'] = str(my_partner['_id'])

            """
            14/01/2024 : Update : Chaque enseignant a son propre compte
            utilisateur dans le LMS
            
            if( "lms_username" in my_partner.keys() ):
                mydata['lms_username'] = my_partner['lms_username']
            else:
                mydata['lms_username'] = ""

            if ("mysy_lms_user_id" in my_partner.keys()):
                mydata['mysy_lms_user_id'] = my_partner['mysy_lms_user_id']
            else:
                mydata['mysy_lms_user_id'] = ""
            """
        mydata['date_update'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))


        mydata['active'] = '1'
        mydata['locked'] = '0'


        ressource_humaine_id = ""
        if ("ressource_humaine_id" in diction.keys()):
            if diction['ressource_humaine_id']:
                ressource_humaine_id = diction['ressource_humaine_id']
        mydata['ressource_humaine_id'] = ressource_humaine_id

        """
        # Si le compte existe deja, verifier que l'adresse email qui est stocké (collection : partner_account) correspond
        # au ressource_humaine_id.

        En gros, si l'adresse email existe, sont ressource_humaine_id doit etre = au 'ressource_humaine_id' fourni, si cela 
        veut dire que l'email est appartient à un autre partner
        """
        count_existe_with_wrong_ressource_humaine_id = False
        count_existe_with_correct_ressource_humaine_id = False
        count_account = 0
        for retval in MYSY_GV.dbname['partnair_account'].find({'email': str(email), 'partner_owner_recid':str(my_partner['recid'])}):
            count_account = count_account + 1
            if ("ressource_humaine_id" in retval.keys() and str(retval['ressource_humaine_id']) == str(ressource_humaine_id)):
                count_existe_with_correct_ressource_humaine_id = True
            else:
                count_existe_with_wrong_ressource_humaine_id = True

        if( count_account > 1):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " - L'adresse email " + str(email) + " correspond à plusieurs utilisateurs ("+str(count_account)+") ")

            return False, " - L'adresse email " + str(email) + "  correspond à plusieurs utilisateurs "

        if (count_existe_with_wrong_ressource_humaine_id is True):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " - L'adresse email " + str(email) + " existe déjà et rattaché à un autre partenaire")

            return False, " - L'adresse email " + str(email) + " existe déjà et rattaché à un autre partenaire "



        qry_key =  {'email':str(email), 'partner_owner_recid':str(my_partner['recid'])}
        print(" #### qry key 012 = ", qry_key)

        inserted_id = ""
        result = MYSY_GV.dbname['partnair_account'].find_one_and_update(
            {'email':str(email), 'partner_owner_recid':str(my_partner['recid'])},
            {"$set": mydata},
            upsert=True,
            return_document=ReturnDocument.AFTER
        )
        if (result is None or "_id" not in result.keys()):
            mycommon.myprint(
                " Impossible de créer ou mettre à jour le compte utilisateur pour  " + str(diction['email']))
            return False, " Impossible de créer ou mettre à jour le compte utilisateur "

        """ 
        15/02/2024 :
        Si l'utilisateur a un deja un accès LMS, il faut aussi mettre à jour le mot de passe dans le LMS

        """
        print(" ### result = ", result)
        print(" ### my_partner = ", my_partner)
        if( "mysy_lms_user_id" in result.keys() and len(str(result['mysy_lms_user_id'])) > 1 and 'token' in result.keys()
            and "partner_owner_recid" in result.keys() and str(result['partner_owner_recid']) == str(my_partner['recid'])  ):
            # ce compte a deja un acces LMS, il faut mettre à jour le mot de passe.
            local_data = {}
            local_data['token'] = result['token']
            local_data['new_password'] = result['pwd']
            local_data['lms_user_id'] = result['mysy_lms_user_id']

            local_pwd_status, local_pwd_retval, local_pwd_rowid = mysy_lms.Update_Passwd_MySy_LMS_User(local_data)

            if( local_pwd_status is False ):
                mycommon.myprint(
                    " WARNING : Impossible de mettre à jour le mot de passe dans le LMS pour le user email  " + str(result['email']))

        else:
            mycommon.myprint(" INFO : le user au compte emai  " + str(result['email'])+" n'as pas d'acces LMS, donc aucune mise à jour du PWD LMS à faire" )




        """
        Mettre à jour les données de l'employé en mettant le login
        """
        employee = MYSY_GV.dbname['ressource_humaine'].update_one({'_id':ObjectId(str(ressource_humaine_id)), 'partner_recid':str(my_partner['recid'])},
                                                       {'$set':{'user_login':str(email), 'account_partner_id':str(result['_id']),
                                                                'is_partner_admin_account':'0', 'date_update':str(datetime.now()),
                                                                'update_by' : str(my_partner['_id']) } })

        employee_data = MYSY_GV.dbname['ressource_humaine'].find_one({'_id':ObjectId(str(ressource_humaine_id))})


        #print(" #### le compte : ", result)
        data_for_mail = {}
        if( "nom" in employee_data.keys()):
            data_for_mail['nom'] = employee_data['nom']
        else:
            data_for_mail['nom'] = ""

        if ("prenom" in employee_data.keys()):
            data_for_mail['prenom'] = employee_data['prenom']
        else:
            data_for_mail['prenom'] = ""

        if ("email" in employee_data.keys()):
            data_for_mail['email'] = employee_data['email']
        else:
            data_for_mail['email'] = ""

        data_for_mail['partner_owner_recid'] = employee_data['partner_recid']

        data_for_mail['mysy_url'] = str(MYSY_GV.CLIENT_URL_BASE)
        data_for_mail['login'] = result['email']
        data_for_mail['pwd'] = result['pwd']
        if( str(result['contact_mail']) != "" ):
            data_for_mail['email_bcc'] = str(result['email'])+","+str(result['contact_mail'])
        else:
            data_for_mail['email_bcc'] = str(result['email'])

        #print(" #### data_for_mail = ", data_for_mail)

        email_inscription_mgt.Employee_Credential_Sending_mail(data_for_mail)

        return True, " Les accès ont été créées. Les emails de notification envoyés"

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible d'ajouter la ressource "


"""
Cette fonction permet de créer un contrat de travail
pour une ressource humaine
Sur le contrat on a : 
- type_employe : employe, stagiaire, indépendant, contractuel
- type_contrat : CDI, CDD, etc
- Cout (purchase_prices_id) ou saisie libre
- date_debut
- date_fin
- groupe_prix_achat_id
"""
def Add_Employee_Contrat(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', 'rh_id', 'date_debut', 'date_fin', 'type_contrat',
                      'type_employe', 'cout', 'groupe_prix_achat_id', 'quantite', 'comment', 'periodicite']

        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', 'rh_id', 'date_debut', 'date_fin', 'type_contrat', 'type_employe']

        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 la ressource_humaine est valide
        is_rh_id_valide = MYSY_GV.dbname['ressource_humaine'].count_documents({'_id':ObjectId(str(diction['rh_id'])),
                                                                               'valide':'1',
                                                                               'locked':'0',
                                                                               'partner_recid':str(my_partner['recid'])})

        if( is_rh_id_valide != 1):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " L'identifiant de la ressource humaine est invalide ")
            return False, " L'identifiant de la ressource humaine est invalide "


        # Verifier que 'groupe_prix_achat_id' existe si dans diction
        groupe_prix_achat_id = ""
        if ("groupe_prix_achat_id" in diction.keys()):
            if diction['groupe_prix_achat_id']:
                groupe_prix_achat_id = diction['groupe_prix_achat_id']

                if (MYSY_GV.dbname['purchase_prices'].count_documents(
                        {'_id': ObjectId(str(diction['groupe_prix_achat_id'])),
                         'valide': '1',
                         'locked': '0',
                         'partner_owner_recid': str(my_partner['recid'])}) != 1):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - L'identifiant du groupe d'achat est invalide ")

                    return False, " L'identifiant du groupe d'achat est invalide  "
                price_grp_data = MYSY_GV.dbname['purchase_prices'].find_one(
                    {'_id': ObjectId(str(diction['groupe_prix_achat_id'])),
                     'valide': '1',
                     'locked': '0',
                     'partner_owner_recid': str(my_partner['recid'])})

                """
                Verifier que les dates du groupe de prix sont valident pendant tout le contrat
                """
                if (datetime.strptime(str(price_grp_data['date_debut'])[0:10], '%d/%m/%Y') > datetime.strptime(
                        str(diction['date_debut'])[0:10], '%d/%m/%Y')):
                    mycommon.myprint(str(inspect.stack()[0][3]) + " La date de début du contrat " + str(
                        datetime.strptime(str(diction['date_debut'])[0:10],
                                          '%d/%m/%Y')) + " est antérieure à la date de début de validité du groupe de prix d'achat " + str(
                        datetime.strptime(str(price_grp_data['date_debut'])[0:10], '%d/%m/%Y')) + " ")
                    return False, " La date de début du contrat " + str(
                        datetime.strptime(str(diction['date_debut'])[0:10],
                                          '%d/%m/%Y')) + " est antérieure à la date de début de validité du groupe de prix d'achat " + str(
                        datetime.strptime(str(price_grp_data['date_debut'])[0:10], '%d/%m/%Y')) + " "

                if (datetime.strptime(str(price_grp_data['date_fin'])[0:10], '%d/%m/%Y') < datetime.strptime(
                        str(diction['date_fin'])[0:10], '%d/%m/%Y')):
                    mycommon.myprint(str(inspect.stack()[0][3]) + " La date de fin du contrat " + str(
                        datetime.strptime(str(diction['date_fin'])[0:10],
                                          '%d/%m/%Y')) + " est postérieure à la date de début de validité du groupe de prix d'achat " + str(
                        datetime.strptime(str(price_grp_data['date_fin'])[0:10], '%d/%m/%Y')) + " ")
                    return False, " La date de début du contrat " + str(
                        datetime.strptime(str(diction['date_debut'])[0:10],
                                          '%d/%m/%Y')) + " est antérieure à la date de début de validité du groupe de prix d'achat " + str(
                        datetime.strptime(str(price_grp_data['date_debut'])[0:10], '%d/%m/%Y')) + " "



            else:
                """
                Si groupe_prix_achat_id est vide, alors il me faut obligatoirement 
                le prix et la periodicité 
                                """
                if ("cout" not in diction.keys() or str(diction['cout']).strip() == ""):
                    mycommon.myprint(str(
                        inspect.stack()[0][3]) + " Le prix est obligatoire ")
                    return False, " Le prix est obligatoire"

                if ("periodicite" not in diction.keys() or str(diction['periodicite']).strip() == ""):
                    mycommon.myprint(str(
                        inspect.stack()[0][3]) + " La périodicite est obligatoire ")
                    return False, " La périodicite est obligatoire"



        # S'il ya des date, verifier la validité des dates
        date_debut = ""
        if ("date_debut" in diction.keys() and diction['date_debut']):
            date_debut = str(diction['date_debut'])
        local_status = mycommon.CheckisDate(date_debut)
        if (local_status is False):
            mycommon.myprint(str(
                inspect.stack()[0][3]) + " La date de debut  n'est pas au format jj/mm/aaaa.")
            return False, " La date de debut  n'est pas au format jj/mm/aaaa."

        date_fin = ""
        if ("date_fin" in diction.keys() and diction['date_fin']):
            date_fin = str(diction['date_fin'])
        local_status = mycommon.CheckisDate(date_fin)
        if (local_status is False):
            mycommon.myprint(str(
                inspect.stack()[0][3]) + " La date de fin  n'est pas au format jj/mm/aaaa.")
            return False, " La date de fin  n'est pas au format jj/mm/aaaa. "

        # verifier la cohérence des dates
        if (datetime.strptime(str(date_debut), '%d/%m/%Y') >= datetime.strptime(str(date_fin), '%d/%m/%Y')):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " La date de fin  " + str(
                    date_fin) + " doit être postérieure à la date de début  " + str(
                    diction['date_debut']) + " ")
            return False, " La date de fin  " + str(
                diction['date_fin']) + " doit être postérieure à la date de début  " + str(
                diction['date_debut']) + " "


        """ 
        Verifier que l'employé n'a pas un contrat actif qui se chevauche car à un instant T
        une ressources humaine ne peut avoir qu'un seul contrat valdie
        """
        qry = {'rh_id': str(diction['rh_id']),
                                                                               'valide': '1',
                                                                               'locked': '0',
                                                                               'partner_owner_recid': str( my_partner['recid'])}


        for retVal in MYSY_GV.dbname['ressource_humaine_contrat'].find({'rh_id': str(diction['rh_id']),
                                                                               'valide': '1',
                                                                               'locked': '0',
                                                                               'partner_owner_recid': str( my_partner['recid'])}) :
            New_retVal_start_date = ""
            New_retVal_end_date = ""

            print(" ### debut comparaison date retVal = ", retVal)

            if("date_debut" in retVal.keys() ):
                New_retVal_start_date = datetime.strptime(str(retVal['date_debut']), '%d/%m/%Y').strftime("%d/%m/%Y")

            if ("date_fin" in retVal.keys()):
                New_retVal_end_date = datetime.strptime(str(retVal['date_fin']), '%d/%m/%Y').strftime("%d/%m/%Y")
            else:
                New_retVal_end_date = datetime.strptime(str("31/12/2999"), '%d/%m/%Y').strftime("%d/%m/%Y")

            if (datetime.strptime(str(New_retVal_start_date), '%d/%m/%Y') <= datetime.strptime(str(diction['date_debut']), '%d/%m/%Y') and  datetime.strptime(str(New_retVal_end_date), '%d/%m/%Y') >= datetime.strptime(str(diction['date_debut']), '%d/%m/%Y')):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " La date de debut du contrat " + str(diction['date_debut']) + " chevauche un autre contrat ")
                return False, "  La date de debut du contrat  " + str(diction['date_debut']) + " chevauche un autre contrat "


            if (datetime.strptime(str(New_retVal_start_date), '%d/%m/%Y') <= datetime.strptime(str(diction['date_fin']), '%d/%m/%Y') and   datetime.strptime(str(New_retVal_end_date), '%d/%m/%Y') >= datetime.strptime(str(diction['date_fin']), '%d/%m/%Y')):
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " La date de fin " + str(diction['date_debut']) + " chevauche un autre contrat ")
                return False, " La date de fin de contrat" + str(diction['date_debut']) + " chevauche un autre contrat"

        # Verifier que le cout est un decimal
        if( "cout" in diction.keys() and diction['cout']) :
            local_status, local_retval = mycommon.IsFloat(diction['cout'])
            if( local_status is False ):
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + " Le cout n'est pas valide ")
                return False, " Le cout n'est pas valide "


        # S'il y a une quantité, verifier que le qté est un entie
        if ("quantite" in diction.keys() and diction['quantite']):
            local_status, local_retval = mycommon.IsFloat(diction['quantite'])
            if (local_status is False):
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + " La quantite n'est pas valide ")
                return False, "  La quantite n'est pas valide  "

        # S'il y a un commentaire > 255 caractères
        if ("comment" in diction.keys() and diction['comment']):
            if (len(str(diction['comment'])) > 255):
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + " Le commentaire du contrat fait plus de 255 caractères ")
                return False, " Le commentaire du contrat fait plus de 255 caractères "

        new_data = diction
        new_data['valide'] = "1"
        new_data['locked'] = "0"
        new_data['date_update'] = str(datetime.now())
        new_data['update_by'] = str(my_partner['_id'])
        new_data['partner_owner_recid'] = str(my_partner['recid'])

        del new_data['token']

        inserted_id = MYSY_GV.dbname['ressource_humaine_contrat'].insert_one(new_data).inserted_id
        if (not inserted_id):
            mycommon.myprint(
                " Impossible de créer le contrat (1)  ")
            return False, " Impossible de créer le contrat (1)  "


        return True, " Le contrat été correctement créé "


    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 contrat "


"""
Mise à jour d'un contrat d'une ressource humaine 
"""
def Update_Employee_Contrat(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', '_id', 'rh_id', 'date_debut', 'date_fin', 'type_contrat',
                      'type_employe', 'cout', 'groupe_prix_achat_id', 'quantite', 'comment', 'periodicite']

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'est pas autorisé")
                return False, " Les informations fournies sont incorrectes"

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', '_id', 'rh_id', 'date_debut', 'date_fin', 'type_contrat', 'type_employe']

        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


        if( "periodicite" in diction.keys() and diction['periodicite']):
            if( diction['periodicite'] not in MYSY_GV.PURCHASE_PRICE_PERIODICITY):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " La périodicité est invalide ")
                return False, "  La périodicité est invalide  "

        # Verifier que le contrat existe et est valide
        is_contrat_valide = MYSY_GV.dbname['ressource_humaine_contrat'].count_documents({'_id':ObjectId(str(diction['_id'])),
                                                                                         'valide': '1',
                                                                               'locked': '0',
                                                                               'partner_owner_recid': str(
                                                                                   my_partner['recid'])})
        if( is_contrat_valide != 1):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " L'identifiant du contrat est invalide ")
            return False, " L'identifiant du contrat est invalide "



        # Verifier que la ressource_humaine est valide
        is_rh_id_valide = MYSY_GV.dbname['ressource_humaine'].count_documents({'_id': ObjectId(str(diction['rh_id'])),
                                                                               'valide': '1',
                                                                               'locked': '0',
                                                                               'partner_recid': str(
                                                                                   my_partner['recid'])})

        if (is_rh_id_valide != 1):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " L'identifiant de la ressource humaine est invalide ")
            return False, " L'identifiant de la ressource humaine est invalide "

        # S'il ya des date, verifier la validité des dates
        date_debut = ""
        if ("date_debut" in diction.keys() and diction['date_debut']):
            date_debut = str(diction['date_debut'])
        local_status = mycommon.CheckisDate(date_debut)
        if (local_status is False):
            mycommon.myprint(str(
                inspect.stack()[0][3]) + " La date de debut  n'est pas au format jj/mm/aaaa.")
            return False, " La date de debut  n'est pas au format jj/mm/aaaa."

        date_fin = ""
        if ("date_fin" in diction.keys() and diction['date_fin']):
            date_fin = str(diction['date_fin'])
        local_status = mycommon.CheckisDate(date_fin)
        if (local_status is False):
            mycommon.myprint(str(
                inspect.stack()[0][3]) + " La date de fin  n'est pas au format jj/mm/aaaa.")
            return False, " La date de fin  n'est pas au format jj/mm/aaaa. "



        # verifier la cohérence des dates
        if (datetime.strptime(str(date_debut), '%d/%m/%Y') >= datetime.strptime(str(date_fin), '%d/%m/%Y')):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " La date de fin  " + str(
                    date_fin) + " doit être postérieure à la date de début  " + str(
                    diction['date_debut']) + " ")
            return False, " La date de fin  " + str(
                diction['date_fin']) + " doit être postérieure à la date de début  " + str(
                diction['date_debut']) + " "

        """ 
        Verifier que l'employé n'a pas un contrat actif qui se chevauche car à un instant T
        une ressources humaine ne peut avoir qu'un seul contrat valdie
        /!\ : faire attention à exclure present contrat
        """
        for retVal in MYSY_GV.dbname['ressource_humaine_contrat'].find({'rh_id': str(diction['rh_id']),
                                                                        '_id': {'$ne': ObjectId(str(diction['_id'])) },
                                                                        'valide': '1',
                                                                        'locked': '0',
                                                                        'partner_owner_recid': str(my_partner['recid'])}):

            New_retVal_start_date = ""
            New_retVal_end_date = ""

            if ("date_debut" in retVal.keys()):
                New_retVal_start_date = datetime.strptime(str(retVal['date_debut']), '%d/%m/%Y').strftime("%d/%m/%Y")

            if ("date_fin" in retVal.keys()):
                New_retVal_end_date = datetime.strptime(str(retVal['date_fin']), '%d/%m/%Y').strftime("%d/%m/%Y")
            else:
                New_retVal_end_date = datetime.strptime(str("31/12/2999"), '%d/%m/%Y').strftime("%d/%m/%Y")

            if (datetime.strptime(str(New_retVal_start_date), '%d/%m/%Y') <= datetime.strptime(
                    str(diction['date_debut']), '%d/%m/%Y') and datetime.strptime(str(New_retVal_end_date),
                                                                                  '%d/%m/%Y') >= datetime.strptime(
                    str(diction['date_debut']), '%d/%m/%Y')):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " La date de debut du contrat " + str(
                        diction['date_debut']) + " chevauche un autre contrat ")
                return False, "  La date de debut du contrat  " + str(
                    diction['date_debut']) + " chevauche un autre contrat "

            if (datetime.strptime(str(New_retVal_start_date), '%d/%m/%Y') <= datetime.strptime(str(diction['date_fin']),
                                                                                               '%d/%m/%Y') and datetime.strptime(
                    str(New_retVal_end_date), '%d/%m/%Y') >= datetime.strptime(str(diction['date_fin']), '%d/%m/%Y')):
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " La date de fin " + str(diction['date_debut']) + " chevauche un autre contrat ")
                return False, " La date de fin de contrat" + str(diction['date_debut']) + " chevauche un autre contrat"

        """ 
        # Verifier que 'groupe_prix_achat_id' existe si dans diction
        01/01/2024 : /!\ Important :
        Si le contrat est rattaché à un groupe de prix, alors verifier que 
        les dates de début et de fin du contrat ne sont pas en contration avec les dates de validé
        du groupe de prix.
        """
        groupe_prix_achat_id = ""
        if ("groupe_prix_achat_id" in diction.keys()):
            if diction['groupe_prix_achat_id']:
                groupe_prix_achat_id = diction['groupe_prix_achat_id']

                if (MYSY_GV.dbname['purchase_prices'].count_documents(
                        {'_id': ObjectId(str(diction['groupe_prix_achat_id'])),
                         'valide': '1',
                         'locked': '0',
                         'partner_owner_recid': str(my_partner['recid'])}) != 1):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - L'identifiant du groupe d'achat est invalide ")

                    return False, " L'identifiant du groupe d'achat est invalide  "

                price_grp_data = MYSY_GV.dbname['purchase_prices'].find_one(
                    {'_id': ObjectId(str(diction['groupe_prix_achat_id'])),
                     'valide': '1',
                     'locked': '0',
                     'partner_owner_recid': str(my_partner['recid'])})

                if (datetime.strptime(str(price_grp_data['date_debut'])[0:10], '%d/%m/%Y') > datetime.strptime(str(diction['date_debut'])[0:10], '%d/%m/%Y')):
                    mycommon.myprint(str(inspect.stack()[0][3]) + " La date de début du contrat "+str(datetime.strptime(str(diction['date_debut'])[0:10], '%d/%m/%Y')) +" est antérieure à la date de début de validité du groupe de prix d'achat "+str(datetime.strptime(str(price_grp_data['date_debut'])[0:10], '%d/%m/%Y')) +" ")
                    return False, " La date de début du contrat "+str(datetime.strptime(str(diction['date_debut'])[0:10], '%d/%m/%Y')) +" est antérieure à la date de début de validité du groupe de prix d'achat "+str(datetime.strptime(str(price_grp_data['date_debut'])[0:10], '%d/%m/%Y')) +" "

                if (datetime.strptime(str(price_grp_data['date_fin'])[0:10], '%d/%m/%Y') < datetime.strptime(str(diction['date_fin'])[0:10], '%d/%m/%Y')):
                    mycommon.myprint(str(inspect.stack()[0][3]) + " La date de fin du contrat "+str(datetime.strptime(str(diction['date_fin'])[0:10], '%d/%m/%Y')) +" est postérieure à la date de début de validité du groupe de prix d'achat "+str(datetime.strptime(str(price_grp_data['date_fin'])[0:10], '%d/%m/%Y')) +" ")
                    return False, " La date de début du contrat "+str(datetime.strptime(str(diction['date_debut'])[0:10], '%d/%m/%Y')) +" est antérieure à la date de début de validité du groupe de prix d'achat "+str(datetime.strptime(str(price_grp_data['date_debut'])[0:10], '%d/%m/%Y')) +" "



        # Verifier que le cout est un decimal
        if ("cout" in diction.keys() and diction['cout']):
            local_status, local_retval = mycommon.IsFloat(diction['cout'])
            if (local_status is False):
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + " Le cout n'est pas valide ")
                return False, " Le cout n'est pas valide "

        # S'il y a une quantité, verifier que le qté est un entie
        if ("quantite" in diction.keys() and diction['quantite']):
            local_status, local_retval = mycommon.IsFloat(diction['quantite'])
            if (local_status is False):
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + " La quantite n'est pas valide ")
                return False, "  La quantite n'est pas valide  "

        # S'il y a un commentaire > 255 caractères
        if ("comment" in diction.keys() and diction['comment']):
            if (len(str(diction['comment'])) > 255 ):
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + " Le commentaire du contrat fait plus de 255 caractères ")
                return False, " Le commentaire du contrat fait plus de 255 caractères "

        local_id = diction['_id']
        new_data = diction
        del new_data['token']
        del new_data['_id']


        new_data['date_update'] = str(datetime.now())
        new_data['update_by'] = str(my_partner['recid'])




        update = MYSY_GV.dbname['ressource_humaine_contrat'].update_one({'_id': ObjectId(str(local_id)),
                                                               'partner_owner_recid': str(my_partner['recid']),
                                                               'valide': '1',
                                                               'locked': '0'},
                                                              {'$set': new_data}
                                                              )



        return True, " Le contrat été correctement mis à jour "


    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de mettre à jour le contrat "


"""
Suppression du contrat d'un employé
"""
def Delete_Employee_Contrat(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', '_id']

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'est pas autorisé")
                return False, " Les informations fournies sont incorrectes"

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', '_id']

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans 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 le contrat existe et est valide
        is_contrat_valide = MYSY_GV.dbname['ressource_humaine_contrat'].count_documents(
            {'_id': ObjectId(str(diction['_id'])),
             'valide': '1',
             'locked': '0',
             'partner_owner_recid': str(
                 my_partner['recid'])})
        if (is_contrat_valide != 1):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " L'identifiant du contrat est invalide ")
            return False, " L'identifiant du contrat est invalide "

        delete_retval = MYSY_GV.dbname['ressource_humaine_contrat'].delete_one(
            {'_id': ObjectId(str(diction['_id'])),
             'valide': '1',
             'locked': '0',
             'partner_owner_recid': str(my_partner['recid'])})


        return True, " Le contrat été correctement supprimé "


    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de supprimer le contrat "


"""
Recuperer les données d'un contrat donnée
"""

def Get_Given_Employee_Contrat(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', '_id']

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'est pas autorisé")
                return False, " Les informations fournies sont incorrectes"

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', '_id']

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans 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 le contrat existe et est valide
        is_contrat_valide = MYSY_GV.dbname['ressource_humaine_contrat'].count_documents(
            {'_id': ObjectId(str(diction['_id'])),
             'valide': '1',
             'locked': '0',
             'partner_owner_recid': str(
                 my_partner['recid'])})
        if (is_contrat_valide != 1):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " L'identifiant du contrat est invalide ")
            return False, " L'identifiant du contrat est invalide "

        RetObject = []
        val_tmp = 1

        for retval in MYSY_GV.dbname['ressource_humaine_contrat'].find({'_id': ObjectId(str(diction['_id'])),
                                                             'valide': '1',
                                                             'locked': '0',
                                                             'partner_owner_recid': str(
                                                                 my_partner['recid'])}):
            user = retval
            user['id'] = str(val_tmp)
            val_tmp = val_tmp + 1

            # Recuperation du groupe de prix d'achat si il existe.
            groupe_prix_achat_code = ""
            if ("groupe_prix_achat_id" in retval.keys() and retval['groupe_prix_achat_id']):
                groupe_prix_achat_id_data = MYSY_GV.dbname['purchase_prices'].find_one(
                    {'_id': ObjectId(str(diction['groupe_prix_achat_id'])),
                     'valide': '1',
                     'locked': '0',
                     'partner_owner_recid': str(my_partner['recid'])})
                if (groupe_prix_achat_id_data and "code_groupe_prix" in groupe_prix_achat_id_data.keys()):
                    groupe_prix_achat_code = groupe_prix_achat_id_data['code_groupe_prix']

            user['groupe_prix_achat_code'] = groupe_prix_achat_code

            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 recuperer les données du contrat "


"""
Recupérer la liste des contrats d'un employee
"""
def Get_List_Employee_Contrat(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', 'rh_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', 'rh_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

        # Verifier que la ressource_humaine est valide
        is_rh_id_valide = MYSY_GV.dbname['ressource_humaine'].count_documents(
            {'_id': ObjectId(str(diction['rh_id'])),
             'valide': '1',
             'locked': '0',
             'partner_recid': str(
                 my_partner['recid'])})

        if (is_rh_id_valide != 1):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " L'identifiant de la ressource humaine est invalide ")
            return False, " L'identifiant de la ressource humaine est invalide "


        RetObject = []
        val_tmp = 1
        for retval in MYSY_GV.dbname['ressource_humaine_contrat'].find({'rh_id':str(diction['rh_id']),
            'valide': '1','locked': '0', 'partner_owner_recid': str(my_partner['recid'])}):
            user = retval
            user['id'] = str(val_tmp)
            val_tmp = val_tmp + 1
            RetObject.append(mycommon.JSONEncoder().encode(user))


        return True, RetObject


    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de recuperer la liste des contrat "


"""
Cett fonction permet de recuperer les types de contrat
"""
def Get_Type_Contrat_List(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token',]

        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list  and val.startswith('my_') is False:
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + "  Le champ  '" + val + "' n'existe pas")
                return False, " Les informations fournies sont incorrectes",

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token',]
        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans 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

        """
                Clés de mise à jour 
                """
        data_cle = {}
        data_cle['partner_owner_recid'] = "default"
        data_cle['valide'] = "1"
        data_cle['locked'] = "0"

        #print(" ### Get_Partner_List_Partner_Client data_cle = ", data_cle)
        RetObject = []
        val_tmp = 1

        for retval in MYSY_GV.dbname['contrat_type'].find(data_cle):
            user = retval
            user['id'] = str(val_tmp)
            val_tmp = val_tmp + 1
            RetObject.append(mycommon.JSONEncoder().encode(user))

        return True, RetObject

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de récupérer la liste des types de contrat"



"""
Cette fonction créé ou met à jour un compte enseignant dans le LMS
"""
def HR_Create_LMS_Trainer_Account(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
               Verification des input acceptés
               """
        field_list = ['token', 'rh_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',  'rh_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


        # Verifier la valididé de l'employé enseignant
        is_rh_valide = MYSY_GV.dbname['ressource_humaine'].count_documents({'_id':ObjectId(str(diction['rh_id'])),
                                                                                           'valide':'1',
                                                                            'locked':'0',
                                                                            'partner_recid':str(my_partner['recid']),
                                                                            'is_partner_admin_account':'0'})


        if( is_rh_valide != 1):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " L'identifiant de l'enseignant est invalide ")
            return False, " L'identifiant de l'enseignant est invalide ",

        is_rh_data = MYSY_GV.dbname['ressource_humaine'].find_one({'_id':ObjectId(str(diction['rh_id'])),
                                                                                           'valide':'1',
                                                                            'locked':'0',
                                                                            'partner_recid':str(my_partner['recid']),
                                                                            'is_partner_admin_account':'0'})

        if( "account_partner_id" not in is_rh_data.keys()  ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " Cet enseignant n'a pas de compte utilisateur ")
            return False, " Cet enseignant n'a pas de compte utilisateur ",



        # Recuperation des info qui sont sur compte utilisation (partner_account liée eu RH account)
        rh_partner_account = MYSY_GV.dbname['partnair_account'].find_one({'_id':ObjectId(str(is_rh_data['account_partner_id'])),
                                                                          'active':'1',
                                                                          'recid':str(my_partner['recid'])})

        if( rh_partner_account is None ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " Le compte utilisateur associé à l'enseignant est invalide ")
            return False, " Le compte utilisateur associé à l'enseignant est invalide ",


        mew_diction = {}
        mew_diction['token'] = diction['token']
        mew_diction['rh_partner_account_id'] = str(rh_partner_account['_id'])
        mew_diction['lastname'] = is_rh_data['nom']
        mew_diction['firstname'] = is_rh_data['prenom']
        mew_diction['email'] = is_rh_data['email']
        mew_diction['password'] = rh_partner_account['pwd']
        mew_diction['locked'] = "0"
        mew_diction['official_code'] = ""

        split_mail_tab = str(is_rh_data['email']).split('@')
        local_status, username = mycommon.RemoveAllNonAlphaNumeric(split_mail_tab[0])
        if( local_status is False ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " Impossible de créer le 'username' de l'enseignant dans le LMS ")
            return False, " Impossible de créer le 'username' de l'enseignant dans le LMS "

        mew_diction['username'] = username


        local_status, local_retval, local_retval2 = mysy_lms.Create_MySy_LMS_Enseignant_Account(mew_diction)
        if(local_status is False ):
            return local_status, local_retval

        new_lms_user_id = local_retval2

        print(" # le compte enseignant a été créé dans le lms avec le new_lms_user_id = ", new_lms_user_id)

        """ 
        ### Mettre à jour le compte enseignant avec les data : 
        new_lms_user_id, 
        lms_username
        lms_theme_name
        lms_virtualhost_url
        lms_virtualhost_id
        """
        qry =  {
                                                          'mysy_lms_user_id':str(new_lms_user_id),
                                                          'lms_username':str(username),
                                                          'lms_theme_name':str(my_partner['lms_theme_name']),
                                                          'lms_virtualhost_url': str(my_partner['lms_virtualhost_url']),
                                                          'lms_virtualhost_id': str(my_partner['lms_virtualhost_id']),
                                                      }

        qry_key = {'_id':ObjectId(str(is_rh_data['account_partner_id'])),
                                                                          'active':'1',
                                                                          'recid':str(my_partner['recid'])}

        print(" #### qry_key update partnair_account  = ", qry_key)

        print(" #### qry update partnair_account  = ", qry)
        result_update = MYSY_GV.dbname['partnair_account'].update_one({'_id':ObjectId(str(is_rh_data['account_partner_id'])),
                                                                          'active':'1',
                                                                          'recid':str(my_partner['recid'])},
                                                      {'$set':
                                                          {
                                                          'mysy_lms_user_id':str(new_lms_user_id),
                                                          'lms_username':str(username),
                                                          'lms_theme_name':str(my_partner['lms_theme_name']),
                                                          'lms_virtualhost_url': str(my_partner['lms_virtualhost_url']),
                                                          'lms_virtualhost_id': str(my_partner['lms_virtualhost_id']),
                                                      }
                                                      })


        if( result_update is None or result_update.modified_count <= 0 ) :
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " Impossible de mettre à jour le 'partnair_account' avec les données du LMS ")
            return False, "  Impossible de mettre à jour le 'partnair_account' avec les données du LMS  "
        """
        A présent les acces au LMS sont crées, 
        on va envoyer un email de notification à la personne
        """
        data_for_mail = {}
        data_for_mail['nom'] = is_rh_data['nom']
        data_for_mail['prenom'] =  is_rh_data['prenom']
        data_for_mail['email'] = is_rh_data['email']
        data_for_mail['mysy_url'] = str(MYSY_GV.CLIENT_URL_BASE)

        data_for_mail['partner_owner_recid'] = str(my_partner['recid'])


        email_inscription_mgt.Employee_Acces_LMS_Sending_mail(data_for_mail)

        return True, " Les accès ont été créée dans le LMS. Un email de notification envoyé à l'utilisateur"

    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 les acces LMS "


"""
Cette fonction verrouile / desactive le compte utilisateur 
d'un employé
"""
def Lock_partner_account_From_Rh_Id(diction):
    try:

        field_list = ['token', 'rh_id', ]
        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list and val.startswith('my_') is False:
                mycommon.myprint(str(inspect.stack()[0][
                                         3]) + " -  Le champ  '" + val + "' n'est pas autorisé, Creation partenaire annulée")
                return False, "de récupérer la liste des stagiaires . Toutes les informations fournies ne sont pas valables"

        """
        Verification de la liste des champs obligatoires
        """
        field_list_obligatoire = ['token', 'rh_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, "Toutes les informations necessaires n'ont pas été fournies"

        # Recuperation du recid du partner
        local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
        if (local_status is not True):
            return local_status, my_partner

        # Verifier que le compte existe
        is_rh_valide = MYSY_GV.dbname['ressource_humaine'].count_documents(
            {'_id': ObjectId(str(diction['rh_id'])),
             'partner_recid': my_partner['recid']})

        if (is_rh_valide != 1):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " L'identifiant du compte est invalide ")
            return False, " L'identifiant du compte est invalide "

        is_rh_valide_data = MYSY_GV.dbname['ressource_humaine'].find_one(
            {'_id': ObjectId(str(diction['rh_id'])),
             'partner_recid': my_partner['recid']})


        if( "account_partner_id" not in is_rh_valide_data.keys() or is_rh_valide_data['account_partner_id'] == ""):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " Cet employé ne dispose pas d'un compte utilisateur ")
            return False, " Cet employé ne dispose pas d'un compte utilisateur  "

        new_data = {}
        new_data['token'] = str(diction['token'])
        new_data['partner_id'] = str(is_rh_valide_data['account_partner_id'])

        local_status, local_retval = partners.Lock_partner_account(new_data)

        return local_status, local_retval


    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
        return False, "Impossible de supprimer le compte utilisateur"


"""
Cette fonction Reactive le le compte utilisateur 
d'un employé
"""
def Unlock_partner_account_From_Rh_Id(diction):
    try:

        field_list = ['token', 'rh_id', ]
        incom_keys = diction.keys()
        for val in incom_keys:
            if val not in field_list and val.startswith('my_') is False:
                mycommon.myprint(str(inspect.stack()[0][
                                         3]) + " -  Le champ  '" + val + "' n'est pas autorisé, Creation partenaire annulée")
                return False, "de récupérer la liste des stagiaires . Toutes les informations fournies ne sont pas valables"

        """
        Verification de la liste des champs obligatoires
        """
        field_list_obligatoire = ['token', 'rh_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, "Toutes les informations necessaires n'ont pas été fournies"

        # Recuperation du recid du partner
        local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
        if (local_status is not True):
            return local_status, my_partner

        # Verifier que le compte existe
        is_rh_valide = MYSY_GV.dbname['ressource_humaine'].count_documents(
            {'_id': ObjectId(str(diction['rh_id'])),
             'partner_recid': my_partner['recid']})

        if (is_rh_valide != 1):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " L'identifiant du compte est invalide ")
            return False, " L'identifiant du compte est invalide "

        is_rh_valide_data = MYSY_GV.dbname['ressource_humaine'].find_one(
            {'_id': ObjectId(str(diction['rh_id'])),
             'partner_recid': my_partner['recid']})


        if( "account_partner_id" not in is_rh_valide_data.keys() or is_rh_valide_data['account_partner_id'] == ""):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " Cet employé ne dispose pas d'un compte utilisateur ")
            return False, " Cet employé ne dispose pas d'un compte utilisateur  "

        new_data = {}
        new_data['token'] = str(diction['token'])
        new_data['partner_id'] = str(is_rh_valide_data['account_partner_id'])

        local_status, local_retval = partners.UnLock_partner_account(new_data)

        return local_status, local_retval


    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
        return False, "Impossible de réactiver le compte utilisateur"



"""
Fonction qui permet d'ajouter ou mettre à jour une competence d'un employe
"""
def Add_Update_RH_Competence(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', 'competence_id', 'competence', 'niveau', 'rh_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', 'competence_id', 'competence', 'niveau',  'rh_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


        if (len(str(diction['competence_id']).strip()) > 0):
            # Verifier si l'id de la compétence existe
            is_competence_exist = MYSY_GV.dbname['ressource_humaine'].count_documents({'_id': ObjectId(str(diction['rh_id'])),
                                                                       'partner_recid': str(
                                                                           my_partner['recid']),
                                                                       'valide': '1',
                                                                       'locked': '0',
                                                                        'list_competence._id' : str(diction['competence_id'])})

            if (is_competence_exist <= 0):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " L'identifiant de la compétence est invalide ")
                return False, " L'identifiant de la compétence est invalide "

            # L'eventement existe est valide, on autorise la mise à jour

            update = MYSY_GV.dbname['ressource_humaine'].update_one({'_id': ObjectId(str(diction['rh_id'])),
                                                                       'partner_recid': str(
                                                                           my_partner['recid']),
                                                                       'valide': '1',
                                                                       'locked': '0',
                                                                        'list_competence._id' : str(diction['competence_id'])},
                                                                    {'$set':
                                                                        {
                                                                        'list_competence.$[xxx].competence': str(diction['competence']),
                                                                        'list_competence.$[xxx].niveau': str(diction['niveau']),
                                                                        'list_competence.$[xxx].date_update': str(datetime.now()),
                                                                        'list_competence.$[xxx].update_by': str(my_partner['_id']),
                                                                        }
                                                                    },
                                                                    upsert=False,
                                                                    array_filters=[
                                                                        {"xxx._id": str(diction['competence_id'])}
                                                                    ]

                                                                )

            return True, " La compétence a été mise à jour"



        else:
            # Il s'agit de la creation d'une competence
            new_data = {}
            new_data['date_update'] = str(datetime.now())
            new_data['valide'] = "1"
            new_data['update_by'] = str(my_partner['_id'])
            new_data['locked'] = "0"
            new_data['competence'] = str(diction['competence'])
            new_data['niveau'] = str(diction['niveau'])

            new_competence_id = secrets.token_hex(5)
            new_data['_id'] = new_competence_id


            update = MYSY_GV.dbname['ressource_humaine'].update_one({'_id': ObjectId(str(diction['rh_id'])),
                                                                     'partner_recid': str(
                                                                         my_partner['recid']),
                                                                     'valide': '1',
                                                                     'locked': '0',
                                                                     },

                                                                    {
                                                                '$push': {
                                                                    "list_competence": {
                                                                        '$each': [new_data]
                                                                    }
                                                                }
                                                                },

                                                                    )


            return True, " La compétence a été ajoutée"

    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 ou mettre à jour la compétence "


"""
Cette fonction supprimer une compétence d'un employé
"""
def Delete_RH_Competence(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', 'competence_id', 'rh_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', 'competence_id', 'rh_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


        if (len(str(diction['competence_id']).strip()) > 0):
            # Verifier si l'id de la compétence existe
            is_competence_exist = MYSY_GV.dbname['ressource_humaine'].count_documents({'_id': ObjectId(str(diction['rh_id'])),
                                                                       'partner_recid': str(
                                                                           my_partner['recid']),
                                                                       'valide': '1',
                                                                       'locked': '0',
                                                                        'list_competence._id' : str(diction['competence_id'])})

            if (is_competence_exist <= 0):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " L'identifiant de la compétence est invalide ")
                return False, " L'identifiant de la compétence est invalide "




        delete = MYSY_GV.dbname['ressource_humaine'].update_one({'_id': ObjectId(str(diction['rh_id'])),
                                                                     'partner_recid': str(
                                                                         my_partner['recid']),
                                                                     'valide': '1',
                                                                     'locked': '0',
                                                                     'list_competence._id': str(diction['competence_id'])},

                                                                {'$pull': {'list_competence': {"_id": str(diction['competence_id'])}}}
                                                                )

        return True, " La compétence a été supprimée"

    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 supprimer la compétence  "



