"""
Ce fichier permet de gerer les sequences associées à une session de formation. En effet toutes journées ou 1/2 journées de formation
ne sont pas consecutives.
Par exemple, une session peut de deroulée sur 2 mois (planning) mais en realité il y une formation tous les 3 jours

Ce developpement permet de gerer ce cas.
"""


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
from datetime import timedelta
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

import base_config_modele_journee as base_config_modele_journee


"""
Regles : 
Pour la meme session, verifier qu'il n'y pas de chevauchement de date 

"""

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

        """
        Verification des input acceptés
        """
        field_list = ['token', 'session_id', 'sequence_title', 'sequence_start', 'sequence_end', ]

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

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', 'session_id', 'sequence_title', 'sequence_start', 'sequence_end', ]

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

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

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


        # Verification de l'existence et de la session
        is_existe_valide_session_id = MYSY_GV.dbname["session_formation"].count_documents({'_id':ObjectId(str(diction['session_id'])),
                                                                                                                        'partner_owner_recid':str(my_partner['recid']),
                                                                                                                        'valide':'1'})

        if( is_existe_valide_session_id <= 0):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - L'identifiant de la session n'est pas valide ")
            return False, "L'identifiant de la session n'est pas valide "


        # Recuperation des données de la session
        is_existe_valide_session_id_data = MYSY_GV.dbname["session_formation"].find_one(
            {'_id': ObjectId(str(diction['session_id'])),
             'partner_owner_recid': str(my_partner['recid']),
             'valide': '1'})



        # Verifier qu'il n'y a pas de chevauchement de date avec une autre sequence de la meme session.
        date_debut_seq = ""
        if ("sequence_start" in diction.keys()):
            if diction['sequence_start']:
                date_debut_seq = str(diction['sequence_start'])
                local_status = mycommon.CheckisDate_Hours(date_debut_seq)
                if (local_status is False):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " La date de debut de séquence " + str(
                            date_debut_seq) + " n'est pas au format 'jj/mm/aaaa hh:mm' ")
                    return False, " La date de debut de séquence " + str(date_debut_seq) + " n'est pas au format 'jj/mm/aaaa hh:mm'"

        date_fin_seq = ""
        if ("sequence_end" in diction.keys()):
            if diction['sequence_end']:
                date_fin_seq = str(diction['sequence_end'])
                local_status = mycommon.CheckisDate_Hours(date_fin_seq)
                if (local_status is False):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " La date de fin de séquence " + str(
                            date_fin_seq) + " n'est pas au format 'jj/mm/aaaa hh:mm' ")
                    return False, " La date de fin de séquence " + str(
                        date_fin_seq) + " n'est pas au format 'jj/mm/aaaa hh:mm'"



        if (datetime.strptime(str(date_debut_seq), '%d/%m/%Y %H:%M') >= datetime.strptime(str(date_fin_seq),'%d/%m/%Y %H:%M')):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " La date de fin de séquence " + str(
                    date_fin_seq) + " doit être postérieure à la date de début de séquence "+ str( date_debut_seq)+" ")
            return False, " La date de fin de séquence " + str(
                    date_fin_seq) + " doit être postérieure à la date de début de séquence "+ str( date_debut_seq)+" "



        for retVal in MYSY_GV.dbname['session_formation_sequence'].find({'session_id': str(diction['session_id']),
                                                                         'partner_owner_recid': str(my_partner['recid']),
                                                                         'valide':'1',
                                                                         'locked':'0'}):

            #print(" #### str(retVal['event_start']) = ", str(retVal['sequence_start']))
            #print(" #### str(retVal['event_end']) = ", str(retVal['sequence_end']))

            New_retVal_start_date =  datetime.strptime(str(retVal['sequence_start']), '%d/%m/%Y %H:%M').strftime("%d/%m/%Y %H:%M")
            New_retVal_end_date =  datetime.strptime(str(retVal['sequence_end']), '%d/%m/%Y %H:%M').strftime("%d/%m/%Y %H:%M")
            #print(" ### New_retVal_start_date = ", New_retVal_start_date)
            #print(" ### New_retVal_end_date = ", New_retVal_end_date)



            if (datetime.strptime(str(New_retVal_start_date), '%d/%m/%Y %H:%M') <= datetime.strptime(str(date_debut_seq), '%d/%m/%Y %H:%M') and
                     datetime.strptime(str(New_retVal_end_date), '%d/%m/%Y %H:%M') >= datetime.strptime(str(date_debut_seq), '%d/%m/%Y %H:%M')):

                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " La date de debut de séquence" + str(
                        date_debut_seq) + " chevauche une autre séquence ")
                return False, " La date de debut de séquence" + str(
                    date_debut_seq) + " chevauche une autre séquence"

            if (datetime.strptime(str(New_retVal_start_date), '%d/%m/%Y %H:%M') <= datetime.strptime(str(date_fin_seq), '%d/%m/%Y %H:%M') and
                     datetime.strptime(str(New_retVal_end_date), '%d/%m/%Y %H:%M') >= datetime.strptime(str(date_fin_seq), '%d/%m/%Y %H:%M')):

                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " La date de fin de séquence" + str(
                        date_debut_seq) + " chevauche une autre séquence ")
                return False, " La date de fin de séquence" + str(
                    date_debut_seq) + " chevauche une autre séquence"

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


        my_data = {}
        my_data['session_id'] = str(diction['session_id'])
        my_data['sequence_title'] = sequence_title
        my_data['sequence_start'] = date_debut_seq
        my_data['sequence_end'] = date_fin_seq
        my_data['valide'] = "1"
        my_data['locked'] = "0"
        my_data['partner_owner_recid'] = str(my_partner['recid'])
        my_data['update_by'] = str(my_partner['_id'])


        MYSY_GV.dbname['session_formation_sequence'].insert_one(my_data)



        """
        """

        return True, " La séquence a été correctement ajoutée"

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


