From 19eb883b37445a55d8582d7a01f4c7237dc5c7c5 Mon Sep 17 00:00:00 2001 From: cherif Date: Fri, 2 Jun 2023 21:59:07 +0200 Subject: [PATCH] 02/06/23 - 22h --- .idea/workspace.xml | 28 ++- code_promo_mgt.py | 446 ++++++++++++++++++++++++++++++++++++++++++++ main.py | 56 ++++++ 3 files changed, 523 insertions(+), 7 deletions(-) create mode 100644 code_promo_mgt.py diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 117deae..beb6a26 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,16 +1,23 @@ - + + - - + + + + @@ -26,7 +33,7 @@ "keyToString": { "RunOnceActivity.OpenProjectViewOnStart": "true", "RunOnceActivity.ShowReadmeOnStart": "true", - "last_opened_file_path": "C:/Users/billa/Documents/myclass.com/Siteweb/Production/Ela_back/Back_Office/main.py" + "last_opened_file_path": "C:/Users/billa/Documents/Projet_X/projet_w_siteweb/developpement/PrjX_back" } } @@ -264,7 +271,14 @@ @@ -279,7 +293,6 @@ - @@ -304,6 +317,7 @@ - \ No newline at end of file diff --git a/code_promo_mgt.py b/code_promo_mgt.py new file mode 100644 index 0000000..027dbe1 --- /dev/null +++ b/code_promo_mgt.py @@ -0,0 +1,446 @@ +''' +Ce fichier traite tout ce qui est liée à la gestion des codes promo +''' + +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 + + +""" +Cette fonction créer un code promo +Elle verifie que ce code n'existe pas deja +- controle sur les date de validé +- controle sur le type de code +""" +def Add_Code_Promo(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 = [ 'code', 'type', 'description', 'valeur', 'date_debut', 'date_fin' ] + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas, mise à jour logo lms annulée") + return False, " Les informations fournies sont incorrecte", + + ''' + 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 = ['code', 'type', 'description', 'valeur', 'date_debut', 'date_fin' ] + 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 incorrecte", + + + code = "" + if ("code" in diction.keys()): + if diction['code']: + code = diction['code'] + + my_type = "" + if ("type" in diction.keys()): + if diction['type']: + my_type = diction['type'] + + if( my_type not in ['fix', 'percent'] ): + mycommon.myprint(str(inspect.stack()[0][3]) + " - La valeur du type = "+str(my_type)+" n'est pas accepté. Les valeurs autorisées sont : 'fix' ou 'percent'") + return False, str(inspect.stack()[0][ + 3]) + " - La valeur du type = "+str(my_type)+" n'est pas accepté. Les valeurs autorisées sont : 'fix' ou 'percent'", + + + description = "" + if ("description" in diction.keys()): + if diction['description']: + description = diction['description'] + + if(len(description) > 255 ): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " - Le champ 'description' fait plus de 255 caracteres ") + + return False, " - Le champ 'description' fait plus de 255 caracteres " + + + valeur = "" + if ("valeur" in diction.keys()): + if diction['valeur']: + valeur = diction['valeur'] + + local_status, valeur = mycommon.IsFloat(valeur) + if (local_status is False): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champs 'valeur' est incorrecte. la veleur attendue est un entier ou un decimal.") + return False, " Le champs 'valeur' est incorrecte. la veleur attendue est un entier ou un decimal. " + + date_debut = "" + if ("date_debut" in diction.keys()): + if diction['date_debut']: + date_debut = diction['date_debut'] + + # Controle de cohérence sur date_debut + local_status = mycommon.CheckisDate(str(date_debut)[0:10]) + if (local_status is False): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " - La date de debut n'est pas au format jj/mm/aaaa ") + + return False, " - La date de debut n'est pas au format jj/mm/aaaa " + + + date_fin = "" + if ("date_fin" in diction.keys()): + if diction['date_fin']: + date_fin = diction['date_fin'] + + # Controle de cohérence sur date_fin + local_status = mycommon.CheckisDate(str(date_fin)[0:10]) + if (local_status is False): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " - La date de fin n'est pas au format jj/mm/aaaa ") + + return False, " - La date de fin n'est pas au format jj/mm/aaaa " + + # Controle de cohérence des dates entre elles + if (datetime.strptime(str(diction['date_debut'])[0:10], '%d/%m/%Y') > datetime.strptime( + str(diction['date_fin'])[0:10], '%d/%m/%Y')): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " - La date debut " + str( + diction['date_debut']) + " est postérieure à la date de fin " + str(diction['date_fin']) ) + + return False, " La date debut " + str(diction['date_debut']) + \ + " est postérieure à la date de fin " + str(diction['date_fin']) + " " + + """ + Verification un tel code promo n'existe pas deja + """ + tmp_count = MYSY_GV.dbname['code_promo'].count_documents({'code': str(code), 'valide': '1'}) + if (tmp_count > 0): + mycommon.myprint( + " Le code promo '" + str(code) + "' existe deja, impossible d'ajouter la promotion ") + return False, " Le code promo '" + str(code) + "' existe deja, impossible d'ajouter la promotion " + + data = {} + data['code'] = code + data['type'] = my_type + data['description'] = description + data['valeur'] = valeur + data['date_debut'] = date_debut + data['date_fin'] = date_fin + + inserted_id = "" + inserted_id = MYSY_GV.dbname['code_promo'].insert_one(data).inserted_id + if( not inserted_id): + mycommon.myprint( + " Impossible de créer le code promo o '" + str(code) + "' ") + return False, " Impossible de créer le code promo o '" + str(code) + "' " + + return True, " Le code promo " + str(code) +" a été correctement créé" + + except Exception as e: + exc_type, exc_obj, exc_tb = sys.exc_info() + mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)) + return False, " Impossible de créer le code promo " + + +""" +Cette fonction retourne les code promo valides + - valide = 1 + - Date debut et Date fin sont ok +""" +def Get_Valide_Code_Promo(diction): + try: + + field_list = ['token',] + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list: + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée") + return False, "Toutes les informations fournies ne sont pas valables" + + """ + Verification de la liste 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, "Toutes les informations necessaires n'ont pas été fournies" + + # 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]) + " - partner_recid est KO. Les données de connexion sont incorrectes ") + return False, " Les données de connexion sont incorrectes " + + coll_session = MYSY_GV.dbname['code_promo'] + myquery = {} + myquery['valide'] = "1" + myquery['locked'] = "0" + + print(" ##### myquery = " + str(myquery)) + RetObject = [] + + for retval in coll_session.find(myquery): + # print(" ##### retval = " + str(retval)) + debut_debut = datetime.strptime(str(retval['date_debut']).strip(), '%d/%m/%Y') + date_fin = datetime.strptime(str(retval['date_fin']).strip(), '%d/%m/%Y') + if (debut_debut <= datetime.now() and date_fin >= datetime.now()): + 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 recuperer la session de formation" + + +""" +Cette fonction retourne tous les codes promo, peut importe la validité +""" +def Get_All_Code_Promo(diction): + try: + + field_list = ['token',] + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list: + mycommon.myprint(str(inspect.stack()[0][ + 3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée") + return False, "Toutes les informations fournies ne sont pas valables" + + """ + Verification de la liste 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, "Toutes les informations necessaires n'ont pas été fournies" + + # 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]) + " - partner_recid est KO. Les données de connexion sont incorrectes ") + return False, " Les données de connexion sont incorrectes " + + coll_session = MYSY_GV.dbname['code_promo'] + + RetObject = [] + + for retval in coll_session.find({}): + # print(" ##### retval = " + str(retval)) + debut_debut = datetime.strptime(str(retval['date_debut']).strip(), '%d/%m/%Y') + date_fin = datetime.strptime(str(retval['date_fin']).strip(), '%d/%m/%Y') + if (debut_debut <= datetime.now() and date_fin >= datetime.now()): + 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 recuperer la session de formation" + + +""" +Cette fonction met à jour un code promo. + +Un code promo est modifiable tant qu'il n'est pas "is_used" +""" +def Update_Code_Promo(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 = [ 'code', 'type', 'description', 'valeur', 'date_debut', 'date_fin' ] + incom_keys = diction.keys() + for val in incom_keys: + if val not in field_list: + mycommon.myprint(str( + inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas, mise à jour logo lms annulée") + return False, " Les informations fournies sont incorrecte", + + ''' + 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 = ['code', 'type', 'description', 'valeur', 'date_debut', 'date_fin' ] + 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 incorrecte", + + + code = "" + if ("code" in diction.keys()): + if diction['code']: + code = diction['code'] + + my_type = "" + if ("type" in diction.keys()): + if diction['type']: + my_type = diction['type'] + + if( my_type not in ['fix', 'percent'] ): + mycommon.myprint(str(inspect.stack()[0][3]) + " - La valeur du type = "+str(my_type)+" n'est pas accepté. Les valeurs autorisées sont : 'fix' ou 'percent'") + return False, str(inspect.stack()[0][ + 3]) + " - La valeur du type = "+str(my_type)+" n'est pas accepté. Les valeurs autorisées sont : 'fix' ou 'percent'", + + + description = "" + if ("description" in diction.keys()): + if diction['description']: + description = diction['description'] + + if(len(description) > 255 ): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " - Le champ 'description' fait plus de 255 caracteres ") + + return False, " - Le champ 'description' fait plus de 255 caracteres " + + + valeur = "" + if ("valeur" in diction.keys()): + if diction['valeur']: + valeur = diction['valeur'] + + local_status, valeur = mycommon.IsFloat(valeur) + if (local_status is False): + mycommon.myprint( + str(inspect.stack()[0][3]) + " Le champs 'valeur' est incorrecte. la veleur attendue est un entier ou un decimal.") + return False, " Le champs 'valeur' est incorrecte. la veleur attendue est un entier ou un decimal. " + + date_debut = "" + if ("date_debut" in diction.keys()): + if diction['date_debut']: + date_debut = diction['date_debut'] + + # Controle de cohérence sur date_debut + local_status = mycommon.CheckisDate(str(date_debut)[0:10]) + if (local_status is False): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " - La date de debut n'est pas au format jj/mm/aaaa ") + + return False, " - La date de debut n'est pas au format jj/mm/aaaa " + + + date_fin = "" + if ("date_fin" in diction.keys()): + if diction['date_fin']: + date_fin = diction['date_fin'] + + # Controle de cohérence sur date_fin + local_status = mycommon.CheckisDate(str(date_fin)[0:10]) + if (local_status is False): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " - La date de fin n'est pas au format jj/mm/aaaa ") + + return False, " - La date de fin n'est pas au format jj/mm/aaaa " + + # Controle de cohérence des dates entre elles + if (datetime.strptime(str(diction['date_debut'])[0:10], '%d/%m/%Y') > datetime.strptime( + str(diction['date_fin'])[0:10], '%d/%m/%Y')): + mycommon.myprint( + str(inspect.stack()[0][ + 3]) + " - La date debut " + str( + diction['date_debut']) + " est postérieure à la date de fin " + str(diction['date_fin']) ) + + return False, " La date debut " + str(diction['date_debut']) + \ + " est postérieure à la date de fin " + str(diction['date_fin']) + " " + + """ + Verification un tel code promo n'existe pas deja + """ + tmp_count = MYSY_GV.dbname['code_promo'].count_documents({'code': str(code), 'valide': '1'}) + if (tmp_count < 0): + mycommon.myprint( + " Le code promo '" + str(code) + "' existe pas") + return False, " Le code promo '" + str(code) + "' existe pas " + + tmp_count = MYSY_GV.dbname['code_promo'].count_documents({'code': str(code), 'valide': '1', 'is_used':'1'}) + if (tmp_count > 0): + mycommon.myprint( + " Le code promo '" + str(code) + "' est déjà utilisé") + return False, " Le code promo '" + str(code) + "' est déjà utilisé " + + + data = {} + data['code'] = code + data['type'] = my_type + data['description'] = description + data['valeur'] = valeur + data['date_debut'] = date_debut + data['date_fin'] = date_fin + + inserted_id = "" + result = MYSY_GV.dbname['code_promo'].find_one_and_update( + {'code': str(code), 'locked': '0', 'valide': '1'}, + {"$set": data}, + upsert= False, + return_document=ReturnDocument.AFTER + ) + if( not result): + mycommon.myprint( + " Impossible de mettre à jour le code promo '" + str(code) + "' ") + return False, " Impossible de mettre à jour le code promo '" + str(code) + "' " + + return True, " Le code promo " + str(code) +" 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 code promo " + diff --git a/main.py b/main.py index 0d1b85e..7f52658 100644 --- a/main.py +++ b/main.py @@ -39,6 +39,7 @@ import Attestation_Certificat as Att_Cert import tools_cherif.tools_cherif as tools_cherif import business_prices as business_prices import lms_chamilo.mysy_lms as mysy_lms +import code_promo_mgt as code_promo_mgt app = Flask(__name__) cors = CORS(app, resources={r"/foo": {"origins": "*"}}) @@ -2985,6 +2986,61 @@ def Unpublish_Class_From_Lms(): localStatus, message = mysy_lms.Unpublish_Class_From_Lms(payload) return jsonify(status=localStatus, message=message) + + +""" +Cette API ajoute un code promo +""" +@app.route('/myclass/api/Add_Code_Promo/', methods=['POST','GET']) +@crossdomain(origin='*') +def Add_Code_Promo(): + # On recupere le corps (payload) de la requete + payload = request.form.to_dict() + print(" ### code_promo_mgt : payload = ",payload) + localStatus, message = code_promo_mgt.Add_Code_Promo(payload) + return jsonify(status=localStatus, message=message) + +""" +Cette API recupere les codes promo valides + - valide = 1 + - Date debut et Date fin sont ok + """ +@app.route('/myclass/api/Get_Valide_Code_Promo/', methods=['POST','GET']) +@crossdomain(origin='*') +def Get_Valide_Code_Promo(): + # On recupere le corps (payload) de la requete + payload = request.form.to_dict() + print(" ### Get_Valide_Code_Promo : payload = ",payload) + localStatus, message = code_promo_mgt.Get_Valide_Code_Promo(payload) + return jsonify(status=localStatus, message=message) + +""" +Cette API retourne tous les codes promo, peut importe la validité +""" +@app.route('/myclass/api/Get_All_Code_Promo/', methods=['POST','GET']) +@crossdomain(origin='*') +def Get_All_Code_Promo(): + # On recupere le corps (payload) de la requete + payload = request.form.to_dict() + print(" ### Get_All_Code_Promo : payload = ",payload) + localStatus, message = code_promo_mgt.Get_All_Code_Promo(payload) + return jsonify(status=localStatus, message=message) + +""" +API de mise à jour du code promo +""" +@app.route('/myclass/api/Update_Code_Promo/', methods=['POST','GET']) +@crossdomain(origin='*') +def Update_Code_Promo(): + # On recupere le corps (payload) de la requete + payload = request.form.to_dict() + print(" ### Update_Code_Promo : payload = ",payload) + localStatus, message = Update_Code_Promo.Get_All_Code_Promo(payload) + return jsonify(status=localStatus, message=message) + + + + if __name__ == '__main__': print(" debut api") context = SSL.Context(SSL.SSLv23_METHOD)