"""
Ce document définit comment les utilisateurs avec un profil ‘admin’ pourront ajouter de nouveaux champs spécifiques.

Il arrive fréquemment que des clients souhaite ajouter des champs relatifs à leur activité (champs non gérés en standard), ce module est conçu pour répondre à ce besoin.

"""

import bson
import pymongo
from pymongo import MongoClient
import json
from bson import ObjectId
import re
from datetime import datetime
import prj_common as mycommon
import secrets
import inspect
import sys, os
import csv
import pandas as pd
from pymongo import ReturnDocument
import GlobalVariable as MYSY_GV
from math import isnan
import GlobalVariable as MYSY_GV
import ela_index_bdd_classes as eibdd
import email_mgt as email
import jinja2
from flask import send_file
from xhtml2pdf import pisa
from email.message import EmailMessage
from email.mime.text import MIMEText
from email import encoders
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders

"""
Ajout d'un champs spécifique"""

def Add_specific_field(diction):
    try:
        diction = mycommon.strip_dictionary(diction)
        field_list = ['related_collection',  'field_type', 'is_mandatory', 'field_label', 'field_name',
         'is_displayed','field_value', 'token', 'is_public']

        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 = ['related_collection',  'field_type', 'is_mandatory', 'field_label', 'field_name',
         'is_displayed', '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, False

        """
                        Recuperation des données fournies en entrée
                        """
        data = {}
        data['partner_owner_recid'] = str(my_partner['recid'])
        data['valide'] = "1"
        data['locked'] = "0"
        data['date_update'] = str(datetime.now())
        data['field_value'] = ""


        related_collection = ""
        if ("related_collection" in diction.keys()):
            if diction['related_collection']:
                related_collection = diction['related_collection']
        if( str(related_collection) not in MYSY_GV.PERSONALISATION_AUTORIZED_COLLECTION ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(related_collection) + "' n'est pas autorisée pour la personnalisation ")
            return False, "  La valeur '" + str(related_collection) + "' n'est pas autorisée pour la personnalisation",

        data['related_collection'] = related_collection

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

        if (str(field_type) not in MYSY_GV.SPECIFIC_FIELD_TYPE):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    field_type) + "' n'est pas autorisée pour la personnalisation ")
            return False, "  La valeur '" + str(field_type) + "' n'est pas autorisée pour la personnalisation",

        data['field_type'] = field_type

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

        if (str(is_mandatory) not in ['0', '1']):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    is_mandatory) + "' n'est pas autorisée pour la personnalisation ")
            return False, "  La valeur '" + str(is_mandatory) + "' n'est pas autorisée pour la personnalisation",
        data['is_mandatory'] = is_mandatory

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

        if (str(is_public) not in ['0', '1']):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    is_public) + "' n'est pas autorisée pour la personnalisation ")
            return False, "  La valeur '" + str(is_public) + "' n'est pas autorisée pour la personnalisation",
        data['is_public'] = is_public



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

        if (len(str(field_label)) > 50 ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    field_label) + "' n'est pas autorisée pour la personnalisation. Il fait plus de 50 caractères ")
            return False, "  La valeur '" + str(field_label) + "' n'est pas autorisée pour la personnalisation. Il fait plus de 50 caractères",

        data['field_label'] = field_label

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

        if (str(field_name).startswith("my_") is False):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    field_name) + "' n'est pas autorisée pour la personnalisation ")
            return False, "  La valeur '" + str(field_name) + "' n'est pas autorisée pour la personnalisation",

        if (len(str(field_name)) > 50):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    field_name) + "' n'est pas autorisée pour la personnalisation. Il fait plus de 50 caractères ")
            return False, "  La valeur '" + str(
                field_name) + "' n'est pas autorisée pour la personnalisation. Il fait plus de 50 caractères",

        field_name_val_saisie = str(field_name).replace("my_", "")
        if(str(field_name_val_saisie).isalnum() is False ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    field_name_val_saisie) + "' contient des caractères non alphanumériques ")
            return False, "  La valeur '" + str(field_name_val_saisie) + "' contient des caractères non alphanumériques ",


        data['field_name'] = field_name


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

        if (str(is_displayed) not in ['0', '1']):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    is_displayed) + "' n'est pas autorisée pour la personnalisation ")
            return False, "  La valeur '" + str(is_displayed) + "' n'est pas autorisée pour la personnalisation",

        data['is_displayed'] = is_displayed


        # Verification que le champ n'existe pas
        # la clé est le nom
        is_personalisez_field_count = MYSY_GV.dbname['base_specific_fields'].count_documents({'related_collection':str(diction['related_collection']),
                                                                                              'partner_owner_recid':str(my_partner['recid']),
                                                                                              'field_name':str(diction['field_name']),
                                                                                              'valide':'1',
                                                                                              })

        if( is_personalisez_field_count > 0):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - Cette personnalisation existe déjà ")
            return False, "Cette personnalisation existe déjà ",

        inserted_id = ""
        inserted_id = MYSY_GV.dbname['base_specific_fields'].insert_one(data).inserted_id
        if (not inserted_id):
            mycommon.myprint(
                " Impossible de créer le champ personnalisé ")
            return False, " Impossible de créer le champ personnalisé  "


        return True, " Le champ personnalisé a été correctement ajouté "

    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 le nouveau champ personnalisé"


