"""
Ce fichier permet de gerer la personalisation des documents d'un partenaire.

Par exemple, la personnalisation des documents de convocation.
Il permet egalement de créer un document à par entitère, inconnu par l'editeur du logiciel.
Use case : un partenaire souhaite un document d'attestation de presence.

A la creation, l'utilisateur devra choisir un objet (formation, stagiaire, etc), le système proposera les champs adequat

Donc au debut, l'utilisateur peut :
1 - Modifier un document existant (convocation, confirmation inscription, annulation inscription, etc)
2 - Créer un nouveau document from scratch (attestation de presence)
/!\ : Prevoir un bouton previsualitation
"""
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

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

        """
        Verification des input acceptés
        """
        field_list = ['token',  "nom",  "ref_interne", "type_doc", "cible", "sujet",'contenu_doc', 'duplicate',
                      'joint_pdf', 'default_version', 'corps_mail', 'edit_by_client',
                      'courrier_template_type_document_ref_interne', 'original_courrier_template_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',  "ref_interne", ]

        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 = {}
        data['partner_owner_recid'] = my_partner['recid']

        if ("original_courrier_template_id" in diction.keys() and diction['original_courrier_template_id']):
            is_original_courrier_template_id_valide = MYSY_GV.dbname['courrier_template'].count_documents(
                {'_id': ObjectId(str(diction['original_courrier_template_id'])),
                 'valide': '1',
                 'locked': '0',
                 'partner_owner_recid': 'default'})
            if (is_original_courrier_template_id_valide != 1):
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " L'identifiant du courrier d'origine (original_courrier_template_id)  est invalide ")

                return False, " L'identifiant du courrier d'origine (original_courrier_template_id)  est invalide "

            # Cette n'est ajoutée que le champ existe et est valide. donc l'indemtation est dans le 'if', normal
            data['original_courrier_template_id'] = diction['original_courrier_template_id']

            # Recuperation de quelques valeurs par défaut
            is_original_courrier_template_id_data = MYSY_GV.dbname['courrier_template'].find_one(
                {'_id': ObjectId(str(diction['original_courrier_template_id'])),
                 'valide': '1',
                 'locked': '0',
                 'partner_owner_recid': 'default'})

            if ("duplicate" in is_original_courrier_template_id_data.keys()):
                data['duplicate'] = is_original_courrier_template_id_data['duplicate']

            if ("joint_pdf" in is_original_courrier_template_id_data.keys()):
                data['joint_pdf'] = is_original_courrier_template_id_data['joint_pdf']

            if ("edit_by_client" in is_original_courrier_template_id_data.keys()):
                data['edit_by_client'] = is_original_courrier_template_id_data['edit_by_client']

            if ("type_doc" in is_original_courrier_template_id_data.keys()):
                data['type_doc'] = is_original_courrier_template_id_data['type_doc']



        ref_interne = ""
        if ("ref_interne" in diction.keys()):
            if diction['ref_interne']:
                ref_interne = diction['ref_interne']
                if (len(str(ref_interne)) > 255):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - Le champ 'ref_interne' fait plus de 255 caractères ")

                    return False, " - Le champ 'ref_interne' fait plus de 255 caractères "
        data['ref_interne'] = ref_interne

        nom = ""
        if ("nom" in diction.keys()):
            if diction['nom']:
                nom = diction['nom']
                if (len(str(nom)) > 255):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - Le champ 'nom' fait plus de 255 caractères ")

                    return False, " - Le champ 'nom' fait plus de 255 caractères "
        data['nom'] = nom



        sujet = ""
        if ("sujet" in diction.keys()):
            if diction['sujet']:
                sujet = diction['sujet']
                if (len(str(sujet)) > 255):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - Le champ 'sujet' fait plus de 255 caractères ")

                    return False, " - Le champ 'sujet' fait plus de 255 caractères "
        data['sujet'] = sujet


        cible = ""
        if ("cible" in diction.keys()):
            if diction['cible']:
                cible = diction['cible']
                if (len(str(cible)) > 255):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - Le champ 'cible' fait plus de 255 caractères ")

                    return False, " - Le champ 'cible' fait plus de 255 caractères "
        data['cible'] = cible

        courrier_template_type_document_ref_interne = ""
        if ("courrier_template_type_document_ref_interne" in diction.keys()):
            if diction['courrier_template_type_document_ref_interne']:
                courrier_template_type_document_ref_interne = diction['courrier_template_type_document_ref_interne']
                if (len(str(courrier_template_type_document_ref_interne)) > 255):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - Le champ 'courrier_template_type_document_ref_interne' fait plus de 255 caractères ")

                    return False, " - Le champ 'courrier_template_type_document_ref_interne' fait plus de 255 caractères "
        data['courrier_template_type_document_ref_interne'] = courrier_template_type_document_ref_interne


        type_doc = ""
        if ("type_doc" in diction.keys()):
            if diction['type_doc']:
                type_doc = diction['type_doc']
                if (str(type_doc).lower().strip() not in MYSY_GV.MODELE_DOCUMENT_TYPE ):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - Le champ 'type_doc' n'est pas accepté. les valeurs acceptées sont "+str(MYSY_GV.MODELE_DOCUMENT_TYPE))

                    return False, " - Le champ 'type_doc' n'est pas accepté. les valeurs acceptées sont "+str(MYSY_GV.MODELE_DOCUMENT_TYPE)
        data['type_doc'] = type_doc


        contenu_doc = ""
        if ("contenu_doc" in diction.keys()):
            if diction['contenu_doc']:
                contenu_doc = diction['contenu_doc']
                if (len(str(contenu_doc)) > 30000):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " Le champ 'contenu_doc' fait "+str(len(str(contenu_doc)))+" cartactères. Limite 30000 caractères ")

                    return False, "  Le champ 'contenu_doc' fait "+str(len(str(contenu_doc)))+" cartactères. Limite 30000 caractères "
        data['contenu_doc'] = contenu_doc


        duplicate = "0"
        if ("duplicate" in diction.keys()):
            if diction['duplicate']:
                duplicate = diction['duplicate']
                if(str(duplicate) not in ['0', '1']):
                    duplicate = '0'

        data['duplicate'] = duplicate


        # ----
        joint_pdf = "0"
        if ("joint_pdf" in diction.keys()):
            if diction['joint_pdf']:
                joint_pdf = diction['joint_pdf']
                if (str(joint_pdf) not in ['0', '1']):
                    joint_pdf = '0'
        data['joint_pdf'] = joint_pdf

        edit_by_client = "0"
        if ("edit_by_client" in diction.keys()):
            if diction['edit_by_client']:
                edit_by_client = diction['edit_by_client']
                if (str(edit_by_client) not in ['0', '1']):
                    edit_by_client = '0'

        data['edit_by_client'] = edit_by_client



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

        corps_mail = ""
        if ("corps_mail" in diction.keys()):
            if diction['corps_mail']:
                corps_mail = diction['corps_mail']
                if (len(str(corps_mail)) > 10000):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - Le champ 'corps_mail' fait plus de 10000 caractères ")

                    return False, " - Le champ 'corps_mail' fait plus de 10000 caractères "
        data['corps_mail'] = corps_mail

        # ---

        qry = {'ref_interne':str(ref_interne), 'valide':'1',
                                                                               'partner_owner_recid':str(my_partner['recid']),
                                                                               'nom': str(nom),
                                                                               'type_doc':str(diction['type_doc'])}

        print(" ### qry = ", qry)

        # Verifier qu'il n'existe pas un document avec le meme code code interne
        exist_doc_count = MYSY_GV.dbname['courrier_template'].count_documents({'ref_interne':str(ref_interne), 'valide':'1',
                                                                               'partner_owner_recid':str(my_partner['recid']),
                                                                               'nom': str(nom),
                                                                               'type_doc':str(diction['type_doc'])})

        if( exist_doc_count > 0 ):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Il existe déjà un document avec la meme reference interne ")
            return False, "- Il existe déjà un document avec la meme reference interne "


        """
        Si le document est une vesion par defaut, il faut alors decoché un eventuel document avec le meme : 
        - ref_interne
        - type_doc
        
        """
        if( "default_version" in diction.keys()  and str(diction['default_version']) == "1"):
            MYSY_GV.dbname['courrier_template'].update_many({'ref_interne':str(ref_interne),
                                                             'valide':'1',
                                                                'edit_by_client':str(edit_by_client),
                                                             'partner_owner_recid':str(my_partner['recid']),
                                                             'type_doc':str(diction['type_doc'])},
                                                            {'$set':{'default_version':'0'}})

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

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

        return True, " Le nouveau document a é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 nouveau document "


