"""
Ce fichier permet de gerer les groupes d'inscrit.
Par exemple dans les formations initiales, les inscrits à une formation
sont regroupés en
- groupe de TD
- groupe de TP
- groupe de Projet
- etc.

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

"""
Ajout d'un groupe.
Un groupe est defini par les 
- Code
- Nom
- Description
- Type de groupe (liste : TD, TP, etc)
- class_id
- session_id

La collection est : groupe_inscription
"""

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

        """
        Verification des input acceptés
        """
        field_list = ['token', 'code', 'nom', 'description', 'type_groupe_code', 'class_id', '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'est pas autorisé")
                return False, " Les informations fournies sont incorrectes"

        """
        Verification des champs obligatoires
        """
        field_list_obligatoire = ['token', 'code',  'type_groupe_code', 'class_id', '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


        # Verifier que ce code n'existe pas déjà
        is_existe_class_metier = MYSY_GV.dbname['groupe_inscription'].count_documents({'code':str(diction['code']),
                                                                                                       'valide':'1',
                                                                                                       'partner_owner_recid':str(my_partner['recid'])})


        if( is_existe_class_metier > 0 ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " Un groupe avec le code '" + str(diction['code']) + "' existe déjà ")
            return False, " Un groupe avec le code '" + str(diction['code']) + "' existe déjà  "


        """
        Verifier que le class_id exist et est valide
        """
        is_class_id_count = MYSY_GV.dbname['myclass'].count_documents({'_id':ObjectId(str(diction['class_id'])),
                                                                                      'valide':'1',
                                                                                      'locked':'0',
                                                                       'partner_owner_recid':str(my_partner['recid'])})

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

        """
        Verifier que la session_id exist et est valide
        """
        is_session_id_count = MYSY_GV.dbname['session_formation'].count_documents({'_id': ObjectId(str(diction['session_id'])),
                                                                       'valide': '1',
                                                                      'partner_owner_recid':str(my_partner['recid'])})

        if (is_session_id_count != 1):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " L'identifiant de la session/classe est invalide  valide ")
            return False, " L'identifiant de la session/classe est invalide  valide "

        """
                Verifier que la type_groupe exist et est valide
                """
        is_type_groupe_code_count = MYSY_GV.dbname['groupe_inscription_type'].count_documents(
            {'code': str(diction['type_groupe_code']),
             'valide': '1',
             'partner_owner_recid':'default'})

        if (is_type_groupe_code_count != 1):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " Le type de groupe est invalide  valide ")
            return False, " Le type de groupe est invalide  valide  "

        new_data = diction
        del diction['token']

        # Initialisation des champs non envoyés à vide
        for val in field_list:
            if val not in diction.keys():
                new_data[str(val)] = ""

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

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

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


        return True, " Le groupe a été correctement ajouté "

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



"""
Mise à jour d'un groupe 
"""

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

        """
        Verification des input acceptés
        """
        field_list =  ['token', '_id', 'code', 'nom', 'description', 'type_groupe_code', 'class_id', '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'est pas autorisé")
                return False, " Les informations fournies sont incorrectes"

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

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

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

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

        new_data = diction

        # Verifier que le groupe existe et est valide
        is_existe_groupe = MYSY_GV.dbname['groupe_inscription'].count_documents(
            {'_id': ObjectId(str(diction['_id'])),
             'valide': '1',
             'partner_owner_recid': str(my_partner['recid'])})

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


        qry = {'code':str(diction['code']),
                                                                                                           'valide':'1',
                                                                                                           'partner_owner_recid':str(my_partner['recid']),
                                                                                          '_id': {'$ne': ObjectId(str(diction['_id']))},

                                                                                                 }

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

        # Verifier que ce code n'existe pas déjà pour un autre groupe
        if( "code" in diction.keys() ):
            is_existe_class_metier = MYSY_GV.dbname['groupe_inscription'].count_documents({'code':str(diction['code']),
                                                                                                           'valide':'1',
                                                                                                           'partner_owner_recid':str(my_partner['recid']),
                                                                                          '_id': {'$ne': ObjectId(str(diction['_id']))},

                                                                                                 })


            if( is_existe_class_metier > 0 ):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " Un groupe avec le code '" + str(diction['code']) + "' existe déjà ")
                return False, " Un groupe avec le code '" + str(diction['code']) + "' existe déjà  "


        """
        Verifier que le class_id exist et est valide
        """
        if ("class_id" in diction.keys()):
            is_class_id_count = MYSY_GV.dbname['myclass'].count_documents({'_id':ObjectId(str(diction['class_id'])),
                                                                                          'valide':'1',
                                                                                          'locked':'0',
                                                                           'partner_owner_recid':str(my_partner['recid'])})

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

        """
        Verifier que la session_id exist et est valide
        """
        if ("session_id" in diction.keys()):
            is_session_id_count = MYSY_GV.dbname['session_formation'].count_documents({'_id': ObjectId(str(diction['session_id'])),
                                                                           'valide': '1',
                                                                          'partner_owner_recid':str(my_partner['recid'])})

            if (is_session_id_count != 1):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " L'identifiant de la session/classe est invalide  valide ")
                return False, " L'identifiant de la session/classe est invalide  valide "


        """
                Verifier que la type_groupe exist et est valide
                """
        if ("type_groupe_code" in diction.keys()):
            is_type_groupe_code_count = MYSY_GV.dbname['groupe_inscription_type'].count_documents(
                {'code': str(diction['type_groupe_code']),
                 'valide': '1',
                 'partner_owner_recid':'default'})

            if (is_type_groupe_code_count != 1):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " Le type de groupe est invalide  valide ")
                return False, " Le type de groupe est invalide  valide  "




        local_id = str(diction['_id'])

        del diction['token']
        del diction['_id']


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

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

        result = MYSY_GV.dbname['groupe_inscription'].find_one_and_update(
            data_cle,
            {"$set": new_data},
            upsert=False,
            return_document=ReturnDocument.AFTER
        )

        if ("_id" not in result.keys()):
            mycommon.myprint(
                " Impossible de mettre à jour le groupe (2) ")
            return False, " Impossible de mettre à jour le groupe (2)  "

        return True, " Le groupe 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 groupe "


"""
Suppression d'un groupe
regles : 
Si la condition (_id) n'est pas utilisé dans les collection
- groupe_inscription_membre  (la liste des personnes apprenant a ce groupe. on utilise l'inscription_id)
"""

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

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

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

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

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

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

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


        # Verifier que la codition de paiement existe
        is_existe_groupe = MYSY_GV.dbname['groupe_inscription'].count_documents(
            {'_id': ObjectId(str(diction['_id'])),
             'valide': '1',
             'partner_owner_recid': str(my_partner['recid'])})

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


        """ 
        Verifier que le groupe n'est pas utilisé dans la collection 'groupe_inscription_membre' 
        """
        is_groupe_has_members = MYSY_GV.dbname['groupe_inscription_membre'].count_documents({'partner_owner_recid':my_partner['recid'],
                                                                                                       'valide':'1',
                                                                                                       'groupe_inscription_id':str(diction['_id'])})


        if( is_groupe_has_members > 0 ):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " Impossible de supprimer de le groupe. Ce groupe a "+str(is_groupe_has_members)+" membres ")
            return False, " Impossible de supprimer de le groupe. Ce groupe a "+str(is_groupe_has_members)+" membres.  "




        delete = MYSY_GV.dbname['groupe_inscription'].delete_one({'_id': ObjectId(str(diction['_id'])),
                                                      'partner_owner_recid': str(my_partner['recid']),
                                                     }, )



        return True, " Le groupe  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 groupe "



"""
Recuperer la liste des groupe d'un partenaire avec des filtre sur : 
- la session_id
- la class_id
- le type_groupe_code
"""
def Get_List_Groupe_Inscrit_With_Filter(diction):
    try:
        diction = mycommon.strip_dictionary(diction)

        """
        Verification des input acceptés
        """
        field_list = ['token', 'code', 'nom', 'type_groupe_code', 'class_external_code',
                      'code_session', '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', ]
        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_code = {}
        if ("code" in diction.keys()):
            filt_ref_interne = {
                'code': {'$regex': str(diction['code']), "$options": "i"}}

        filt_session_id_on_main_collection = {}
        if ("session_id" in diction.keys()):
            filt_session_id_on_main_collection = { 'session_id': str(diction['session_id'])}


        filt_session_id = {}
        list_session_id = []
        if ("code_session" in diction.keys()):
            filt_code_session = {'code_session': {'$regex': str(diction['code_session']), "$options": "i"}}

            qry_list_session_id = {"$and": [{'code_session': {'$regex': str(diction['code_session']), "$options": "i"}},
                                            {'partner_owner_recid': str(my_partner['recid'])}]}

            # print(" ### qry_list_session_id aa = ", qry_list_session_id)
            list_session_id_count = MYSY_GV.dbname['session_formation'].count_documents(qry_list_session_id)

            if (list_session_id_count <= 0):
                # Aucune session
                return True, []

            for val in MYSY_GV.dbname['session_formation'].find(qry_list_session_id):
                list_session_id.append(str(val['_id']))

            # print(" ### liste des Id des sessions eligible list_session_id = ", list_session_id)
            filt_session_id = {'session_id': {'$in': list_session_id, }}


        filt_class_id = {}
        list_class_id = []
        if ("class_external_code" in diction.keys()):
            filt_class_title = {'external_code': {'$regex': str(diction['class_external_code']), "$options": "i"}}

            qry_list_class_id = {
                "$and": [{'external_code': {'$regex': str(diction['class_external_code']), "$options": "i"}},
                         {'partner_owner_recid': str(my_partner['recid'])}]}

            print(" ### qry_list_class_id aa = ", qry_list_class_id)
            list_class_id_count = MYSY_GV.dbname['myclass'].count_documents(qry_list_class_id)

            if (list_class_id_count <= 0):
                # Aucune session
                return True, []

            for val in MYSY_GV.dbname['myclass'].find(qry_list_class_id):
                list_class_id.append(str(val['_id']))

            # print(" ### liste des Id des sessions eligible list_session_id = ", list_session_id)
            filt_class_id = {'class_id': {'$in': list_class_id, }}



        RetObject = []
        val_tmp = 0

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

        print("### Get_List_Groupe_Inscrit_With_Filter find_qry = ", find_qry)

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

            if ("class_id" not in retval.keys()):
                user['class_title'] = ""
                user['class_internal_url'] = ""
            else:
                my_class_data = MYSY_GV.dbname['myclass'].find_one({"_id":ObjectId(str(retval['class_id'])),
                                                                            'valide':'1',
                                                                            'locked':'0'})

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

                if (my_class_data and "internal_url" in my_class_data.keys()):
                    user['class_internal_url'] = my_class_data['internal_url']

            if ("session_id" not in retval.keys()):
                user['session_code_session'] = ""
            else:
                my_session_formation_data = MYSY_GV.dbname['session_formation'].find_one({"_id": ObjectId(str(retval['session_id'])),
                                                                    'valide': '1',})

                if (my_session_formation_data and "code_session" in my_session_formation_data.keys()):
                    user['session_code_session'] = my_session_formation_data['code_session']


            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 metiers de formation "


"""
Recuperer les données d'un groupe donné
"""
def Get_Given_Groupe_Inscrit_Data(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['valide'] = "1"
        data_cle['locked'] = "0"
        data_cle['_id'] = ObjectId(str(diction['_id']))


        RetObject = []
        val_tmp = 0

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

        return True, RetObject


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


"""
Recuperer la liste des membres d'un groupe
"""

def Get_Given_Groupe_Inscrit_With_Membres(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['valide'] = "1"
        data_cle['locked'] = "0"
        data_cle['_id'] = ObjectId(str(diction['_id']))


        RetObject = []
        val_tmp = 0

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

            user['membres'] = MYSY_GV.dbname['groupe_inscription_membre'].find({'groupe_inscription_id':str(retval['_id']),
                                                                                'valide':'1',
                                                                                'locked':'0',
                                                                                'partner_owner_recid':str(my_partner['recid'])})

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



"""
Cette fonction permet d'inscrire des 'inscrit_id' a un groupe
"""

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

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

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

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

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

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

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

        new_data = diction

        # Verifier que le groupe existe et est valide

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



        is_existe_groupe = MYSY_GV.dbname['groupe_inscription'].count_documents(
            {'_id': ObjectId(str(diction['_id'])),
             'valide': '1',
             'partner_owner_recid': str(my_partner['recid'])})

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


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

        tab_inscriptions_ids_splited = str(tab_inscriptions_ids).split(",")
        # Controle de validité des inscriptions
        for my_inscription in tab_inscriptions_ids_splited:
            # Verifier que l'inscription est valide
            my_inscription_is_valide = MYSY_GV.dbname['inscription'].count_documents(
                {'_id': ObjectId(str(my_inscription)), 'status': '1',
                 'partner_owner_recid': str(my_partner['recid'])})

            if (my_inscription_is_valide != 1):
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " L'inscription_id '" + my_inscription + "' est invalide ")
                return False, "  L'inscription_id '" + my_inscription + "' est invalide "

        cpt  = 0
        for my_inscription in tab_inscriptions_ids_splited:
            new_data = {}
            new_data['groupe_inscription_id'] = str(diction['_id'])
            new_data['inscription_id'] = str(my_inscription)

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

            data_cle = {}
            data_cle['partner_owner_recid'] = str(my_partner['recid'])
            data_cle['groupe_inscription_id'] = str(diction['_id'])
            data_cle['inscription_id'] = str(my_inscription)
            data_cle['valide'] = "1"
            data_cle['locked'] = "0"

            result = MYSY_GV.dbname['groupe_inscription_membre'].find_one_and_update(
                data_cle,
                {"$set": new_data},
                upsert=True,
                return_document=ReturnDocument.AFTER
            )

            if (result is None or "_id" not in result.keys()):
                mycommon.myprint(
                    " Impossible d'inscrire les personnes au groupe (2) ")
                return False, "  Impossible d'inscrire les personnes au groupe (2) "


            cpt = cpt + 1



        return True, str(cpt)+ " Membre(s) inscrit(s)"


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


"""
Recuperer les membres d'un groupe
"""
def Get_Given_Groupe_Membres(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 = 0

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

            local_new_dict = {}
            local_new_dict['token'] = diction['token']
            local_new_dict['inscrit_id'] = retval['inscription_id']

            local_inscrit_data_status, local_inscrit_data_retval = mycommon.Get_Inscrit_And_Apprenant_Data(
                local_new_dict)
            if (local_inscrit_data_status is False):
                return local_inscrit_data_status, local_inscrit_data_retval

            nom = ""
            prenom = ""
            email = ""



            if ("inscrit_data" in local_inscrit_data_retval.keys()):
                user['inscrit_data'] = local_inscrit_data_retval['inscrit_data']

                nom = local_inscrit_data_retval['inscrit_data']['nom']
                prenom = local_inscrit_data_retval['inscrit_data']['prenom']
                email = local_inscrit_data_retval['inscrit_data']['email']


            if ("apprenant_data" in local_inscrit_data_retval.keys()):
                user['apprenant_data'] = local_inscrit_data_retval['apprenant_data']

                # Si on a un dossier apprenant, alors on écrase les variables ci-dessous
                nom = local_inscrit_data_retval['apprenant_data']['nom']
                prenom = local_inscrit_data_retval['apprenant_data']['prenom']
                email = local_inscrit_data_retval['apprenant_data']['email']


            user['nom'] = nom
            user['prenom'] = prenom
            user['email'] = email


            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 membres du groupe  "






"""
Cette fonction permet de supprimer des inscrits à un groupe (membre d'un groupe)
"""

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

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

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

        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

        new_data = diction

        # Verifier que le groupe existe et est valide
        is_existe_groupe = MYSY_GV.dbname['groupe_inscription'].count_documents(
            {'_id': ObjectId(str(diction['groupe_inscription_id'])),
             'valide': '1',
             'partner_owner_recid': str(my_partner['recid'])})

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

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

        tab_inscriptions_ids_splited = str(tab_inscriptions_ids).split(",")

        tab_inscriptions_ids_splited_ObjectID = []
        for tmp in tab_inscriptions_ids_splited :
            tab_inscriptions_ids_splited_ObjectID.append(ObjectId(str(tmp)))

        qery_delete = {'_id': {'$in': tab_inscriptions_ids_splited_ObjectID},
                       'groupe_inscription_id':str(diction['groupe_inscription_id']),
                       'partner_owner_recid': str(my_partner['recid']),
                      'locked': '0'}

        #print(" ### qery_delete =  ", qery_delete)

        delete = MYSY_GV.dbname['groupe_inscription_membre'].delete_many(qery_delete )

        return True, str(delete.deleted_count) + " Membre(s) désinscrit(s)"


    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
        return False, " Impossible désinscrire les personnes au groupe  "


"""
Recuperer les données d'un groupe donné
"""
def Get_Type_Groupe_Apprenant(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['valide'] = "1"
        data_cle['locked'] = "0"



        RetObject = []
        val_tmp = 0

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

        return True, RetObject


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



"""
Fonction qui permet d'exporter les membres d'un groupe dans un fichier excel
"""

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

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

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

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

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

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

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

        """
        Verifier que le group  est valide
        """
        is_groupe_valide = MYSY_GV.dbname['groupe_inscription'].count_documents(
            {"_id": ObjectId(str(diction['_id'])),
             'valide': '1',
             'locked': '0',
             'partner_owner_recid': str(my_partner['recid'])})

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

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

        RetObject = []
        val_tmp = 0

        ts = datetime.now().timestamp()
        ts = str(ts).replace(".", "").replace(",", "")[-5:]

        orig_file_name = "Export_Groupe_Membres_" + str(ts) + ".xlsx"
        outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)

        tab_exported_fields_header = ["formation", "classe", "Groupe_code","Groupe_Nom", "type_groupe_code", "nom_apprenant",
                                      "prenom_apprenant", "email_apprenant", ]


        # Create a workbook and add a worksheet.
        workbook = xlsxwriter.Workbook(outputFilename)
        worksheet = workbook.add_worksheet()

        nb_val = 0
        row = 0
        column = 0

        groupe_formation = ""
        groupe_code_session = ""

        # Recuperer les données de la formation
        class_data = MYSY_GV.dbname['myclass'].find_one({'_id': ObjectId(str(groupe_data['class_id'])),
                                                         'valide': '1', 'locked': '0',
                                                         'partner_owner_recid': str(my_partner['recid'])})

        if (class_data and "title" in class_data.keys()):
            groupe_formation = class_data['title']


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

        if (session_data and "code_session" in session_data.keys()):
            groupe_code_session = session_data['code_session']

        """
                Creation de l'entete du fichier excel
                """

        for header_item in tab_exported_fields_header:
            worksheet.write(row, column, header_item)
            column += 1

        """
        Creation des data du fichier excel
        """
        for retval in MYSY_GV.dbname['groupe_inscription_membre'].find(
                {'groupe_inscription_id': str(diction['_id']),
                 'valide': '1',
                 'locked': '0',
                 'partner_owner_recid': str(my_partner['recid']),
                 }):


            user = retval
            nom_apprenant = ""
            prenom_apprenant = ""
            email_apprenant = ""
            groupe = ""


            if ("inscription_id" in retval and retval['inscription_id']):
                # Recuprer les données de l'inscrit
                inscription_data = MYSY_GV.dbname['inscription'].find_one(
                    {'_id': ObjectId(str(retval['inscription_id']))},
                    {'_id': 1, 'apprenant_id': 1})

                apprenant_data = MYSY_GV.dbname['apprenant'].find_one(
                    {'_id': ObjectId(str(inscription_data['apprenant_id']))},
                    {'_id': 1, 'nom': 1, 'prenom': 1, 'email': 1})

                nom_apprenant = apprenant_data['nom']
                prenom_apprenant = apprenant_data['prenom']
                email_apprenant = apprenant_data['email']




            user['nom'] = nom_apprenant
            user['prenom'] = prenom_apprenant
            user['email'] = email_apprenant
            user['id'] = str(nb_val)
            if ("note" not in retval.keys()):
                user['note'] = "-1"

            nb_val = nb_val + 1

            column = 0
            row = row + 1

            # Champ : formation
            worksheet.write(row, column, groupe_formation)
            column += 1

            # Champ : classe / code session
            worksheet.write(row, column, groupe_code_session)
            column += 1

            # Champ : groupe_code
            worksheet.write(row, column, str(groupe_data['code']))
            column += 1

            # Champ : Groupe Nom
            worksheet.write(row, column, str(groupe_data['nom']))
            column += 1

            # Champ : Groupe type_groupe_code
            worksheet.write(row, column, str(groupe_data['type_groupe_code']))
            column += 1


            # Champ : nom
            worksheet.write(row, column, user['nom'])
            column += 1

            # Champ : prenom
            worksheet.write(row, column, user['prenom'])
            column += 1

            # Champ : email
            worksheet.write(row, column, user['email'])
            column += 1



        workbook.close()
        if os.path.exists(outputFilename):
            # print(" ### ok os.path.exists(outputFilename) "+str(outputFilename))
            return True, send_file(outputFilename, as_attachment=True)


        return False, "Impossible de générer l'export  (2) "


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