"""
Modification d'un champ spécifique.

/!\ : on ne peut pas modifier le nom technique d'un champ deja utilisé
la requete de controle est : {  "mon_champs" : { $exists : true, $ne: ""  } }, si existe alors PAS de modification du nom technique
"""
def Update_specific_field(diction):
    try:
        diction = mycommon.strip_dictionary(diction)
        field_list = ['related_collection', 'field_type', 'is_mandatory', 'field_label', 'field_name',
                      'is_displayed', 'field_value', '_id', 'token', 'is_public']

        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 = ['related_collection', 'field_type', 'is_mandatory',  'field_name',
                       '_id', 'token', ]

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

        # Verification si l'_id existe et est valide
        specific_field_data = MYSY_GV.dbname['base_specific_fields'].find_one({'_id': ObjectId(str(diction['_id'])), 'partner_owner_recid':str(my_partner['recid']),
             'valide': '1',})

        if( specific_field_data is None):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " -Impossible d'identifier le document à mettre à jour ")
            return False, " Impossible d'identifier le document à mettre à jour",



        # Verification s'il y a eu modification du nom technique du champ
        is_importante_field_changed = False

        if( str( diction['field_name']) != str(specific_field_data['field_name'])):
            is_importante_field_changed = True

        if (str(diction['related_collection']) != str(specific_field_data['related_collection'])):
            is_importante_field_changed = True

        if (str(diction['field_type']) != str(specific_field_data['field_type'])):
            is_importante_field_changed = True

        if( is_importante_field_changed is True ):
            local_qry = {str(specific_field_data['field_name']): {'$exists': True, '$ne': ""}}

            is_record_exist_count = MYSY_GV.dbname[str(specific_field_data['related_collection'])].count_documents(
                local_qry)

            if (is_record_exist_count > 0):
                mycommon.myprint(str(
                    inspect.stack()[0][3]) + " Le champ est déjà utilisé, impossible de modifier le nom technique, le type et l'entité ")
                return False, "Le champ est déjà utilisé, impossible de modifier le nom technique, le type et l'entité",


        """
                        Recuperation des données fournies en entrée
                        """
        data = {}
        data['partner_owner_recid'] = str(my_partner['recid'])
        data['valide'] = "1"
        data['locked'] = "0"
        data['date_update'] = str(datetime.now())
        data['field_value'] = ""

        related_collection = ""
        if ("related_collection" in diction.keys()):
            related_collection = diction['related_collection']
        if (str(related_collection) not in MYSY_GV.PERSONALISATION_AUTORIZED_COLLECTION):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    related_collection) + "' n'est pas autorisée pour la personnalisation ")
            return False, "  La valeur '" + str(related_collection) + "' n'est pas autorisée pour la personnalisation",

        data['related_collection'] = related_collection

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

        if (str(field_type) not in MYSY_GV.SPECIFIC_FIELD_TYPE ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    field_type) + "' n'est pas autorisée pour la personnalisation ")
            return False, "  La valeur '" + str(field_type) + "' n'est pas autorisée pour la personnalisation",

        data['field_type'] = field_type

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

        if (str(is_mandatory) not in ['0', '1']):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    is_mandatory) + "' n'est pas autorisée pour la personnalisation ")
            return False, "  La valeur '" + str(is_mandatory) + "' n'est pas autorisée pour la personnalisation",
        data['is_mandatory'] = is_mandatory

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

        if (str(is_public) not in ['0', '1']):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    is_public) + "' n'est pas autorisée pour la personnalisation ")
            return False, "  La valeur '" + str(is_public) + "' n'est pas autorisée pour la personnalisation",
        data['is_public'] = is_public


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

        if (len(str(field_label)) > 50):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    field_label) + "' n'est pas autorisée pour la personnalisation. Il fait plus de 50 caractères ")
            return False, "  La valeur '" + str(
                field_label) + "' n'est pas autorisée pour la personnalisation. Il fait plus de 50 caractères",

        data['field_label'] = field_label

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

        if (str(field_name).startswith("my_") is False):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    field_name) + "' n'est pas autorisée pour la personnalisation ")
            return False, "  La valeur '" + str(field_name) + "' n'est pas autorisée pour la personnalisation",

        if (len(str(field_name)) > 50):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    field_name) + "' n'est pas autorisée pour la personnalisation. Il fait plus de 50 caractères ")
            return False, "  La valeur '" + str(
                field_name) + "' n'est pas autorisée pour la personnalisation. Il fait plus de 50 caractères",

        data['field_name'] = field_name

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

        if (str(is_displayed) not in ['0', '1']):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La valeur '" + str(
                    is_displayed) + "' n'est pas autorisée pour la personnalisation ")
            return False, "  La valeur '" + str(is_displayed) + "' n'est pas autorisée pour la personnalisation",

        data['is_displayed'] = is_displayed

        # Verification que le champ n'existe pas
        # la clé est le nom
        is_personalisez_field_count = MYSY_GV.dbname['base_specific_fields'].count_documents(
            {'_id': ObjectId(str(diction['_id'])),
             'valide': '1',
             })

        if (is_personalisez_field_count <= 0):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - Cette personnalisation n'existe pas ")
            return False, "Cette personnalisation n'existe pas ",

        ret_val2 = MYSY_GV.dbname['base_specific_fields'].find_one_and_update(
            {'_id': ObjectId(str(diction['_id'])), 'partner_owner_recid':str(my_partner['recid']),
             'valide': '1',},
            {"$set": data},
            return_document=ReturnDocument.AFTER,
            upsert=False,
        )


        return True, " Le champ personnalisé a é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 champ personnalisé "


