diff --git a/class_mgt.py b/class_mgt.py index 876f1b2..e180d46 100644 --- a/class_mgt.py +++ b/class_mgt.py @@ -97,6 +97,8 @@ def add_class(diction): mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de recuperer le recid du partenaire") return False, " Les informations d'identification sont incorrectes" + + part_status, part_pack, part_pack_nb_training_auto = mycommon.Partner_Get_pack_nbTraining(user_recid) if( part_status is False): mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de recuperer le pack et le nombre de formation du partenaire") diff --git a/ela_factures_mgt.py b/ela_factures_mgt.py index d6127a1..11369a0 100644 --- a/ela_factures_mgt.py +++ b/ela_factures_mgt.py @@ -591,6 +591,14 @@ def createOrder(diction): return_document=ReturnDocument.AFTER ) + # Apres la creation du nouvelle abonnement, il faut aller cloturer l'ancien abonnement actif + today_tmp = datetime.today().date() + ret_val_cloture = coll_order.update_many({'order_id': {'$ne' : str(new_data['order_id'])}, 'valide': '1', + 'client_recid':str(user_recid)}, + {"$set": {'end_date': str(today_tmp), 'date_update': str(datetime.now())}}, + ) + + # Facturation de la commande #print(" ######## lancement de la facturation total_ttc_float = " + str(total_ttc_float)) if (total_ttc_float > 0): diff --git a/main.py b/main.py index c8a9796..51caeb3 100644 --- a/main.py +++ b/main.py @@ -1373,30 +1373,59 @@ def AutoamticCreateInvoice(): """ API de excuter une fonction de statistique """ -@app.route('/myclass/api/GetStat_class_view/', methods=['GET','POST']) +@app.route('/myclass/api/GetStat_class_view_old/', methods=['GET','POST']) @crossdomain(origin='*') -def GetStat_class_view(): +def GetStat_class_view_old(): # On recupere le corps (payload) de la requete payload = request.form.to_dict() print(" ### payload = ", str(payload)) - status, message = Stat.GetStat_class_view() + status, message = Stat.GetStat_class_view_old() return jsonify(status=status, message=message) """ API de excuter une fonction de statistique sur la semaine ecoulée """ -@app.route('/myclass/api/GetStat_class_view_lastweek/', methods=['GET','POST']) +@app.route('/myclass/api/GetStat_class_view/', methods=['GET','POST']) @crossdomain(origin='*') -def GetStat_class_view_lastweek(): +def GetStat_class_view(): # On recupere le corps (payload) de la requete payload = request.form.to_dict() print(" ### payload = ", str(payload)) - status, message = Stat.GetStat_class_view_lastweek() + status, message = Stat.GetStat_class_view(payload) return jsonify(status=status, message=message) +""" +Cette API retourne les STAT des X formations les plus vues d'un client donné sur +une periode donnée +""" +@app.route('/myclass/api/GetStat_class_view_topX/', methods=['GET','POST']) +@crossdomain(origin='*') +def GetStat_class_view_topX(): + # On recupere le corps (payload) de la requete + payload = request.form.to_dict() + print(" ### payload = ", str(payload)) + status, message = Stat.GetStat_class_view_topX(payload) + return jsonify(status=status, message=message) + + + +""" +Cette API retourne les X formations les plus vues d'un client donné sur +une periode donnée +""" +@app.route('/myclass/api/Get_X_Best_Class_On_Given_period/', methods=['GET','POST']) +@crossdomain(origin='*') +def Get_X_Best_Class_On_Given_period(): + # On recupere le corps (payload) de la requete + payload = request.form.to_dict() + print(" ### payload = ", str(payload)) + status, message = Stat.Get_X_Best_Class_On_Given_period(payload) + return jsonify(status=status, message=message) + + if __name__ == '__main__': print(" debut api") context = SSL.Context(SSL.SSLv23_METHOD) diff --git a/statistics.py b/statistics.py index 2cf13f9..4841d2a 100644 --- a/statistics.py +++ b/statistics.py @@ -28,7 +28,7 @@ class JSONEncoder(json.JSONEncoder): return json.JSONEncoder.default(self, o) -def GetStat_class_view(): +def GetStat_class_view_old(): try: # collection collection = MYSY_GV.dbname["user_recherche_result"] @@ -107,8 +107,78 @@ def GetStat_class_view(): return False, "Impossible de recuperer les stat" -def GetStat_class_view_lastweek(): +def GetStat_class_view(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 = ['external_code', 'internal_url', 'zone_diffusion', 'metier', 'date_lieu', + 'published', 'token', 'date_start', 'date_end'] + 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 formation annulée") + return False, " Verifier votre API" + + ''' + 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])+" - La valeur '" + val + "' n'est pas presente dans liste ") + return False, " Verifier votre API" + + ''' + Verification si le token et l'email sont valident + ''' + + # recuperation des paramettre + mydata = {} + + + if ("token" in diction.keys()): + if diction['token']: + mydata['token'] = diction['token'] + + date_start = "" + if ("date_start" in diction.keys()): + if diction['date_start']: + date_start = diction['date_start'] + + date_end = "" + if ("date_end" in diction.keys()): + if diction['date_end']: + date_end = diction['date_end'] + + + + # Verification de la validité du token + ''' + Important : pour créer une formation, il faut obligatoirement avoir un token. + PAS DE CREATION DE FORMATION EN MODE NON CONNECTE. + + CONCERNANT LES CREEES PAR NOS SYSTEME AUTOMATIQUE, IL FAUDRA LEUR PASSER UNE VALEUR MALGRE TOUT + + ''' + retval = mycommon.check_partner_token_validity("", str(mydata['token'])) + + if retval is False: + mycommon.myprint(str(inspect.stack()[0][3]) + " - Le token n'est pas valide") + return False, "L'email ou le token ne sont pas valident" + + # Recuperation du recid du partenaire + user_recid = mycommon.get_parnter_recid_from_token(str(mydata['token'])) + if user_recid is False: + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de recuperer le recid du partenaire") + return False, " Les informations d'identification sont incorrectes" + # collection collection = MYSY_GV.dbname["user_recherche_result"] @@ -132,13 +202,13 @@ def GetStat_class_view_lastweek(): SUBSTR = 7 pipe2 = [ - {'$match': {'date_update': {'$gt': str(thisweek_format)}, - 'owner':'ism' + {'$match': {'date_update' : { '$gte' : str(date_start), '$lte' : str(date_end)}, + 'token':str(mydata['token']) }}, { '$group': { '_id': { - "INTERNAL URL": "$internal_url", + "OWNER": "$owner", "Date_view": {"$substr": ["$date_update", 0, SUBSTR]}, }, @@ -151,6 +221,8 @@ def GetStat_class_view_lastweek(): } ] + print(" PIP 2 ="+str(pipe2)) + insertObject = [] for result in collection.aggregate(pipe2): tmp_val = {} @@ -185,3 +257,280 @@ def GetStat_class_view_lastweek(): 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 les stat" + + +""" +Cette fonction retourne le top 5 sur une periode donnée +""" +def GetStat_class_view_topX(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 = ['external_code', 'internal_url', 'zone_diffusion', 'metier', 'date_lieu', + 'published', 'token', 'date_start', 'date_end', 'topX'] + 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 formation annulée") + return False, " Verifier votre API" + + ''' + 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', 'topX'] + + 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, " Verifier votre API" + + ''' + Verification si le token et l'email sont valident + ''' + + # recuperation des paramettre + mydata = {} + + + if ("token" in diction.keys()): + if diction['token']: + mydata['token'] = diction['token'] + + date_start = "" + if ("date_start" in diction.keys()): + if diction['date_start']: + date_start = diction['date_start'] + + date_end = "" + if ("date_end" in diction.keys()): + if diction['date_end']: + date_end = diction['date_end'] + + topX = 0 + if ("topX" in diction.keys()): + if diction['topX']: + topX = mycommon.tryInt(diction['topX']) + + + + + # Verification de la validité du token + ''' + Important : pour créer une formation, il faut obligatoirement avoir un token. + PAS DE CREATION DE FORMATION EN MODE NON CONNECTE. + + CONCERNANT LES CREEES PAR NOS SYSTEME AUTOMATIQUE, IL FAUDRA LEUR PASSER UNE VALEUR MALGRE TOUT + + ''' + retval = mycommon.check_partner_token_validity("", str(mydata['token'])) + + if retval is False: + mycommon.myprint(str(inspect.stack()[0][3]) + " - Le token n'est pas valide") + return False, "L'email ou le token ne sont pas valident" + + # Recuperation du recid du partenaire + user_recid = mycommon.get_parnter_recid_from_token(str(mydata['token'])) + if user_recid is False: + mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de recuperer le recid du partenaire") + return False, " Les informations d'identification sont incorrectes" + + + """ + Recuperation des id (internal_url) des formations + """ + status_tmp, diction_topx = Get_X_Best_Class_On_Given_period(diction) + + print(" pour cette stat, le voix le top " + str(topX) + " des ref concernées ") + print(diction_topx) + + print(" ========= print(diction_topx)") + liste_formation = [] + for val_tmp in diction_topx: + json_object = json.loads(val_tmp) + if ("internal_url" in json_object.keys()): + if json_object['internal_url']: + liste_formation.append(str(json_object['internal_url'])) + + # collection + collection = MYSY_GV.dbname["user_recherche_result"] + + """ + Pour avoir une requete qui groupe par jour, ou jour-heure + on doit jouer avec le + "date" : { $substr: [ "$date_update", 0, 25 ] } ==> ou 25 et la largeur de la coupure, + """ + + thisweek = datetime.today() - timedelta(days=0) + thisweek_format = thisweek.strftime('%Y-%m-%d') + + QUERY_BY = "jour" + SUBSTR = 0 + + if (QUERY_BY == 'heure'): + SUBSTR = 13 + elif (QUERY_BY == 'jour'): + SUBSTR = 10 + elif (QUERY_BY == 'mois'): + SUBSTR = 7 + + pipe2 = [ + {'$match': {'date_update' : { '$gte' : str(date_start), '$lte' : str(date_end)}, + 'token':str(mydata['token']), + 'internal_url': {'$in': liste_formation}, + }}, + { + '$group': { + '_id': { + "INTERNAL URL": "$internal_url", + "OWNER": "$owner", + "Date_view": {"$substr": ["$date_update", 0, SUBSTR]}, + }, + 'count': {'$count': {} + } + } + }, + { + "$sort": {"count": -1} + }, + + ] + + print(" PIP 2 ="+str(pipe2)) + + insertObject = [] + for result in collection.aggregate(pipe2): + tmp_val = {} + + # tab_training_id.append(str(result["_id"])) + # print(result['_id']) + + if ("Date_view" in result['_id'].keys()): + if result['_id']['Date_view']: + print("Date_view = " + str(result['_id']['Date_view'])) + tmp_val['Date_view'] = str(result['_id']['Date_view']) + + if ("OWNER" in result['_id'].keys()): + if result['_id']['OWNER']: + print("Owner = " + str(result['_id']['OWNER'])) + tmp_val['owner'] = str(result['_id']['OWNER']) + + if ("INTERNAL URL" in result['_id'].keys()): + if result['_id']['INTERNAL URL']: + print("INTERNAL URL = " + str(result['_id']['INTERNAL URL'])) + tmp_val['internal_url'] = str(result['_id']['INTERNAL URL']) + + print("Nombre = " + str(result['count'])) + tmp_val['nb_view'] = str(result['count']) + insertObject.append(JSONEncoder().encode(tmp_val)) + + # print(result) + + return True, insertObject + + 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 les stat" + + +""" +Cette fonction recuprer la liste des X formations d'un client donné, +les plus vue sur une periode donnée +""" +def Get_X_Best_Class_On_Given_period(diction): + try: + + field_list = ['token', 'date_start', 'date_end', 'topX'] + 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é, action annulée") + return False, " Verifier votre API" + + # collection + collection = MYSY_GV.dbname["user_recherche_result"] + + mytoken = "" + if ("token" in diction.keys()): + if diction['token']: + mytoken = diction['token'] + + date_start = "" + if ("date_start" in diction.keys()): + if diction['date_start']: + date_start = diction['date_start'] + + date_end = "" + if ("date_end" in diction.keys()): + if diction['date_end']: + date_end = diction['date_end'] + + topX = 0 + if ("topX" in diction.keys()): + if diction['topX']: + topX = mycommon.tryInt(diction['topX']) + + pipe2 = [ + {'$match': {'date_update': {'$gte': str(date_start), '$lte': str(date_end)}, + 'token': str(mytoken) + }}, + { + '$group': { + '_id': { + "INTERNAL URL": "$internal_url", + "OWNER": "$owner", + + }, + 'count': {'$count': {} + } + } + }, + { + "$sort": {"count": -1} + }, + { + "$limit": topX + } + ] + + print(" PIP 222 =" + str(pipe2)) + + insertObject = [] + for result in collection.aggregate(pipe2): + tmp_val = {} + + # tab_training_id.append(str(result["_id"])) + # print(result['_id']) + + + if ("OWNER" in result['_id'].keys()): + if result['_id']['OWNER']: + print("Owner = " + str(result['_id']['OWNER'])) + tmp_val['owner'] = str(result['_id']['OWNER']) + + if ("INTERNAL URL" in result['_id'].keys()): + if result['_id']['INTERNAL URL']: + print("INTERNAL URL = " + str(result['_id']['INTERNAL URL'])) + tmp_val['internal_url'] = str(result['_id']['INTERNAL URL']) + + print("Nombre = " + str(result['count'])) + tmp_val['nb_view'] = str(result['count']) + insertObject.append(JSONEncoder().encode(tmp_val)) + + # print(result) + + + return True, insertObject + + 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 X les formations les plus vue" +