"""
Ce fichier/class gerer tout ce qui est relatif aux prix des formation
- aux discounts accordés par client/famille.
Concrètement, il répond aux questions suivantes :
•	Comment un éditeur de formation va proposer des prix spécifiques à un client / une famille / une entreprise.
•	Comment un client peut voir la liste des prix spécifiques qui sont accordées.

"""
import pymongo
from pymongo import MongoClient
import json
from bson import ObjectId
import re
from datetime import datetime
import prj_common as mycommon
import secrets
import inspect
import sys, os
import csv
import pandas as pd
from pymongo import ReturnDocument
import GlobalVariable as MYSY_GV
from math import isnan
import GlobalVariable as MYSY_GV
import ela_index_bdd_classes as eibdd
import email_mgt as email

def add_business_price(diction):
    try:

        '''
                # Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
                # Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
                # Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
                # field_list.
                '''
        field_list = ['token', 'client_recid', 'discount', 'date_du', 'date_au', 'class']

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

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

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

        # Recuperation du recid du partner
        mydata = {}
        mytoken = ""
        if ("token" in diction.keys()):
            if diction['token']:
                mytoken = diction['token']

        partner_recid = mycommon.get_parnter_recid_from_token(mytoken)
        if (partner_recid is False):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - Impossible de récupérer les donnees du partnaire ")
            return False, "Impossible de récupérer les donnees du partnaire "

        mydata['partner_recid'] = partner_recid

        discount = str(diction['discount']).strip()
        if (mycommon.IsFloat(discount) is False):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + "  Le montant de la reduction  est incorrecte ")
            return False, " Le montant de la reduction  est incorrecte "

        mydata['discount'] = discount

        date_du = str(diction['date_du']).strip()[0:10]
        date_au = str(diction['date_au']).strip()[0:10]


        is_date_du = mycommon.CheckisDate(date_du)
        is_date_au = mycommon.CheckisDate(date_au)

        if (is_date_du is False or is_date_au is False):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " - Impossible de créer le prix,  Les dates sont incorrectes. Le format attendu est jj/mm/aaaa ")
            return False, " Impossible de créer le prix,  Les dates sont incorrectes. Le format attendu est jj/mm/aaaa"

        if (datetime.strptime(str(date_du), '%d/%m/%Y') > datetime.strptime(
                str(date_au), '%d/%m/%Y')):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " - Impossible de créer le prix.  La date debut est postérieure à la date de fin " )

            return False, " Impossible de créer le prix.  La date debut est postérieure à la date de fin "


        mydata['date_du'] = date_du
        mydata['date_au'] = date_au

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

        client_recid = ""
        client_nom = ""
        if(  str(diction['client_recid']).strip() == "all"):
            client_recid = ""
            client_nom = "Tout client"
        else:
            client_recid = str(diction['client_recid']).strip()
            local_status, local_val = mycommon.get_partner_data_from_recid(client_recid)
            if(local_status is False ):
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " - Impossible de créer le prix,  Le client n'est pas valide ")
                return False, " Impossible de créer le prix,  Le client n'est pas valide "

            client_nom = local_val['nom']


        mydata['client_recid'] = client_recid
        mydata['client_nom'] = client_nom
        mydata['valide'] = "1"
        mydata['date_update'] = datetime.now().strftime("%d/%m/%Y")

        ret_val = MYSY_GV.dbname['business_prices'].insert_one(mydata)
        if (ret_val.acknowledged is None):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " - Impossible de créer le prix,  ")
            return False, " Impossible de créer le prix,  "



        return True, " Le prix a été correctement inséré"


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


def update_business_price(diction):
    try:
        '''
                        # Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
                        # Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
                        # Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
                        # field_list.
                        '''
        field_list = ['token', 'price_id', 'discount', 'date_du', 'date_au', 'class']

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

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

        # Recuperation du recid du partner
        mydata = {}
        mytoken = ""
        if ("token" in diction.keys()):
            if diction['token']:
                mytoken = diction['token']

        partner_recid = mycommon.get_parnter_recid_from_token(mytoken)
        if (partner_recid is False):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - Impossible de récupérer les donnees du partnaire ")
            return False, "Impossible de récupérer les donnees du partnaire "

        discount = str(diction['discount']).strip()
        if (mycommon.IsFloat(discount) is False):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + "  Le montant de la reduction  est incorrecte ")
            return False, " Le montant de la reduction  est incorrecte "

        mydata['discount'] = discount

        date_du = str(diction['date_du']).strip()[0:10]
        date_au = str(diction['date_au']).strip()[0:10]

        is_date_du = mycommon.CheckisDate(date_du)
        is_date_au = mycommon.CheckisDate(date_au)

        if (is_date_du is False or is_date_au is False):
            mycommon.myprint(
                str(inspect.stack()[0][
                        3]) + " - Impossible de créer le prix,  Les dates sont incorrectes ")
            return False, " Impossible de créer le prix,  Les dates sont incorrectes"

        mydata['date_du'] = date_du
        mydata['date_au'] = date_au
        mydata['date_update'] = datetime.now().strftime("%d/%m/%Y")

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


        ret_val = MYSY_GV.dbname['business_prices'].find_one_and_update(
            {'_id': ObjectId(str(str(diction['price_id']).strip())), },
            {"$set": mydata},
            upsert=False,
            return_document=ReturnDocument.AFTER
            )

        if ret_val is None or ret_val['_id'] is None:
            mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible de modifier le prix ")
            return False, " Impossible de modifier le prix "


        return True, "Le prix a été bien mis à jour"


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