"""
Recuperation d'un champ spécifique donné en partant de l'_id
"""
def get_given_specific_field(diction):
    try:
        diction = mycommon.strip_dictionary(diction)
        field_list = ['_id', 'token']

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

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

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

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

        #print(" ### data_cle = ", data_cle)

        RetObject = []
        val_tmp = 1
        for retval in MYSY_GV.dbname['base_specific_fields'].find(data_cle):
            user = retval
            user['id'] = str(val_tmp)
            val_tmp = val_tmp + 1
            if( str(retval['related_collection']) == "ressource_humaine"):
                user['related_collection_name'] = "Employe"

            elif (str(retval['related_collection']) == "ressource_materielle"):
                user['related_collection_name'] = "Materiel"

            elif (str(retval['related_collection']) == "session_formation"):
                user['related_collection_name'] = "Session"

            elif (str(retval['related_collection']) == "myclass"):
                user['related_collection_name'] = "Formation"

            elif (str(retval['related_collection']) == "inscription"):
                user['related_collection_name'] = "Inscription"

            else :
                user['related_collection_name'] =  user['related_collection']

            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écuperer le champ personnalisé "

"""
Suppression d'un champ spécifique.
Pour qu'un champ personnalisé soit supprimable, il faut qu'il existe aucun enregistrement avec une valeur pour ce champs.

la requete de controle est : {  "mon_champs" : { $exists : true, $ne: ""  } }, si existe alors PAS de suppression

"""
def delete_given_specific_field(diction):
    try:
        diction = mycommon.strip_dictionary(diction)
        diction = mycommon.strip_dictionary(diction)
        field_list = ['_id', 'token']

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

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

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

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

        """
        Recuperation des données du champ à surprimer
        """
        personnalized_field_data = MYSY_GV.dbname['base_specific_fields'].find_one({'_id':ObjectId(str(diction['_id'])),
                                                                                    'valide':'1',
                                                                                    'partner_owner_recid':str(my_partner['recid'])})

        if( personnalized_field_data is None):
            mycommon.myprint(str(
                inspect.stack()[0][3]) + " L'identification du champ n'est pas valide ")
            return False, "L'identification du champ n'est pas valide ",

        """
        Verification qu'il n'existe aucun enregistrement avec une valeur pour ce champ
        """
        local_qry = { str(personnalized_field_data['field_name']) : { '$exists' : True, '$ne': ""  } }
        #print(" #### delete_given_specific_field local_qry = ", local_qry)
        is_record_exist_count = MYSY_GV.dbname[str(personnalized_field_data['related_collection'])].count_documents(local_qry)

        if( is_record_exist_count > 0 ):
            mycommon.myprint(str(
                inspect.stack()[0][3]) + " Le champ est déjà utilisé, impossible de le supprimer ")
            return False, "Le champ est déjà utilisé, impossible de le supprimer ",


        MYSY_GV.dbname['base_specific_fields'].delete_one({'_id':ObjectId(str(diction['_id']))})


        return True, " Le champ personnalisé 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 le champ personnalisé "