"""
Fonction de Creation automatique de sequence.
Pour certains utilisteurs, au lieu de créer manuellement chaque sequence,
ils laisse le système créer toutes les sequence.

Alogo :
1 - Si la session est valide, on supprime toutes les sequences existantes pour cette session (y compris les plannings)
2 - on prend en entrée le modele de journé à appliquer (heures de la journée, jours de la semaine)
3 - Pour chaque ressource rattachée à session, on va aller faire les reservation d'agenda : ATTENTION
  -> NOTE : On ne va pas ajouté les ressources tout de suite. Apres la creation, on donnera la possiblité de choisir plusieurs (voir toutes) 
  les sequence, puis proposer l'ajout en masse d'une ressource.

"""

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

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

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

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

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

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

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


        # Verification de l'existence et de la session
        is_existe_valide_session_id = MYSY_GV.dbname["session_formation"].count_documents({'_id':ObjectId(str(diction['session_id'])),
                                                                                                                        'partner_owner_recid':str(my_partner['recid']),
                                                                                                                        'valide':'1'})

        if( is_existe_valide_session_id <= 0):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - L'identifiant de la session n'est pas valide ")
            return False, "L'identifiant de la session n'est pas valide "

        """
        Si le "jounree_modele_id" est vide, cela veut dire qu'il faut aller chercher le modele par default
        """
        jounree_modele_id = ""
        if( str(diction['jounree_modele_id']) == "" ):
            jounree_modele_data = MYSY_GV.dbname['base_config_modele_journee'].find_one({'partner_owner_recid': str(my_partner['recid']),
             'valide': '1', 'locked':'0'})

            if( jounree_modele_data is None ):
                # On ne trouve pas de modele par defaut pour ce client. On va aller le chercher le modele par defaut de MySy
                jounree_modele_data_mysy = MYSY_GV.dbname['base_config_modele_journee'].find_one(
                    {'partner_owner_recid': "default",  'valide': '1', 'locked': '0'})

                if( jounree_modele_data_mysy is None ):
                    mycommon.myprint(
                        str(inspect.stack()[0][3]) + " - Aucun modèle de journée n'est configuré dans le système ")
                    return False, " Aucun modèle de journée n'est configuré dans le système "


                jounree_modele_id = str(jounree_modele_data_mysy['_id'])


            else:
                jounree_modele_id = str(jounree_modele_data['_id'])


        else:
            jounree_modele_id = str(diction['jounree_modele_id'])



        if (str(jounree_modele_id).strip() == ""):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - Aucun modèle de journée n'est configuré dans le système (2) ")
            return False, " Aucun modèle de journée n'est configuré dans le système (2) "



        # Verification de l'existence du modele de journée
        is_existe_valide_journee_model_id = MYSY_GV.dbname["base_config_modele_journee"].count_documents(
            {'_id': ObjectId(str(jounree_modele_id)) ,
             'partner_owner_recid': str(my_partner['recid']),
             'valide': '1', 'locked':'0'})

        if (is_existe_valide_journee_model_id <= 0):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - L'identifiant du modèle de journee n'est pas valide ")
            return False, "  L'identifiant du modèle de journee n'est pas valide "


        # Recuperation des data de la journée modele
        is_existe_valide_journee_model_data= MYSY_GV.dbname["base_config_modele_journee"].find_one(
            {'_id': ObjectId(str(jounree_modele_id)),
             'partner_owner_recid': str(my_partner['recid']),
             'valide': '1', 'locked': '0'})

        """
        for local_val in is_existe_valide_journee_model_data['tab_sequence']:
            model_heure_debut = local_val['heure_debut']
            model_heure_fin = local_val['heure_fin']

            local_status = mycommon.CheckisDate_Hours(model_heure_debut)
            if (local_status is False):
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " La date de debut de séquence " + str(
                        model_heure_debut) + " n'est pas au format 'jj/mm/aaaa hh:mm' ")
                return False, " La date de debut de séquence " + str(
                    model_heure_debut) + " n'est pas au format 'jj/mm/aaaa hh:mm'"


            local_status = mycommon.CheckisDate_Hours(model_heure_fin)
            if (local_status is False):
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " La date de fin de séquence " + str(
                        model_heure_fin) + " n'est pas au format 'jj/mm/aaaa hh:mm' ")
                return False, " La date de fin de séquence " + str(
                    model_heure_fin) + " n'est pas au format 'jj/mm/aaaa hh:mm'"

            """""


        is_existe_valide_session_data = MYSY_GV.dbname["session_formation"].find_one(
            {'_id': ObjectId(str(diction['session_id'])),
             'partner_owner_recid': str(my_partner['recid']),
             'valide': '1'})

        date_debut_session = ""
        if ("date_debut" in is_existe_valide_session_data.keys()):
            if is_existe_valide_session_data['date_debut']:
                date_debut_session = str(is_existe_valide_session_data['date_debut'])[0:10]
                local_status = mycommon.CheckisDate(date_debut_session)
                if (local_status is False):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " La date de debut de session " + str(
                            date_debut_session) + " n'est pas au format 'jj/mm/aaaa' ")
                    return False, " La date de debut de session " + str(
                        date_debut_session) + " n'est pas au format 'jj/mm/aaaa' "

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


        date_debut_session = datetime.strptime(str(date_debut_session), '%d/%m/%Y')
        date_fin_session = datetime.strptime(str(date_fin_session), '%d/%m/%Y')

        print(" les jours travaillé ")
        liste_jours_travaille = []
        liste_jours_travaille_code_day = []
        if ("jours" in is_existe_valide_journee_model_data.keys()):
            for jour in is_existe_valide_journee_model_data['jours']:
                if (str(jour['travail']) == "1"):
                    liste_jours_travaille.append(str(jour['jour']))
                    liste_jours_travaille_code_day.append(str(jour['day_name']))

        """
        /!\ Suppression des sequences qui existe et reservation dans les agenda par rapport à cette session 
        """
        for local_retval in MYSY_GV.dbname['session_formation_sequence'].find({'session_id': str(diction['session_id']),
                            'partner_owner_recid': str(my_partner['recid']),}):


            deleted_data_agenda = MYSY_GV.dbname['agenda'].delete_many({'sequence_session_id': str(local_retval['_id']),
                                'partner_owner_recid': str(my_partner['recid']), })

            deleted_data_affectation =  MYSY_GV.dbname['session_formation_sequence_affectation'].delete_many({'sequence_session_id': str(local_retval['_id']),
                                'partner_owner_recid': str(my_partner['recid']),})


        deleted_data_sequence = MYSY_GV.dbname['session_formation_sequence'].delete_many({'session_id': str(diction['session_id']),
                            'partner_owner_recid': str(my_partner['recid']),})

        cpt = 10

        nb_sequence = 0

        for single_date in mycommon.daterange(date_debut_session, date_fin_session):
            #print(single_date.strftime("%Y-%m-%d"))
            #print(single_date.strftime("%A"))

            #print(" Les date off sont : ", is_existe_valide_journee_model_data['date_off'])
            date_jour = str(single_date.strftime("%Y-%m-%d"))
            jour_name = single_date.strftime("%A")

            # Recuperation des sequences associées à jour_name
            jours_name_list_sequence = is_existe_valide_journee_model_data[jour_name]["tab_sequence"]

            #print(" ### les sequences du  ", jour_name, " sont ", jours_name_list_sequence)
            # Pour chaque sequence de la journée
            if (date_jour not in is_existe_valide_journee_model_data['date_off']):
                for local_val in jours_name_list_sequence :

                        sequence_data = {}
                        sequence_data['token'] = diction['token']
                        sequence_data['session_id'] = diction['session_id']
                        sequence_data['sequence_title'] = "Seq_Auto_" + str(cpt)
                        sequence_data['sequence_start'] = str(single_date.strftime("%d/%m/%Y")) + " " + str(
                            local_val['heure_debut']).strip()
                        sequence_data['sequence_end'] = str(single_date.strftime("%d/%m/%Y")) + " " + str(
                            local_val['heure_fin']).strip()

                        #print(" ### sequence_data = ", sequence_data)

                        local_status, local_val = Add_Session_Sequence(sequence_data)

                        if (local_status is False):
                            mycommon.myprint(
                                str(inspect.stack()[0][3]) + " WARNING : " + str(local_val))
                        else:
                            nb_sequence = nb_sequence +1

                        cpt = cpt + 1





        return True, str(nb_sequence)+" séquence(s) automatiquement créée(s) "

    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible de créer automatiquement  les séquences "