def delete_business_price(diction):
    try:
        '''
                        # Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
                        # Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
                        # Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
                        # field_list.
                        '''
        field_list = ['token', 'price_id', ]

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

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

        # Recuperation du recid du partner
        mydata = {}
        mytoken = ""
        if ("token" in diction.keys()):
            if diction['token']:
                mytoken = diction['token']

        partner_recid = mycommon.get_parnter_recid_from_token(mytoken)
        if (partner_recid is False):
            mycommon.myprint(
                str(inspect.stack()[0][3]) + " - Impossible de récupérer les donnees du partnaire ")
            return False, "Impossible de récupérer les donnees du partnaire "

        mydata['date_update'] = datetime.now().strftime("%d/%m/%Y")
        mydata['valide'] = "0"

        ret_val = MYSY_GV.dbname['business_prices'].find_one_and_update(
            {'_id': ObjectId(str(str(diction['price_id']).strip())), },
            {"$set": mydata},
            upsert=False,
            return_document=ReturnDocument.AFTER
        )

        if ret_val is None or ret_val['_id'] is None:
            mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible de supprimer le prix ")
            return False, " Impossible de supprimer le prix "


        return True, "Le prix a été bien supprimer"

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



def recherche_business_price(diction):
    try:
        '''
                        # Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
                        # Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
                        # Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
                        # field_list.
                        '''
        field_list = ['token', 'client_recid', 'discount', 'date_du', 'date_au']

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

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

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

        # Recuperation du recid du partner
        mydata = {}
        mytoken = ""
        if ("token" in diction.keys()):
            if diction['token']:
                mytoken = diction['token']

        partner_recid = mycommon.get_parnter_recid_from_token(mytoken)
        if (partner_recid is False):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer les donnees du partnaire ")
            return False, "Impossible de récupérer les donnees du partnaire "

        client_recid = ""
        client_nom = ""
        if (str(diction['client_recid']).strip() == "all"):
            client_recid = ""
            client_nom = "Tout client"
        else:
            client_recid = str(diction['client_recid']).strip()
            local_status = mycommon.get_user_data_from_recid(client_recid)
            if (local_status is False):
                mycommon.myprint(
                    str(inspect.stack()[0][
                            3]) + " - Impossible de créer le prix,  Le client n'est pas valide ")
                return False, " Impossible de créer le prix,  Le client n'est pas valide "


        return True, "ok"


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

"""
Recuperation des prix client d'un partneaire
"""
def get_cust_prices_by_partner(diction):
    try:
        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]) + "  Impossible de récupérer les prix client,  Le champ  '" + val + "' n'existe pas ")
                return False, " Impossible de récupérer les prix client,  Le champ  '" + val + "' n'existe pas"

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

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - Impossible de récupérer les prix clients, La valeur '" + val + "' n'est pas presente dans liste")
                return False, " Impossible de récupérer les prix clients, La valeur '" + val + "' n'est pas presente dans liste"

        # recuperation des paramettre
        my_token = ""
        partner_recid = ""

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

        partner_recid = ""
        # Verification de la validité du token/mail dans le cas des user en mode connecté
        if (len(str(my_token)) > 0):
            retval = mycommon.check_partner_token_validity("", my_token)

            if retval is False:
                mycommon.myprint(str(inspect.stack()[0][3]) + " - La session de connexion n'est pas valide")
                return False, " Impossible de récupérer les factures"

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

        if (len(str(my_token)) <= 0):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Le token est vide")
            return False, " Impossible de récupérer les factures"

        RetObject = []
        coll_facture = MYSY_GV.dbname['business_prices']

        for retVal in coll_facture.find({'partner_recid':partner_recid, 'valide': '1'},

                                        )\
                .sort([("date_update", pymongo.DESCENDING), ]):
            user = retVal

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

        print(" liste prix du client = "+str(RetObject))
        return True, RetObject

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