""""
Recuperation de la liste des champs spécifique utilisable par un objet metier.
il est important de ne prendre que ceux qui sont valide et avec is_displayed = 1
car cette fonction est utilisée pour remplir les champs.
"""
def Get_Partner_Object_Specific_Valide_Displayed_Fields(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

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

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

        data_cle = {}
        data_cle['partner_owner_recid'] = str(my_partner['recid'])
        data_cle['related_collection'] = str(diction['object_name'])
        data_cle['valide'] = "1"
        data_cle['locked'] = "0"

        RetObject = []
        val_tmp = 1

        # print(" ### qtry = ", data_cle)

        for retval in MYSY_GV.dbname['base_specific_fields'].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écuperer la liste des champs personnalisés "






"""
Recuperation de liste des champs spécifiques d'un partenaire, sans aucun filter
"""
def get_list_specific_field_partner_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']

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

        data_cle = {}
        data_cle['partner_owner_recid'] = str(my_partner['recid'])
        data_cle['valide'] = "1"
        data_cle['locked'] = "0"

        RetObject = []
        val_tmp = 1

        # print(" ### qtry = ", data_cle)

        for retval in MYSY_GV.dbname['base_specific_fields'].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écuperer la liste des champs personnalisés "


"""
Recuperation de liste des champs spécifiques d'un partenaire, avec des filtres sur 
- objet metier
- nom du champs
"""
def get_list_specific_field_partner_with_filter(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

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

        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

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

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

        data_cle = {}
        data_cle['partner_owner_recid'] = str(my_partner['recid'])
        data_cle['valide'] = "1"
        data_cle['locked'] = "0"

        RetObject = []
        val_tmp = 1

        local_qry = {"$and":[ data_cle, filt_object_name, filt_field_name]}
        print(" ### get_list_specific_field_partner_with_filter local_qry = ", local_qry)

        for retval in MYSY_GV.dbname['base_specific_fields'].find(local_qry):
            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écuperer la liste des champs personnalisés "




"""
Recuperation de liste des champs spécifiques d'un objet (client, formation, etc)  d'un partenaire
"""
def get_list_specific_field_partner_by_object(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

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

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

        data_cle = {}
        data_cle['partner_owner_recid'] = str(my_partner['recid'])
        data_cle['related_collection'] = str(diction['object_name']).strip().lower()
        data_cle['is_displayed'] = "1"
        data_cle['valide'] = "1"
        data_cle['locked'] = "0"

        RetObject = []
        val_tmp = 1

        #print(" ### qtry = ", data_cle)

        for retval in MYSY_GV.dbname['base_specific_fields'].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 champs spécifiques "


"""
Fonction retourne la liste des collection eligibles à la creation de champs spécifique
"""
def Get_Collection_Eligible_Champ_Specific():
    try:
        RetObject = []

        mycollection_field1 = {"objet_metier": 'ressource_humaine', "nom": 'Employe',}
        mycollection_field2 = {"objet_metier": 'ressource_materielle', "nom": 'Materiel',}
        mycollection_field3 = {"objet_metier": 'session_formation', "nom": 'Session', }
        mycollection_field4 = {"objet_metier": 'myclass', "nom": 'Formation', }
        mycollection_field5 = {"objet_metier": 'inscription', "nom": 'Inscription', }


        RetObject.append(mycommon.JSONEncoder().encode(mycollection_field1))
        RetObject.append(mycommon.JSONEncoder().encode(mycollection_field2))
        RetObject.append(mycommon.JSONEncoder().encode(mycollection_field3))
        RetObject.append(mycommon.JSONEncoder().encode(mycollection_field4))
        RetObject.append(mycommon.JSONEncoder().encode(mycollection_field5))

        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 récupérer la liste des object métiers éligibles pour les champs spécifiques"