"""
Mise à jour d'une sequence
"""

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

        """
        Verification des input acceptés
        """
        field_list = ['token', '_id', 'session_id', 'sequence_title', 'sequence_start', 'sequence_end', ]

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

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', '_id', 'session_id', 'sequence_title', 'sequence_start', 'sequence_end', ]

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

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

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


        # Verification de l'existence d'une sequence à mettre à jour
        is_existe_valide_session_sequence_id =  MYSY_GV.dbname["session_formation_sequence"].count_documents({'_id':ObjectId(str(diction['_id'])),
                                                                                                                        'partner_owner_recid':str(my_partner['recid']),
                                                                                                                        'valide':'1',
                                                                                                              'locked':'0'})

        if (is_existe_valide_session_sequence_id <= 0):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - L'identifiant de la séquence n'est pas valide ")
            return False, " L'identifiant de la séquence n'est pas valide "


        # Verification de l'existence et de la session
        is_existe_valide_session_id = MYSY_GV.dbname["session_formation"].count_documents({'_id':ObjectId(str(diction['session_id'])),
                                                                                                                        'partner_owner_recid':str(my_partner['recid']),
                                                                                                                        'valide':'1'})

        if( is_existe_valide_session_id <= 0):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - L'identifiant de la session n'est pas valide ")
            return False, "L'identifiant de la session n'est pas valide "

        # Verifier qu'il n'y a pas de chevauchement de date avec une autre sequence de la meme session.
        date_debut_seq = ""
        if ("sequence_start" in diction.keys()):
            if diction['sequence_start']:
                date_debut_seq = str(diction['sequence_start'])
                local_status = mycommon.CheckisDate_Hours(date_debut_seq)
                if (local_status is False):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " La date de debut de séquence " + str(
                            date_debut_seq) + " n'est pas au format 'jj/mm/aaaa hh:mm' ")
                    return False, " La date de debut de séquence " + str(
                        date_debut_seq) + " n'est pas au format 'jj/mm/aaaa hh:mm'"

        date_fin_seq = ""
        if ("sequence_end" in diction.keys()):
            if diction['sequence_end']:
                date_fin_seq = str(diction['sequence_end'])
                local_status = mycommon.CheckisDate_Hours(date_fin_seq)
                if (local_status is False):
                    mycommon.myprint(
                        str(inspect.stack()[0][
                                3]) + " La date de fin de séquence " + str(
                            date_fin_seq) + " n'est pas au format 'jj/mm/aaaa hh:mm' ")
                    return False, " La date de fin de séquence " + str(
                        date_fin_seq) + " n'est pas au format 'jj/mm/aaaa hh:mm'"

        if (datetime.strptime(str(date_debut_seq), '%d/%m/%Y %H:%M') >= datetime.strptime(str(date_fin_seq),
                                                                                          '%d/%m/%Y %H:%M')):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " La date de fin de séquence " + str(
                    date_fin_seq) + " doit être postérieure à la date de début de séquence " + str(
                    date_debut_seq) + " ")
            return False, " La date de fin de séquence " + str(
                date_fin_seq) + " doit être postérieure à la date de début de séquence " + str(date_debut_seq) + " "


        for retVal in MYSY_GV.dbname['session_formation_sequence'].find({'session_id': str(diction['session_id']),
                                                                         'partner_owner_recid': str(
                                                                             my_partner['recid']),
                                                                         'valide': '1',
                                                                         'locked': '0',
                                                                         '_id': {'$ne': ObjectId(
                                                                             str(diction['_id']))}
                                                                         }):



            New_retVal_start_date = datetime.strptime(str(retVal['sequence_start']), '%d/%m/%Y %H:%M').strftime(
                "%d/%m/%Y %H:%M")
            New_retVal_end_date = datetime.strptime(str(retVal['sequence_end']), '%d/%m/%Y %H:%M').strftime(
                "%d/%m/%Y %H:%M")


            if (datetime.strptime(str(New_retVal_start_date), '%d/%m/%Y %H:%M') <= datetime.strptime(
                    str(date_debut_seq), '%d/%m/%Y %H:%M') and
                    datetime.strptime(str(New_retVal_end_date), '%d/%m/%Y %H:%M') >= datetime.strptime(
                        str(date_debut_seq), '%d/%m/%Y %H:%M')):
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " La date de debut de séquence" + str(
                        date_debut_seq) + " chevauche une autre séquence ")
                return False, " La date de debut de séquence" + str(
                    date_debut_seq) + " chevauche une autre séquence"

            if (datetime.strptime(str(New_retVal_start_date), '%d/%m/%Y %H:%M') <= datetime.strptime(
                    str(date_fin_seq), '%d/%m/%Y %H:%M') and
                    datetime.strptime(str(New_retVal_end_date), '%d/%m/%Y %H:%M') >= datetime.strptime(
                        str(date_fin_seq), '%d/%m/%Y %H:%M')):
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " La date de fin de séquence" + str(
                        date_debut_seq) + " chevauche une autre séquence ")
                return False, " La date de fin de séquence" + str(
                    date_debut_seq) + " chevauche une autre séquence"

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

        update_data = {}
        update_data['session_id'] = str(diction['session_id'])
        update_data['sequence_title'] = sequence_title
        update_data['sequence_start'] = date_debut_seq
        update_data['sequence_end'] = date_fin_seq
        update_data['valide'] = "1"
        update_data['locked'] = "0"
        update_data['date_update'] = str(datetime.now())
        update_data['update_by'] = str(my_partner['_id'])

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

        return True, " La séquence a été correctement mise à jour"

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