"""
Mise à jour d'un document d'un partenaire  en se basant sur son _id
"""
def Update_Partner_Document(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
               Verification des input acceptés
               """
        field_list = ['token',  "nom",  "ref_interne", "type_doc", "cible", "sujet",'contenu_doc', '_id',
                      'joint_pdf', 'default_version', 'corps_mail', 'edit_by_client']

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

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

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

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

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

        """
           Verification si ce document n'existe pas deja pour ce partner
             """

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



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

            return False, " - Ce document n'existe pas "



        data_update = {}
        """
        Recuperation des données fournies en entrée
        """
        ref_interne = ""
        if ("ref_interne" in diction.keys()):
            if diction['ref_interne']:
                ref_interne = diction['ref_interne']
                if (len(str(ref_interne)) > 255):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - Le champ 'ref_interne' fait plus de 255 caractères ")

                    return False, " - Le champ 'ref_interne' fait plus de 255 caractères "
                data_update['ref_interne'] = diction['ref_interne']

        nom = ""
        if ("nom" in diction.keys()):
            if diction['nom']:
                nom = diction['nom']
                if (len(str(nom)) > 255):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - Le champ 'nom' fait plus de 255 caractères ")

                    return False, " - Le champ 'nom' fait plus de 255 caractères "
                data_update['nom'] = diction['nom']

        sujet = ""
        if ("sujet" in diction.keys()):
            if diction['sujet']:
                sujet = diction['sujet']
                if (len(str(sujet)) > 255):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - Le champ 'sujet' fait plus de 255 caractères ")

                    return False, " - Le champ 'sujet' fait plus de 255 caractères "
                data_update['sujet'] = diction['sujet']

        cible = ""
        if ("cible" in diction.keys()):
            if diction['cible']:
                cible = diction['cible']
                if (len(str(cible)) > 255):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - Le champ 'cible' fait plus de 255 caractères ")

                    return False, " - Le champ 'cible' fait plus de 255 caractères "
                data_update['cible'] = diction['cible']



        type_doc = ""
        if ("type_doc" in diction.keys()):
            if diction['type_doc']:
                type_doc = diction['type_doc']
                if (str(type_doc).lower().strip() not in MYSY_GV.MODELE_DOCUMENT_TYPE):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - Le champ 'type_doc' n'est pas accepté. les valeurs acceptées sont " + str(
                            MYSY_GV.MODELE_DOCUMENT_TYPE))

                    return False, " - Le champ 'type_doc' n'est pas accepté. les valeurs acceptées sont " + str(
                        MYSY_GV.MODELE_DOCUMENT_TYPE)
                data_update['type_doc'] = diction['type_doc']

        contenu_doc = ""
        if ("contenu_doc" in diction.keys()):
            if diction['contenu_doc']:
                contenu_doc = diction['contenu_doc']
                if (len(str(sujet)) > 20000):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - Le champ 'contenu_doc' fait plus de 20000 caractères ")

                    return False, " - Le champ 'contenu_doc' fait plus de 20000 caractère "
                data_update['contenu_doc'] = diction['contenu_doc']


        # ----
        joint_pdf = "0"
        if ("joint_pdf" in diction.keys()):
            if diction['joint_pdf']:
                joint_pdf = diction['joint_pdf']
                if (str(joint_pdf) not in ['0', '1']):
                    joint_pdf = '0'
                data_update['joint_pdf'] = joint_pdf

        edit_by_client = "0"
        if ("edit_by_client" in diction.keys()):
            if diction['edit_by_client']:
                edit_by_client = diction['edit_by_client']
                if (str(edit_by_client) not in ['0', '1']):
                    edit_by_client = '0'
                data_update['edit_by_client'] = edit_by_client


        default_version = "0"
        if ("default_version" in diction.keys()):
            if diction['default_version']:
                default_version = diction['default_version']
                if (str(default_version) not in ['0', '1']):
                    default_version = '0'
                data_update['default_version'] = default_version

        corps_mail = ""
        if ("corps_mail" in diction.keys()):
            if diction['corps_mail']:
                corps_mail = diction['corps_mail']
                if (len(str(corps_mail)) > 10000):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " - Le champ 'corps_mail' fait plus de 10000 caractères ")

                    return False, " - Le champ 'corps_mail' fait plus de 10000 caractères "
                data_update['corps_mail'] = corps_mail

        # ---

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

        """
                Si le document est une vesion par defaut, il faut alors decoché un eventuel document avec le meme : 
                - ref_interne
                - type_doc

                """

        qry_update ={'ref_interne': str(ref_interne),
                                                             'valide': '1',
                                                             'edit_by_client': str(edit_by_client),
                                                             'partner_owner_recid': str(my_partner['recid']),
                                                             'type_doc': str(diction['type_doc'])}

        print(" ### qry_update = ", qry_update)
        if ("default_version" in diction.keys() and str(diction['default_version']) == "1"):
            MYSY_GV.dbname['courrier_template'].update_many({'ref_interne': str(ref_interne),
                                                             'valide': '1',
                                                             'edit_by_client': str(edit_by_client),
                                                             'partner_owner_recid': str(my_partner['recid']),
                                                             'type_doc': str(diction['type_doc'])},
                                                            {'$set': {'default_version': '0'}})


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


        inserted_id = ""
        result = MYSY_GV.dbname['courrier_template'].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 le modèle de document = ")
            return False, " Impossible de mettre à jour le modèle de document "

        return True, " Le modèle de document 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 modèle de document "


"""
Suppression d'un modèle de document d'un partenaire
"""
def Delete_Partner_Document(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

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


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

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

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

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

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

        """
        Verification de l'existance du modèle de document a supprimer
        """
        existe_modele_doc_count = MYSY_GV.dbname['courrier_template'].count_documents({'_id': ObjectId(str(diction['_id'])),
                                                                                     'partner_owner_recid': str(my_partner['recid']),})

        if( existe_modele_doc_count <= 0 ):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Ce modèle de document  est invalide")
            return False, str(inspect.stack()[0][3]) + "  - Ce modèle de document est invalide "




        """
        Suppression du modèle de document
        """
        MYSY_GV.dbname['courrier_template'].delete_many({'_id': ObjectId(str(diction['_id'])),
                                                                     'partner_owner_recid': str(my_partner['recid']),})



        return True, " Le modèle de document 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 materiel "


"""
Recuperation de la liste des modèles de document d'un partenaire en se basant sur le token (partner_owner_recid)

"""
def Get_List_Partner_Document(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'] = str(my_partner['recid'])

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

        RetObject = []
        val_tmp = 1

        for retval in MYSY_GV.dbname['courrier_template'].find(data_cle):
            user = retval
            user['id'] = str(val_tmp)
            if ("duplicate" not in retval.keys()):
                user['duplicate'] = "0"
            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 modèles de document "


"""
Recuperation de la liste des documents par defaut 
"""
def Get_List_Default_Partner_Document(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['locked'] = "0"
        data_cle['valide'] = "1"

        RetObject = []
        val_tmp = 1

        for retval in MYSY_GV.dbname['courrier_template'].find(data_cle, {'_id':1, 'nom':1, 'ref_interne':1, 'type_doc':1 }):
            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 modèles de document "



"""
Recuperation d'un modèle de dcument donnée en se basant sur on token, _id, 
"""
def Get_Given_Partner_Document(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

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

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

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

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

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


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

        RetObject = []
        val_tmp = 1

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

            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 le modèle de document "

"""
Recuperation d'un document par defaut qui EST UNIQUEMENT paramettré avec un "partner_owner_recid" =  "default"
"""
def Get_Given_DFAULT_Partner_Document(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

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

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

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

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

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


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

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

        RetObject = []
        val_tmp = 1

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

            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 le modèle de document "


"""
Recherche de la liste des modèles de document sans filter - no_filter
"""
def Get_List_Partner_Document_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


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

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

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

        #print(" ### materiel find_qry = ", find_qry)
        RetObject = []
        val_tmp = 1

        for retval in MYSY_GV.dbname['courrier_template'].find(find_qry).sort([("_id", pymongo.DESCENDING)]):
            user = retval
            user['id'] = str(val_tmp)
            val_tmp = val_tmp + 1
            if( "duplicate" not in retval.keys()):
                user['duplicate'] = "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 modèles de document "


"""
Recherche de la liste des modèles de document avec des filter
"""
def Get_List_Partner_Document_with_filter(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

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

        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_nom = {}
        if ("nom" in diction.keys()):
            filt_nom = {'nom': {'$regex': str(diction['nom']), "$options": "i"}}

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



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

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


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

        #print(" ### materiel find_qry = ", find_qry)
        RetObject = []
        val_tmp = 1

        for retval in MYSY_GV.dbname['courrier_template'].find(find_qry).sort([("_id", pymongo.DESCENDING)]):
            user = retval
            user['id'] = str(val_tmp)
            val_tmp = val_tmp + 1
            if( "duplicate" not in retval.keys()):
                user['duplicate'] = "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 modèles de document "




"""
Pour permettre de rénitialiser un template 'detruit' par un user,
Cette fonction permet de récupérer les données d'origine du template
"""
def Get_Default_Partner_Document_By_Internal_Ref(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', 'ref_interne', 'original_courrier_template_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', 'ref_interne', 'original_courrier_template_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 'original_courrier_template_id' existe et est valide
        if( 'original_courrier_template_id' in diction.keys()):
            is_original_courrier_template_id_valide = MYSY_GV.dbname['courrier_template'].count_documents({'_id':ObjectId(str(diction['original_courrier_template_id'])),
                                                                                                           'valide':'1',
                                                                                                           'locked':'0',
                                                                                                          'partner_owner_recid':'default'})

            if (is_original_courrier_template_id_valide != 1):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " Le champ 'original_courrier_template_id' n'est pas valide ")
                return False, " Le champ 'original_courrier_template_id' n'est pas valide "



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


        RetObject = []
        val_tmp = 1

        #print(" ### data_cle = ", data_cle)
        for retval in MYSY_GV.dbname['courrier_template'].find({'_id':ObjectId(str(diction['original_courrier_template_id'])),
                                                                                                           'valide':'1',
                                                                                                           'locked':'0',
                                                                                                          'partner_owner_recid':'default'}):
            user = retval
            user['id'] = str(val_tmp)
            val_tmp = val_tmp + 1

            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 le modèle de document d'origine "



"""
Recuperation de tous les  champs personnalisables
"""
def Get_All_Personnalisable_Collection_Fields(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"

        RetObject = []
        val_tmp = 1

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

            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 champs personnalisables  "




"""
Recuperation des champs personnalisable d'un 'courrier_template_ref_interne' donné
"""
def Get_Given_Personnalisable_Fields_By_template_ref_interne(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

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

        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', 'courrier_template_ref_interne' ]
        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['courrier_template_ref_interne'] = diction['courrier_template_ref_interne']


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

        RetObject = []
        val_tmp = 1

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

            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 champs personnalisables de l'objet "



"""
Recuperation des champs personnalisable d'un 'courrier_template_id' donné, avec un partner_owner_recid  = "default"
"""
def Get_Given_Personnalisable_Fields_By_courrier_template_id(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

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


        # Recuperation du ref interne du courrie_template, avec un partner_owner_recid  = "default"

        courrier_template_data =  MYSY_GV.dbname['courrier_template'].find_one({'partner_owner_recid':'default', '_id':ObjectId(str(diction['courrier_template_id'])),
                                                                                'valide':'1', 'locked':'0'})

        if( courrier_template_data is None):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - L'Id du modèle de courrier est invalide ")
            return False, " L'Id du modèle de courrier est invalide",

        if( "ref_interne" not in courrier_template_data.keys() ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - La ref_interne du modèle de courrier est invalide ")
            return False, "  La ref_interne du modèle de courrier est invalide",


        """
        Clés de mise à jour 
        """
        data_cle = {}
        data_cle['partner_owner_recid'] = 'default'
        data_cle['courrier_template_ref_interne'] = courrier_template_data['ref_interne']


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

        RetObject = []
        val_tmp = 1

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

            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 champs personnalisables de l'objet "


"""
Dupliquer un document
"""
def Duplicate_Given_Partner_Document(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

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

        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 = field_list = ['token', '_id', 'nom', 'sujet', 'type_doc']
        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 document existe et qu"il est bien duplicable
        """
        is_document_valide = MYSY_GV.dbname['courrier_template'].count_documents({'_id':ObjectId(str(diction['_id'])),
                                                                           'valide':'1',
                                                                           'locked':'0',
                                                                           'duplicate':'1',
                                                                           'partner_owner_recid':str(my_partner['recid'])
                                                                           })

        if(is_document_valide != 1 ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - L'identifiant du modèle de courrier est invalide ")
            return False, " L'identifiant du modèle de courrier est invalide ",

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

        new_document = is_document_data
        del new_document['_id']

        new_document['date_update'] = str(datetime.now())
        new_document['update_by'] = str(my_partner['_id'])
        new_document['type_doc'] = str(diction['type_doc'])
        new_document['nom'] = str(diction['nom'])
        new_document['sujet'] = str(diction['sujet'])


        if( "joint_pdf" in is_document_data.keys()):
            new_document['joint_pdf'] = str(is_document_data['joint_pdf'])
        else:
            new_document['joint_pdf'] = "0"

        if ("corps_mail" in is_document_data.keys()):
            new_document['corps_mail'] = str(is_document_data['corps_mail'])
        else:
            new_document['corps_mail'] = ""

        # On ne reprend jamais le 'default_version' dans une duplicata
        new_document['default_version'] = "0"


        inserted_id = MYSY_GV.dbname['courrier_template'].insert_one(new_document).inserted_id
        if (not inserted_id):
            mycommon.myprint(
                " Impossible de dupliquer le document (1) ")
            return False, " Impossible de dupliquer le document (1) "


        return True, "Le document a été correctement dupliqué "
    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 du dupliquer le document  "