"""
Cette fonction retour la liste de clients rattaché à un fournisseur
collection 'fsseur_client_link'
"""
def get_linked_customer_to_partner(diction):
    try:
        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]) + "  Impossible de récupérer les prix client,  Le champ  '" + val + "' n'existe pas ")
                return False, " Impossible de récupérer les prix client,  Le champ  '" + val + "' n'existe pas"

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

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - Impossible de récupérer les clients, La valeur '" + val + "' n'est pas presente dans liste")
                return False, " Impossible de récupérer les clients, La valeur '" + val + "' n'est pas presente dans liste"

        # recuperation des paramettre
        my_token = ""
        partner_recid = ""

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

        print(" ### my_token = ", my_token)
        partner_recid = ""
        # Verification de la validité du token/mail dans le cas des user en mode connecté
        if (len(str(my_token)) > 0):
            retval = mycommon.check_partner_token_validity("", my_token)

            if retval is False:
                mycommon.myprint(str(inspect.stack()[0][3]) + " - La session de connexion n'est pas valide")
                return False, " Impossible de récupérer les factures"

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

        if (len(str(my_token)) <= 0):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Le token est vide")
            return False, " Impossible de récupérer les factures"

        RetObject = []
        coll_facture = MYSY_GV.dbname['fsseur_client_link']

        pipe = [
                 { '$lookup':
                      {
                        'from': 'partnair_account',
                        'localField': 'client_recid',
                        'foreignField': 'recid',
                        'as': 'partnair_account'
                      }
                    }
                ]

        for retVal in coll_facture.aggregate(pipe):
            client = retVal['partnair_account']
            val = {}
            val['nom'] = client[0]['nom']
            val['recid'] = client[0]['recid']
            RetObject.append(mycommon.JSONEncoder().encode(val))

        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) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
        return False, "Impossible de récupérer les factures"


"""
Cette fonction retourne un ligne de prix spécifique
"""
def get_cust_specific_prices_by_partner(diction):
    try:
        field_list = ['token', 'price_line_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]) + "  Impossible de récupérer les prix client,  Le champ  '" + val + "' n'existe pas ")
                return False, " Impossible de récupérer les prix client,  Le champ  '" + val + "' n'existe pas"

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

        for val in field_list_obligatoire:
            if val not in diction:
                mycommon.myprint(
                    str(inspect.stack()[0][3]) + " - Impossible de récupérer les prix clients, La valeur '" + val + "' n'est pas presente dans liste")
                return False, " Impossible de récupérer les prix clients, La valeur '" + val + "' n'est pas presente dans liste"

        # recuperation des paramettre
        my_token = ""
        partner_recid = ""

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

        partner_recid = ""
        # Verification de la validité du token/mail dans le cas des user en mode connecté
        if (len(str(my_token)) > 0):
            retval = mycommon.check_partner_token_validity("", my_token)

            if retval is False:
                mycommon.myprint(str(inspect.stack()[0][3]) + " - La session de connexion n'est pas valide")
                return False, " Impossible de récupérer les factures"

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

        if (len(str(my_token)) <= 0):
            mycommon.myprint(str(inspect.stack()[0][3]) + " - Le token est vide")
            return False, " Impossible de récupérer les factures"

        """
        pipe = [

                { '$match': {'_id':ObjectId(diction['price_line_id']), 'valide': '1' } },
                 { '$lookup':
                      {
                        'from': 'partnair_account',
                        'localField': 'client_recid',
                        'foreignField': 'recid',
                        'as': 'partnair_account'
                      }
                    }
                ]


        for retVal in coll_facture.aggregate(pipe):
            new_retVal = {}
            new_retVal['nom'] = retVal['partnair_account']['nom']
            new_retVal['discount'] = retVal['discount']
            new_retVal['date_du'] = retVal['date_du']
            new_retVal['date_au'] = retVal['date_au']
            new_retVal['discount'] = retVal['discount']



        """
        RetObject = []
        coll_facture = MYSY_GV.dbname['business_prices']
        retVal = coll_facture.find_one({'partner_recid':partner_recid, 'valide': '1',
                                         '_id':ObjectId(diction['price_line_id'])}, )


        print(" ### retVal ", retVal)
        RetObject.append(mycommon.JSONEncoder().encode(retVal))

        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) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
        return False, "Impossible de récupérer les factures"