"""
Recuperer la liste des sequence d'une formation 
"""
def Get_Session_Sequence_List(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', 'session_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', 'session_id']
        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
                return False, " Les informations fournies sont incorrectes",

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

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

        RetObject = []
        val_tmp = 1
        for New_retVal in MYSY_GV.dbname['session_formation_sequence'].find({'session_id':str(diction['session_id']),
            'partner_owner_recid':str(my_partner['recid']), 'valide':'1', 'locked':'0'}):

            user = New_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 séquences de la session "


"""
Recuperer les données d'une sequence donnée
"""
def Get_Given_Session_Sequence(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

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

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

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

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

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

        RetObject = []
        val_tmp = 1
        for New_retVal in MYSY_GV.dbname['session_formation_sequence'].find({'_id':ObjectId(str(diction['_id'])),
            'partner_owner_recid':str(my_partner['recid']), 'valide':'1', 'locked':'0'}):

            user = New_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 les données de la séquence"



"""
Supprimer une sequence donnée
"""
def Delete_Given_Session_Sequence(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

        # Verifier si la sequence est valide
        is_existe_valide_session_sequence_id = MYSY_GV.dbname["session_formation_sequence"].count_documents(
            {'_id': ObjectId(str(diction['_id'])),
             'partner_owner_recid': str(my_partner['recid']),
             'valide': '1',
             'locked': '0'})

        if (is_existe_valide_session_sequence_id <= 0):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - L'identifiant de la séquence n'est pas valide ")
            return False, " L'identifiant de la séquence n'est pas valide "

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


        """
        Apres la suppression de la sequence, on supprime les eventuels reservations dans les agenda pour tout event rattaché à cette sequence
        """
        deleted_data_qry = {'sequence_session_id':str(diction['_id']),
                                                             'partner_owner_recid': str(my_partner['recid']),}

        #print(" ### deleted_data_qry = ", deleted_data_qry)

        deleted_data = MYSY_GV.dbname['agenda'].delete_many(deleted_data_qry)


        return True,  "La sequence a été supprimée "

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


"""
Supprimer une sequence donnée en mass
"""
def Delete_Given_Session_Sequence_Mass(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

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

        tab_id = ""
        if ("tab_id" in diction.keys()):
            if diction['tab_id']:
                tab_id = str(diction['tab_id']).split(",")

        nb_sequence = 0
        for my_id in tab_id:
            my_seq_data = {}
            my_seq_data['token'] =  diction['token']
            my_seq_data['_id'] = str(my_id)

            local_status, local_retval = Delete_Given_Session_Sequence(my_seq_data)
            if (local_status is False):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - WARNING . " + str(local_retval))

            else:
                nb_sequence = nb_sequence + 1

        return True, str(nb_sequence)+" séquence(s) supprimée(s) "

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



"""
Affectation d'une ressource (humaine ou materielle) a une sequence
"""
def Add_Sequence_Affectation_Ressource_Poste(diction):
    try:

        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', "sequence_session_id", "poste",  "comment", 'related_target_collection', 'related_target_collection_id']

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

        """
        Verification des champs obligatoires
        """

        field_list_obligatoire = ['token', 'sequence_session_id', "poste",  ]

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

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


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

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

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

        # Verifier que la sequence  existe bien
        sequence_session_existe_count = MYSY_GV.dbname['session_formation_sequence'].count_documents({'_id':ObjectId(str(sequence_session_id)), 'partner_owner_recid':str(partner_recid),
                                                                                     'valide':'1', 'locked':'0'})

        if( sequence_session_existe_count <= 0 ) :
            mycommon.myprint(str(inspect.stack()[0][3]) + " - La sequence est  invalide ")
            return False, " La sequence est  invalide "

        if (sequence_session_existe_count > 1):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Sequence incohérente. il a plusieurs sequences avec le meme id ")
            return False, "  Sequence incohérente. il a plusieurs sequences avec le meme id  "

        sequence_session_existe_data = MYSY_GV.dbname['session_formation_sequence'].find_one(
            {'_id': ObjectId(str(sequence_session_id)), 'partner_owner_recid': str(partner_recid),
             'valide': '1', 'locked': '0'})

        qry_la = {'_id': ObjectId(str(sequence_session_existe_data['session_id'])), 'partner_owner_recid': str(partner_recid),
             'valide': '1'}



        session_data = MYSY_GV.dbname['session_formation'].find_one(
            {'_id': ObjectId(str(sequence_session_existe_data['session_id'])), 'partner_owner_recid': str(partner_recid),
             'valide': '1'})


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

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


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



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

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


        my_data = {}

        my_data['partner_owner_recid'] = str(partner_recid)
        my_data['poste'] = str(poste)
        my_data['related_target_collection_id'] = str(related_target_collection_id)
        my_data['related_target_collection'] = str(related_target_collection)
        if( "comment" in diction.keys() ):
            my_data['comment'] = str(diction['comment'])
        else:
            my_data['comment'] = ""
        my_data['sequence_session_id'] = str(diction['sequence_session_id'])


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

        inserted_data = MYSY_GV.dbname['session_formation_sequence_affectation'].insert_one(my_data)
        if( inserted_data is None):
            return False," Impossible d'affecter la ressource à la sequence (2)"

        print(" ### inserted_data = ", inserted_data)


        """
        A présent que la sequence est créée, creation de l'event dans l'agenda de la ressource
        """

        my_class_data = MYSY_GV.dbname['myclass'].find_one({'internal_url':str(session_data['class_internal_url']),
                                                            'partner_owner_recid':str(session_data['partner_owner_recid']),
                                                            'valide':'1'})

        class_title = ""
        if( my_class_data and "title" in my_class_data.keys()):
            class_title = my_class_data['title']

        data_agenda = {}
        data_agenda['related_collection'] = str(related_target_collection)
        data_agenda['related_collection_recid'] = str(related_target_collection_id)
        data_agenda['partner_owner_recid'] = str(partner_recid)
        data_agenda['event_title'] = str(class_title)

        data_agenda['session_formation_sequence_affectation_id'] = str(inserted_data.inserted_id)

        data_agenda['comment'] = str(session_data['code_session'])

        data_agenda['event_start'] = datetime.strptime(str(sequence_session_existe_data['sequence_start']), '%d/%m/%Y %H:%M').isoformat()
        data_agenda['event_end'] = datetime.strptime(str(sequence_session_existe_data['sequence_end']), '%d/%m/%Y %H:%M').isoformat()
        data_agenda['valide'] = "1"
        data_agenda['locked'] = "0"
        data_agenda['event_type'] = "planning"
        data_agenda['sequence_session_id'] = str(sequence_session_existe_data['_id'])
        data_agenda['update_by'] = str(my_partner_data['_id'])

        #print(" #### data_agenda to add = ", data_agenda)

        MYSY_GV.dbname['agenda'].insert_one(data_agenda)


        return True, " La sequence a bien été affectée au poste"

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



"""
Affectation d'une ressource (humaine ou materielle) en masse à plusieurs sequence 
"""
def Add_Sequence_Affectation_Ressource_Poste_Mass(diction):
    try:

        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', "tab_sequence_session_id", "poste",  "comment", 'related_target_collection', 'related_target_collection_id']

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

        """
        Verification des champs obligatoires
        """

        field_list_obligatoire = ['token', 'tab_sequence_session_id', "poste",  ]

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

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



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

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

        tab_sequence_session_id = ""
        if ("tab_sequence_session_id" in diction.keys()):
            if diction['tab_sequence_session_id']:
                tab_sequence_session_id = str(diction['tab_sequence_session_id']).split(",")

        # Verifier que la sequence  existe bien
        for sequence_session_id in tab_sequence_session_id :
            sequence_session_existe_count = MYSY_GV.dbname['session_formation_sequence'].count_documents({'_id':ObjectId(str(sequence_session_id)), 'partner_owner_recid':str(partner_recid),
                                                                                         'valide':'1', 'locked':'0'})

            if( sequence_session_existe_count <= 0 ) :
                mycommon.myprint(str(inspect.stack()[0][3]) + " - La sequence est  invalide ")
                return False, " La sequence est  invalide "

            if (sequence_session_existe_count > 1):
                mycommon.myprint(str(inspect.stack()[0][3]) + " - Sequence incohérente. il a plusieurs sequences avec le meme id ")
                return False, "  Sequence incohérente. il a plusieurs sequences avec le meme id  "

        # Vu que toutes les sequences sont valides, on fait la mise à jour
        for sequence_session_id in tab_sequence_session_id:
            my_ressource_seq_data = {}

            my_ressource_seq_data['token'] = diction['token']
            my_ressource_seq_data['sequence_session_id'] = sequence_session_id
            if( "poste" in diction.keys() ):
                my_ressource_seq_data['poste'] = diction['poste']
            else:
                my_ressource_seq_data['poste'] = ""

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

            if ("related_target_collection" in diction.keys()):
                my_ressource_seq_data['related_target_collection'] = diction['related_target_collection']
            else:
                my_ressource_seq_data['related_target_collection'] = ""

            if ("related_target_collection_id" in diction.keys()):
                my_ressource_seq_data['related_target_collection_id'] = diction['related_target_collection_id']
            else:
                my_ressource_seq_data['related_target_collection_id'] = ""



            local_status, local_retval = Add_Sequence_Affectation_Ressource_Poste(my_ressource_seq_data)
            if(local_status is False ):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - WARNING . "+str(local_retval))




        return True, " Les ressources ont bien été ajoutées en masse"

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



"""
Mettre à jour une affectation de ressource
"""
def Update_Sequence_Affectation_Ressource_Poste(diction):
    try:

        diction = mycommon.strip_dictionary(diction)

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

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

        """
        Verification des champs obligatoires
        """

        field_list_obligatoire = ['token', '_id'  ]

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

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



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

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


        # Verifier l'existence et la validité de la sequence à modifier
        sequence_session_id = ""
        if ("sequence_session_id" in diction.keys()):
            if diction['sequence_session_id']:
                sequence_session_id = diction['sequence_session_id']

        # Verifier que l'affetation existe bien
        affectation_sequence_session_existe_count = MYSY_GV.dbname['session_formation_sequence_affectation'].count_documents({'_id':ObjectId(str(diction['_id'])), 'partner_owner_recid':str(partner_recid),
                                                                                     'valide':'1', 'locked':'0'})

        if( affectation_sequence_session_existe_count <= 0 ) :
            mycommon.myprint(str(inspect.stack()[0][3]) + " - L'affectation est  invalide ")
            return False, " L'affectation est  invalide "

        if (affectation_sequence_session_existe_count > 1):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - L'affectation est incohérente. il a plusieurs affectations avec le meme id ")
            return False, " L'affectation est incohérente. il a plusieurs affectations avec le meme id  "


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

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


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



        update_data = {}

        update_data['partner_owner_recid'] = str(partner_recid)
        update_data['poste'] = str(poste)
        update_data['related_target_collection_id'] = str(related_target_collection_id)
        update_data['related_target_collection'] = str(related_target_collection)
        update_data['comment'] = str(diction['comment'])
        update_data['sequence_session_id'] = str(diction['sequence_session_id'])


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

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

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



        return True, " L'affectation a bien été mise à jour"

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


"""
Supprimer une affectation de ressource à une sequence
"""
def Delete_Sequence_Affectation_Ressource_Poste(diction):
    try:

        diction = mycommon.strip_dictionary(diction)

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

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

        """
        Verification des champs obligatoires
        """

        field_list_obligatoire = ['token', '_id' ]

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

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



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

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


        # Verifier l'existence et la validité de la sequence à modifier
        sequence_session_id = ""
        if ("sequence_session_id" in diction.keys()):
            if diction['sequence_session_id']:
                sequence_session_id = diction['sequence_session_id']

        # Verifier que l'affetation existe bien
        affectation_sequence_session_existe_count = MYSY_GV.dbname['session_formation_sequence_affectation'].count_documents({'_id':ObjectId(str(diction['_id'])), 'partner_owner_recid':str(partner_recid),
                                                                                     'valide':'1', 'locked':'0'})

        if( affectation_sequence_session_existe_count <= 0 ) :
            mycommon.myprint(str(inspect.stack()[0][3]) + " - L'affectation est  invalide ")
            return False, " L'affectation est  invalide "

        if (affectation_sequence_session_existe_count > 1):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - L'affectation est incohérente. il a plusieurs affectations avec le meme id ")
            return False, " L'affectation est incohérente. il a plusieurs affectations avec le meme id  "

        affectation_sequence_session_data = MYSY_GV.dbname[
            'session_formation_sequence_affectation'].find_one(
            {'_id': ObjectId(str(diction['_id'])), 'partner_owner_recid': str(partner_recid),
             'valide': '1', 'locked': '0'})



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

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

        """
        A present que la ressource a été supprimée, il faut egalement supprimer la reservation de la ressource
        """
        qry_for_delete = {'sequence_session_id':str(affectation_sequence_session_data['sequence_session_id']), 'partner_owner_recid': str(affectation_sequence_session_data['partner_owner_recid']),
                                                  'related_collection_recid':str(affectation_sequence_session_data['related_target_collection_id']),
                                                  'related_collection':str(affectation_sequence_session_data['related_target_collection']),
                                                'session_formation_sequence_affectation_id': str(affectation_sequence_session_data['_id'])}

        print(" #### qry_for_delete = ", qry_for_delete)

        MYSY_GV.dbname['agenda'].delete_many(qry_for_delete)


        return True, " L'affectation a bien été supprimée"

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



"""
Recuperer la liste des affectations de ressource à une sequence
"""
def Get_List_Sequence_Ressource_Affectation(diction):
    try:
        field_list_obligatoire = [ 'token', 'sequence_session_id', ]

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

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



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

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



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


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

        RetObject = []
        val_tmp = 1

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

            related_target_collection_id_nom = ""
            related_target_collection_object = ""

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

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

                        if(affectation_target_data is not None):
                            related_target_collection_id_nom = affectation_target_data["nom"] +" "+affectation_target_data["prenom"]
                            related_target_collection_object = "Ressource Humaine"

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

                        if (affectation_target_data is not None):
                            related_target_collection_id_nom = affectation_target_data["nom"]
                            related_target_collection_object = "Ressource Materielle"




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

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

        return True, RetObject

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