master
cherif 2024-08-27 20:04:36 +02:00
parent 586e52504d
commit 1931c81c11
11 changed files with 11295 additions and 28 deletions

View File

@ -2,10 +2,17 @@
<project version="4">
<component name="ChangeListManager">
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="ddd">
<change afterPath="$PROJECT_DIR$/Dashbord_queries/BPF.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Log/log_file.log" beforeDir="false" afterPath="$PROJECT_DIR$/Log/log_file.log" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Session_Formation.py" beforeDir="false" afterPath="$PROJECT_DIR$/Session_Formation.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/base_partner_catalog_config.py" beforeDir="false" afterPath="$PROJECT_DIR$/base_partner_catalog_config.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/class_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/class_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/email_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/email_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/partners.py" beforeDir="false" afterPath="$PROJECT_DIR$/partners.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/prj_common.py" beforeDir="false" afterPath="$PROJECT_DIR$/prj_common.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/wrapper.py" beforeDir="false" afterPath="$PROJECT_DIR$/wrapper.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />

635
Dashbord_queries/BPF.py Normal file
View File

@ -0,0 +1,635 @@
"""
Ce fichier permet de traiter et generer le BPF
SPEC : Source : https://culture-rh.com/bfp-bilan-pedagogique-financier/
"""
import ast
import dateutil
import pymongo
import xlsxwriter
from flask import send_file
from pymongo import MongoClient
import json
from bson import ObjectId
import re
from datetime import datetime, timezone, date
import prj_common as mycommon
import secrets
import inspect
import sys, os
import csv
import pandas as pd
from pymongo import ReturnDocument
import GlobalVariable as MYSY_GV
from math import isnan
import GlobalVariable as MYSY_GV
from datetime import timedelta
from datetime import timedelta
import Dashbord_queries.formation_tbd_qries as formation_tbd_qries
from dateutil.relativedelta import relativedelta
def Get_Qery_Generate_BPF_From_partner_invoice_header(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'periode_start_date', 'periode_end_date', 'filter_value', ]
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_client_id = {}
if ("filter_client_id" in diction.keys() and diction['filter_client_id']):
filt_client_id = {'order_header_client_id': str(diction['filter_client_id'])}
filt_periode_start_date = ""
if ("periode_start_date" in diction.keys() and diction['periode_start_date']):
filt_periode_start_date = str(diction['periode_start_date'])[0:10]
local_status = mycommon.CheckisDate(filt_periode_start_date)
if (local_status is False):
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le filtre : 'date de debut' n'est pas au format jj/mm/aaaa.")
return False, " Le filtre : 'date de debut' n'est pas au format jj/mm/aaaa."
filt_periode_end_date = ""
if ("periode_end_date" in diction.keys() and diction['periode_end_date']):
filt_periode_end_date = str(diction['periode_end_date'])[0:10]
local_status = mycommon.CheckisDate(filt_periode_end_date)
if (local_status is False):
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le filtre : 'date de fin' n'est pas au format jj/mm/aaaa.")
return False, " Le filtre : 'date de fin' n'est pas au format jj/mm/aaaa."
"""
Si la valeur de 'filter_value' est m0 ou m1, on va aller recuperer les date du mois correspondant.
On ecrase les valeur de filt_session_start_date et filt_session_end_date
"""
if ('filter_value' in diction.keys()):
# print(" filter_value = ", diction['filter_value'])
if (str(diction['filter_value']) == "m0"):
# On recupere les date du mois en cours
local_status, start_current_month_date, end_current_month_date = mycommon.Get_Current_Month_Start_End_Date()
if (local_status is False):
return local_status, start_current_month_date
filt_periode_start_date = start_current_month_date
filt_periode_end_date = end_current_month_date
# print(" ### filt_session_start_date = ", filt_session_start_date, " ### filt_session_end_date = ", filt_session_end_date)
elif (str(diction['filter_value']) == "m1"):
# On recupere les date du mois en cours
local_status, start_current_month_date, end_current_month_date = mycommon.Get_Previous_Month_Start_End_Date()
if (local_status is False):
return local_status, start_current_month_date
filt_periode_start_date = start_current_month_date
filt_periode_end_date = end_current_month_date
filt_periode_start_date_ISODATE = datetime.strptime(str(filt_periode_start_date), '%d/%m/%Y')
filt_periode_end_date_ISODATE = datetime.strptime(str(filt_periode_end_date), '%d/%m/%Y')
RetObject = []
val_tmp = 0
"""
C1 Quelles sont vos ressources provenant directement des entreprises pour la formation de leurs salariés ?
On recherche le CA venant des client : is_client = 1, is_financeur != 1
"""
C1_qery_match = {'$and': [{"partner_owner_recid": str(my_partner['recid'])},
{"valide": '1'},
{
'mysy_invoice_date': {'$gte': filt_periode_start_date_ISODATE,
'$lte': filt_periode_end_date_ISODATE}}, ]}
C1_pipe_qry = ([
{"$addFields": {
"mysy_invoice_date": {
'$dateFromString': {
'dateString': '$invoice_date',
'format': "%d/%m/%Y"
}
}
}
},
{'$match': C1_qery_match},
{'$lookup': {
'from': 'partner_client',
"let": {'order_header_client_id': "$order_header_client_id",
'partner_owner_recid': '$partner_owner_recid'},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$_id", {'$convert': {
'input': "$$order_header_client_id",
'to': "objectId",
'onError': {'error': 'true'},
'onNull': {'isnull': 'true'}
}}]},
{'$eq': ["$valide", "1"]},
{'$eq': ["$partner_recid", '$$partner_owner_recid']},
{'$eq': ["is_client", "1"]},
{'$ne': ["is_financeur", "1"]},
]
}
}
},
],
'as': 'partner_client_collection'
}
},
{'$group': {
"TotalAmount": {"$sum": {'$toDouble': '$total_header_toutes_taxes'}},
"count": {"$sum": 1}
}
},
])
print(" ### Get_Qery_Generate_BPF C1_pipe_qry = ", C1_pipe_qry)
C2_pipe_qry = ([
{"$addFields": {
"mysy_invoice_date": {
'$dateFromString': {
'dateString': '$invoice_date',
'format': "%d/%m/%Y"
}
}
}
},
{'$match': C1_qery_match},
{'$lookup': {
'from': 'partner_client',
"let": {'order_header_client_id': "$order_header_client_id",
'partner_owner_recid': '$partner_owner_recid'},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$_id", {'$convert': {
'input': "$$order_header_client_id",
'to': "objectId",
'onError': {'error': 'true'},
'onNull': {'isnull': 'true'}
}}]},
{'$eq': ["$valide", "1"]},
{'$eq': ["$partner_recid", '$$partner_owner_recid']}
]
}
}
},
],
'as': 'partner_client_collection'
}
},
{
'$unwind': '$partner_client_collection'
},
{'$lookup': {
'from': 'partner_client_type',
"let": {'client_type_id': "$partner_client_collection.client_type_id",
'partner_recid': '$partner_recid'
},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$_id", {'$convert': {
'input': "$$client_type_id",
'to': "objectId",
'onError': {'error': 'true'},
'onNull': {'isnull': 'true'}
}}]},
{'$eq': ["$valide", "1"]},
{'$eq': ["$partner_client_collection.partner_recid",
'$$partner_recid']},
]
}
}
},
],
'as': 'partner_client_type_collection'
}
},
{'$group': {
'_id': {
"Client_type": "$partner_client_type_collection.code",
},
"TotalAmount": {"$sum": {'$toDouble': '$total_header_toutes_taxes'}},
"count": {"$sum": 1}
}
},
])
print(" ### Get_Qery_Generate_BPF C2_pipe_qry = ", C2_pipe_qry)
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 "
def Get_Qery_Generate_BPF_From_Inscription(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'periode_start_date', 'periode_end_date', 'filter_value', ]
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_client_id = {}
if ("filter_client_id" in diction.keys() and diction['filter_client_id']):
filt_client_id = {'order_header_client_id': str(diction['filter_client_id'])}
filt_periode_start_date = ""
if ("periode_start_date" in diction.keys() and diction['periode_start_date']):
filt_periode_start_date = str(diction['periode_start_date'])[0:10]
local_status = mycommon.CheckisDate(filt_periode_start_date)
if (local_status is False):
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le filtre : 'date de debut' n'est pas au format jj/mm/aaaa.")
return False, " Le filtre : 'date de debut' n'est pas au format jj/mm/aaaa."
filt_periode_end_date = ""
if ("periode_end_date" in diction.keys() and diction['periode_end_date']):
filt_periode_end_date = str(diction['periode_end_date'])[0:10]
local_status = mycommon.CheckisDate(filt_periode_end_date)
if (local_status is False):
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le filtre : 'date de fin' n'est pas au format jj/mm/aaaa.")
return False, " Le filtre : 'date de fin' n'est pas au format jj/mm/aaaa."
"""
Si la valeur de 'filter_value' est m0 ou m1, on va aller recuperer les date du mois correspondant.
On ecrase les valeur de filt_session_start_date et filt_session_end_date
"""
if ('filter_value' in diction.keys()):
# print(" filter_value = ", diction['filter_value'])
if (str(diction['filter_value']) == "m0"):
# On recupere les date du mois en cours
local_status, start_current_month_date, end_current_month_date = mycommon.Get_Current_Month_Start_End_Date()
if (local_status is False):
return local_status, start_current_month_date
filt_periode_start_date = start_current_month_date
filt_periode_end_date = end_current_month_date
# print(" ### filt_session_start_date = ", filt_session_start_date, " ### filt_session_end_date = ", filt_session_end_date)
elif (str(diction['filter_value']) == "m1"):
# On recupere les date du mois en cours
local_status, start_current_month_date, end_current_month_date = mycommon.Get_Previous_Month_Start_End_Date()
if (local_status is False):
return local_status, start_current_month_date
filt_periode_start_date = start_current_month_date
filt_periode_end_date = end_current_month_date
filt_periode_start_date_ISODATE = datetime.strptime(str(filt_periode_start_date), '%d/%m/%Y')
filt_periode_end_date_ISODATE = datetime.strptime(str(filt_periode_end_date), '%d/%m/%Y')
RetObject = []
val_tmp = 0
"""
Voici une requete qui fait une jointure entre
- Inscription, Client, Type_Client, Facture
"""
C1_qery_match = {'$and': [{"partner_owner_recid": str(my_partner['recid'])},
{"valide": '1'},
{
'mysy_invoice_date': {'$gte': filt_periode_start_date_ISODATE,
'$lte': filt_periode_end_date_ISODATE}}, ]}
Inscription_Client_Type_Client_Facture_pipe_qry = ([
{'$match': {'invoiced':'1'} },
{'$lookup': {
'from': 'partner_client',
"let": {'facture_client_rattachement_id': "$facture_client_rattachement_id",
'partner_owner_recid': '$partner_owner_recid'},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$_id", {'$convert': {
'input': "$$facture_client_rattachement_id",
'to': "objectId",
'onError': {'error': 'true'},
'onNull': {'isnull': 'true'}
}}]},
{'$eq': ["$valide", "1"]},
{'$eq': ["$partner_recid", '$$partner_owner_recid']},
]
}
}
},
],
'as': 'partner_client_collection'
}
},
{
'$unwind': '$partner_client_collection'
},
{'$lookup': {
'from': 'partner_client_type',
"let": {'client_type_id': "$partner_client_collection.client_type_id",
'partner_recid': '$partner_recid',
},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$_id", {'$convert': {
'input': "$$client_type_id",
'to': "objectId",
'onError': {'error': 'true'},
'onNull': {'isnull': 'true'}
}}]},
{'$eq': ["$valide", "1"]},
{'$eq': ["$partner_client_collection.partner_recid", '$$partner_recid']},
]
}
}
},
],
'as': 'partner_client_type_collection'
}
},
{'$lookup': {
'from': 'partner_invoice_header',
"let": {'facture_client_rattachement_id': "$facture_client_rattachement_id",
'invoiced_ref': "$invoiced_ref",
'partner_owner_recid': '$partner_owner_recid'
},
'pipeline': [
{
"$addFields": {
"mysy_invoice_date": {
'$dateFromString': {
'dateString': '$invoice_date',
'format': "%d/%m/%Y"
}
}
}
},
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$invoice_header_ref_interne", '$$invoiced_ref']},
{'$eq': ["$order_header_client_id", '$$facture_client_rattachement_id']},
{'$eq': ["$valide", "1"]},
{'$eq': ["$partner_owner_recid", '$$partner_owner_recid']},
]
}
}
},
],
'as': 'partner_invoice_header_collection'
}
},
])
print(" ### Get_Qery_Generate_BPF_From_Inscription Inscription_Client_Type_Client_Facture_pipe_qry = ", Inscription_Client_Type_Client_Facture_pipe_qry)
Inscription_Client_Type_Client_Facture_pipe_qry_Client_Financeur = ([
{'$match': {'invoiced': '1'}},
{'$lookup': {
'from': 'partner_client',
"let": {'facture_client_rattachement_id': "$facture_client_rattachement_id",
'partner_owner_recid': '$partner_owner_recid'},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$_id", {'$convert': {
'input': "$$facture_client_rattachement_id",
'to': "objectId",
'onError': {'error': 'true'},
'onNull': {'isnull': 'true'}
}}]},
{'$eq': ["$valide", "1"]},
{'$eq': ["$partner_recid", '$$partner_owner_recid']},
{'$eq': ["$is_financeur", '1']},
]
}
}
},
],
'as': 'partner_client_collection'
}
},
{
'$unwind': '$partner_client_collection'
},
{'$lookup': {
'from': 'partner_client_type',
"let": {'client_type_id': "$partner_client_collection.client_type_id",
'partner_recid': '$partner_recid',
},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$_id", {'$convert': {
'input': "$$client_type_id",
'to': "objectId",
'onError': {'error': 'true'},
'onNull': {'isnull': 'true'}
}}]},
{'$eq': ["$valide", "1"]},
{'$eq': ["$partner_client_collection.partner_recid", '$$partner_recid']},
]
}
}
},
],
'as': 'partner_client_type_collection'
}
},
{'$lookup': {
'from': 'partner_invoice_header',
"let": {'facture_client_rattachement_id': "$facture_client_rattachement_id",
'invoiced_ref': "$invoiced_ref",
'partner_owner_recid': '$partner_owner_recid'
},
'pipeline': [
{
"$addFields": {
"mysy_invoice_date": {
'$dateFromString': {
'dateString': '$invoice_date',
'format': "%d/%m/%Y"
}
}
}
},
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$invoice_header_ref_interne", '$$invoiced_ref']},
{'$eq': ["$order_header_client_id", '$$facture_client_rattachement_id']},
{'$eq': ["$valide", "1"]},
{'$eq': ["$partner_owner_recid", '$$partner_owner_recid']},
]
}
}
},
],
'as': 'partner_invoice_header_collection'
}
},
])
print(" ### Get_Qery_Generate_BPF_From_Inscription Inscription_Client_Type_Client_Facture_pipe_qry_Client_Financeur = ",
Inscription_Client_Type_Client_Facture_pipe_qry)
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 "

File diff suppressed because one or more lines are too long

View File

@ -10747,6 +10747,12 @@ def Invoice_Partner_From_Session_By_Inscription_Id( diction):
order_header_montant_reduction = "0"
partner_invoice_header_data['order_header_montant_reduction'] = order_header_montant_reduction
order_header_type_client_id = ""
if( "client_type_id" in partner_client_id_data.keys() ):
order_header_type_client_id = partner_client_id_data['client_type_id']
partner_invoice_header_data['order_header_type_client_id'] = order_header_type_client_id
# Calcul du Totol HT sans reduction
total_ht = 0
@ -10912,6 +10918,57 @@ def Invoice_Partner_From_Session_By_Inscription_Id( diction):
return False, " Facture : Impossible de créer les lignes de la facture "+str(partner_invoice_header_data['invoice_header_ref_interne']), False
"""
27/08/2024 - update pour faire le BPF
on va créer une table de detail qui reprend le detail des inscription
"""
order_line_montant_hors_taxes_par_apprenant = 0
if( nb_valide_inscription_pr_client > 0 ):
order_line_montant_hors_taxes_par_apprenant = round( total_ht / nb_valide_inscription_pr_client, 2)
for tmp_inscription_dat in MYSY_GV.dbname['inscription'].find(
{'facture_client_rattachement_id': str(diction['partner_client_id']),
'session_id': str(diction['session_id']),
'partner_owner_recid': str(my_partner['recid']),
'status': '1',
'_id': {'$in': diction['tab_inscription_ids']}
},
):
partner_invoice_line_data_detail = {}
partner_invoice_line_data_detail['order_line_inscription_id'] = str(tmp_inscription_dat['_id'])
partner_invoice_line_data_detail['order_line_inscription_type_apprenant'] = str(tmp_inscription_dat['type_apprenant'])
partner_invoice_line_data_detail['order_line_inscription_modefinancement'] = str(tmp_inscription_dat['modefinancement'])
partner_invoice_line_data_detail['order_line_formation'] = class_data[0]['internal_url']
partner_invoice_line_data_detail['order_line_prix_unitaire'] = str(prix_session)
partner_invoice_line_data_detail['order_line_montant_hors_taxes'] = str(total_ht)
partner_invoice_line_data_detail['order_line_invoiced_amount'] = str(order_line_montant_hors_taxes_par_apprenant)
partner_invoice_line_data_detail['order_line_comment'] = str(nom_prenom_email_participant)
partner_invoice_line_data_detail['invoice_header_id'] = str(inserted_invoice_id)
partner_invoice_line_data_detail['invoice_line_type'] = "facture"
partner_invoice_line_data_detail['invoice_header_ref_interne'] = partner_invoice_header_data[
'invoice_header_ref_interne']
partner_invoice_line_data_detail['update_by'] = str(my_partner['_id'])
partner_invoice_line_data_detail['valide'] = "1"
partner_invoice_line_data_detail['locked'] = "0"
partner_invoice_line_data_detail['partner_owner_recid'] = str(my_partner['recid'])
print(" #### partner_invoice_line_data = ", partner_invoice_line_data)
inserted_invoice_id = MYSY_GV.dbname['partner_invoice_line_detail'].insert_one(
partner_invoice_line_data_detail).inserted_id
"""
MYSY_GV.dbname['inscription'].update_one({'_id':ObjectId(str(tmp_inscription_dat['_id']))},
{'$set':{'invoiced_amount_ht':str(order_line_montant_hors_taxes_par_apprenant)}}
)
"""
"""
05/06/2024 Gestion E-Facture
Apres la creation de la facture, on va aller créer le document securisé
@ -11198,6 +11255,11 @@ def Invoice_Splited_Partner_From_Session_By_Inscription_Id( diction):
order_header_adr_fact_pays = partner_client_id_data['invoice_pays']
partner_invoice_header_data['order_header_adr_fact_pays'] = order_header_adr_fact_pays
order_header_type_client_id = ""
if ("client_type_id" in partner_client_id_data.keys()):
order_header_type_client_id = partner_client_id_data['client_type_id']
partner_invoice_header_data['order_header_type_client_id'] = order_header_type_client_id
order_header_montant_reduction = "0"
partner_invoice_header_data['order_header_montant_reduction'] = order_header_montant_reduction
@ -11395,6 +11457,51 @@ def Invoice_Splited_Partner_From_Session_By_Inscription_Id( diction):
now = str(datetime.now())
tab_date_invoice.append(str(now))
"""
27/08/2024 - update pour faire le BPF
on va créer une table de detail qui reprend le detail des inscription
"""
order_line_montant_hors_taxes_par_apprenant = round(total_ht , 2)
for tmp_inscription_dat in MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'status': '1',
'_id':ObjectId(str(diction['inscription_id'])),
'partner_owner_recid': str(my_partner['recid']),
"invoice_split": {'$ne': ''},
'invoice_split': {'$exists': True},
"invoiced": {'$ne': '1'},
}):
partner_invoice_line_data_detail = {}
partner_invoice_line_data_detail['order_line_inscription_id'] = str(tmp_inscription_dat['_id'])
partner_invoice_line_data_detail['order_line_inscription_type_apprenant'] = str(tmp_inscription_dat['type_apprenant'])
partner_invoice_line_data_detail['order_line_inscription_modefinancement'] = str(tmp_inscription_dat['modefinancement'])
partner_invoice_line_data_detail['order_line_formation'] = class_data[0]['internal_url']
partner_invoice_line_data_detail['order_line_prix_unitaire'] = str(prix_session)
partner_invoice_line_data_detail['order_line_montant_hors_taxes'] = str(total_ht)
partner_invoice_line_data_detail['order_line_invoiced_amount'] = str(split_invoice_part_FLOAT)
partner_invoice_line_data_detail['order_line_comment'] = str(nom_prenom_email_participant)
partner_invoice_line_data_detail['invoice_header_id'] = str(inserted_invoice_id)
partner_invoice_line_data_detail['invoice_line_type'] = "facture"
partner_invoice_line_data_detail['invoice_header_ref_interne'] = partner_invoice_header_data[
'invoice_header_ref_interne']
partner_invoice_line_data_detail['update_by'] = str(my_partner['_id'])
partner_invoice_line_data_detail['valide'] = "1"
partner_invoice_line_data_detail['locked'] = "0"
partner_invoice_line_data_detail['partner_owner_recid'] = str(my_partner['recid'])
print(" #### partner_invoice_line_data = ", partner_invoice_line_data)
inserted_invoice_id = MYSY_GV.dbname['partner_invoice_line_detail'].insert_one(
partner_invoice_line_data_detail).inserted_id
"""
MYSY_GV.dbname['inscription'].update_one({'_id': ObjectId(str(tmp_inscription_dat['_id']))},
{'$set': {'invoiced_amount_ht': str(
order_line_montant_hors_taxes_par_apprenant)}}
)
"""
"""
05/06/2024 Gestion E-Facture
Apres la creation de la facture, on va aller créer le document securisé

View File

@ -145,18 +145,33 @@ def Add_Update_Partner_Catalog_Pub_Config(diction):
del diction['_id']
del diction['token']
result = MYSY_GV.dbname['config_partner_catalog'].find_one_and_update(
{'_id': ObjectId(str(my_id)),
'partner_owner_recid': str(my_partner['recid'])},
{"$set": diction},
upsert=True,
return_document=ReturnDocument.AFTER
)
if( my_id ):
diction['date_update'] = str(datetime.now())
diction['update_by'] = str(my_partner['_id'])
result = MYSY_GV.dbname['config_partner_catalog'].find_one_and_update(
{'_id': ObjectId(str(my_id)),
'partner_owner_recid': str(my_partner['recid'])},
{"$set": diction},
upsert=True,
return_document=ReturnDocument.AFTER
)
if (result is None or "_id" not in result.keys()):
mycommon.myprint(
" Impossible d'ajouter ou mettre à jour la configuration du catalogue public (2) ")
return False, " Impossible d'ajouter ou mettre à jour la configuration du catalogue public (2) "
if (result is None or "_id" not in result.keys()):
mycommon.myprint(
" Impossible d'ajouter ou mettre à jour la configuration du catalogue public (2) ")
return False, " Impossible d'ajouter ou mettre à jour la configuration du catalogue public (2) "
else:
diction['valide'] = "1"
diction['locked'] = "0"
diction['partner_owner_recid'] = str(my_partner['recid'])
diction['date_update'] = str(datetime.now())
diction['update_by'] = str(my_partner['_id'])
result = MYSY_GV.dbname['config_partner_catalog'].insert_one(diction)
return True, " La configuration du catalogue a été correctement mis à jour"
@ -217,6 +232,7 @@ def Get_Partner_Catalog_Pub_Config(diction):
data_cle['valide'] = "1"
data_cle['locked'] = "0"
print(" ### data_cle = ", data_cle)
RetObject = []
val_tmp = 0
@ -244,7 +260,7 @@ def Get_Partner_Catalog_Pub_Config(diction):
RetObject.append(mycommon.JSONEncoder().encode(user))
#print(" ### RetObject = ", RetObject);
print(" ### Get_Partner_Catalog_Pub_Config = RetObject = ", RetObject);
return True, RetObject

View File

@ -2322,6 +2322,409 @@ def get_class(diction):
return False, " Impossible de récupérer la formation"
def get_class_for_partner_catalog(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 = ['internal_url', 'token', 'title', 'valide', 'locked', 'user_ip', 'user_country_code', 'user_country_name', 'user_city',
'user_postal', 'user_latitude', 'user_longitude', 'user_state', 'connection_type']
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, Creation formation annulée")
return False, " Impossible de récupérer la formation"
'''
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, " Impossible de récupérer la formation"
# recuperation des paramettre
mydata = {}
my_internal_url = ""
my_token = ""
if ("internal_url" in diction.keys()):
if diction['internal_url']:
my_internal_url = diction['internal_url']
if ("token" in diction.keys()):
if diction['token']:
my_token = diction['token']
client_connected_recid = ""
connection_type = ""
if ("connection_type" in diction.keys()):
if diction['connection_type']:
connection_type = diction['connection_type']
'''
Gestion des filters.
'''
internal_url_crit = {}
if ("internal_url" in diction.keys()):
if diction['internal_url']:
internal_url_crit['internal_url'] = diction['internal_url']
title_crit = {}
if ("title" in diction.keys()):
if diction['title']:
title_crit['title'] = diction['title']
coll_name = MYSY_GV.dbname['myclass']
# verifier que le token et l'email sont ok
coll_token = MYSY_GV.dbname['user_token']
# Verification de la validité du token dans le cas des user en mode connecté
'''
/!\ Important : si le token est vide, alors c'est une recherche faite en mode non-connecté.
on doit l'accepter.
le controle de la validé du token est faite que ce dernier n'est pas vide.
'''
user_recid = "None"
coll_search_result = MYSY_GV.dbname['user_recherche_result']
# Verification de la validité du token/mail dans le cas des user en mode connecté
if (len(str(my_token)) > 0 and str(connection_type).strip() == "user"):
retval = mycommon.check_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 la formation"
# Recuperation du recid de l'utilisateur
user_recid = mycommon.get_user_recid_from_token(my_token)
if user_recid is False:
mycommon.myprint(str(inspect.stack()[0][3])+" - Impossible de récupérer le token de l'utilisateur")
return False, " Impossible de récupérer la formation"
# Verification de la validité du token/mail dans le cas des partner en mode connecté
if (len(str(my_token)) > 0 and str(connection_type).strip() == "partner"):
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 "Err_Connexion", "La session de connexion n'est pas valide"
# Recuperation du recid de l'utilisateur
user_recid = mycommon.get_parnter_recid_from_token(my_token)
if user_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"
RetObject = []
filt_external_code = {}
internal_url = ""
if ("internal_url" in diction.keys()):
filt_external_code = {'internal_url':str(diction['internal_url'])}
internal_url = str(diction['internal_url'])
#print(' ICICICIC '+str(filt_external_code))
#print(" #### internal_url = ", internal_url)
qry_02 = {'valide':'1','locked':'0','internal_url':internal_url, }
#print(" #### qty_02 = ", qry_02)
# Recuperation des info du partenaire propriaitaire comme : ces certification (qualiopi, datadock, etc) et son nom
tmp_class_data = MYSY_GV.dbname['myclass'].find_one({'valide':'1','locked':'0','internal_url':internal_url, },
{"_id": 1, "partner_owner_recid": 1, } )
if( tmp_class_data is None or tmp_class_data["partner_owner_recid"] is None):
#print(' ### tmp_class_data =', str(tmp_class_data ))
mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données du partenaire - laa ")
return False, " Cette formation est indisponible "
#print(" ### la formation concernee est : ", tmp_class_data)
qry = {'active':'1','locked':'0','recid':str(tmp_class_data["partner_owner_recid"]) }
tmp_partenaire_data = MYSY_GV.dbname['partnair_account'].find_one(qry)
#print(" ### qry = ", qry)
if (tmp_partenaire_data is None or tmp_partenaire_data["_id"] is None):
mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données du partenaire (2) ")
return False, " Cette formation est indisponible (2) "
filt_title = {}
if ("title" in diction.keys()):
filt_title = {'title': {'$regex': str(diction['title']), "$options": "i"}}
print(" #### avant requete get partner_owner_recid laa yy= "+str(user_recid)+
" internal_url = "+str(my_internal_url)+
" filt_title = "+str(filt_title))
text_size = 0
"""
# Pour facilité l'affichage du front, on va créer une variable qui liste le nombre de pavé existant.
A date la liste des champs est : description, plus_produit, objectif, programme, prerequis, session, pourqui
"""
nb_pave_a_afficher = 0
connected_client_recid = ""
if (str(connection_type).strip() == "partner"):
connected_client_recid = user_recid
pipe = [
{'$match': {'internal_url': internal_url,}},
{'$project': { 'indexed': 0, 'indexed_desc': 0, 'indexed_obj': 0, "indexed_title": 0, "valide": 0,
"locked": 0}},
{'$lookup':
{
'from': 'business_prices',
'let': {'partner_owner_recid': "$partner_owner_recid", 'programme': '$programme'},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$partner_recid", "$$partner_owner_recid"]},
{'$eq': ["$client_recid", connected_client_recid]},
{'$eq': ["$valide", "1"]}
]
}
}
},
],
'as': 'business_prices'
}
}
]
print(" ### pipe myclass = ", pipe)
for retVal in coll_name.aggregate(pipe):
"""
for retVal in coll_name.find({'valide':'1','locked':'0','internal_url':internal_url, 'published':'1'},
{"_id": 0, "indexed": 0, "indexed_desc": 0, "indexed_obj": 0, "indexed_title": 0,
"valide": 0, "locked": 0, "partner_owner_recid": 0, }
).limit(1):
"""
#print('#### ICI retVal = '+str(retVal))
if ("business_prices" in retVal.keys()):
if(len(retVal['business_prices']) > 0 and "discount" in retVal['business_prices'][0].keys() ):
"""
Calcal du prix discounté
"""
#print(" ### discount = ", x['business_prices'][0]['discount'], " PRIX initial = ", x['price'])
local_discount = mycommon.tryFloat(str(retVal['business_prices'][0]['discount']))
local_initial_price = mycommon.tryFloat(str(retVal['price']))
local_discounted_price = round( local_initial_price - (local_initial_price * (local_discount/100)), 2)
retVal['business_prices'][0]['discounted_price'] = str(local_discounted_price)
#print(" #### local_discounted_price = ", local_discounted_price)
my_recid = {}
my_recid['user_rec_id'] = str(user_recid)
mydict_combined = {**diction, **retVal, **my_recid}
mydict_combined['date_update'] = str(datetime.now())
mydict_combined['type_view'] = "detail"
if ("_id" in mydict_combined.keys()):
mydict_combined['class_id'] = mydict_combined.pop('_id')
#mycommon.myprint("COMBINED = " + str(mydict_combined))
'''
Statistique : Insertion du recherche - resultat '''
ret_val_tmp = coll_search_result.insert_one(mydict_combined)
if (ret_val_tmp is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de mettre à jour la table des resultat"
" d'une recherche de formation. Voir _id = ")
return False, "Impossible de faire un affichage detaillé "
# Cette varible compte le nombre de certificat dont dispose le partenaire.
# Cette information est utilisée pour savoir les taille à afficher sur le front
nb_partner_certificat = 0
if( "isdatadock" in tmp_partenaire_data.keys() and tmp_partenaire_data['isdatadock']):
retVal['isdatadock'] = tmp_partenaire_data['isdatadock']
if (tmp_partenaire_data['isdatadock'] == "1"):
nb_partner_certificat = nb_partner_certificat + 1
if ("isqualiopi" in tmp_partenaire_data.keys() and tmp_partenaire_data['isqualiopi']):
retVal['isqualiopi'] = tmp_partenaire_data['isqualiopi']
if (tmp_partenaire_data['isqualiopi'] == "1"):
nb_partner_certificat = nb_partner_certificat + 1
if ("iscertitrace" in tmp_partenaire_data.keys() and tmp_partenaire_data['iscertitrace']):
retVal['iscertitrace'] = tmp_partenaire_data['iscertitrace']
if( tmp_partenaire_data['iscertitrace'] == "1"):
nb_partner_certificat = nb_partner_certificat + 1
if ("isbureaucertitrace" in tmp_partenaire_data.keys() and tmp_partenaire_data['isbureaucertitrace']):
retVal['isbureaucertitrace'] = tmp_partenaire_data['isbureaucertitrace']
if (tmp_partenaire_data['isbureaucertitrace'] == "1"):
nb_partner_certificat = nb_partner_certificat + 1
if ("iscertifvoltaire" in tmp_partenaire_data.keys() and tmp_partenaire_data['iscertifvoltaire']):
retVal['iscertifvoltaire'] = tmp_partenaire_data['iscertifvoltaire']
if (tmp_partenaire_data['iscertifvoltaire'] == "1"):
nb_partner_certificat = nb_partner_certificat + 1
retVal['nb_partner_certificat'] = str(nb_partner_certificat)
if ("nom" in tmp_partenaire_data.keys() and tmp_partenaire_data['nom']):
retVal['nom_partenaire'] = tmp_partenaire_data['nom']
if ("website" in tmp_partenaire_data.keys() and tmp_partenaire_data['website']):
retVal['website_partenaire'] = tmp_partenaire_data['website']
if ("description" in retVal.keys()):
tmp_str = retVal['description']
no_html = mycommon.cleanhtml(retVal['description'])
nb_pave_a_afficher = nb_pave_a_afficher + 1
text_size = text_size + len(str(no_html))
if (len(no_html) > MYSY_GV.MAX_CARACT_DETAIL):
retVal['description'] = no_html[:MYSY_GV.MAX_CARACT_DETAIL] + " ..."
if ("objectif" in retVal.keys()):
tmp_str = retVal['objectif']
no_html = mycommon.cleanhtml(retVal['objectif'])
text_size = text_size + len(str(no_html))
nb_pave_a_afficher = nb_pave_a_afficher + 1
if (len(no_html) > MYSY_GV.MAX_CARACT_DETAIL):
retVal['objectif'] = no_html[:MYSY_GV.MAX_CARACT_DETAIL] + " ..."
if ("pourqui" in retVal.keys() and retVal['pourqui']):
nb_pave_a_afficher = nb_pave_a_afficher + 1
if ("programme" in retVal.keys()):
tmp_str = retVal['programme']
no_html = mycommon.cleanhtml( retVal['programme'])
text_size = text_size + len(str(no_html))
nb_pave_a_afficher = nb_pave_a_afficher + 1
if (len(no_html) > MYSY_GV.MAX_CARACT_DETAIL):
retVal['programme'] = no_html[:MYSY_GV.MAX_CARACT_DETAIL] + " ..."
if ("methode_pedagogique" in retVal.keys()):
tmp_str = retVal['methode_pedagogique']
no_html = mycommon.cleanhtml( retVal['methode_pedagogique'])
text_size = text_size + len(str(no_html))
nb_pave_a_afficher = nb_pave_a_afficher + 1
if (len(no_html) > MYSY_GV.MAX_CARACT_DETAIL):
retVal['methode_pedagogique'] = no_html[:MYSY_GV.MAX_CARACT_DETAIL] + " ..."
if ("condition_handicape" in retVal.keys()):
tmp_str = retVal['condition_handicape']
no_html = mycommon.cleanhtml( retVal['condition_handicape'])
text_size = text_size + len(str(no_html))
nb_pave_a_afficher = nb_pave_a_afficher + 1
if (len(no_html) > MYSY_GV.MAX_CARACT_DETAIL):
retVal['condition_handicape'] = no_html[:MYSY_GV.MAX_CARACT_DETAIL] + " ..."
if ("suivi_eval" in retVal.keys()):
tmp_str = retVal['suivi_eval']
no_html = mycommon.cleanhtml( retVal['suivi_eval'])
text_size = text_size + len(str(no_html))
nb_pave_a_afficher = nb_pave_a_afficher + 1
if (len(no_html) > MYSY_GV.MAX_CARACT_DETAIL):
retVal['suivi_eval'] = no_html[:MYSY_GV.MAX_CARACT_DETAIL] + " ..."
if ("pedagogie" in retVal.keys()):
tmp_str = retVal['pedagogie']
no_html = mycommon.cleanhtml(retVal['pedagogie'])
if (len(no_html) > MYSY_GV.MAX_CARACT_DETAIL):
retVal['pedagogie'] = no_html[:MYSY_GV.MAX_CARACT_DETAIL] + " ..."
#retVal["text_size"] = str(text_size)
retVal["text_size"] = "1600"
"""
Verifier s'il y a des session des formations actives
"""
localmyquery = {}
localmyquery['class_internal_url'] = internal_url
localmyquery['valide'] = "1"
localmyquery['session_status'] = "true"
count_localmyquery = MYSY_GV.dbname['session_formation'].count_documents(localmyquery)
if( count_localmyquery > 0 ):
nb_pave_a_afficher = nb_pave_a_afficher + 1
print(" ### nb_pave_a_afficher , SESSION ")
retVal["nb_pave_a_afficher"] = str(nb_pave_a_afficher)
#print(" #### Pour la formation :",internal_url, " text_size = ", str(text_size))
#mycommon.myprint(" #### "+str(retVal))
user = retVal
if( "recyclage_delai" not in user.keys()):
user['recyclage_delai'] = ""
if ("recyclage_alert" not in user.keys()):
user['recyclage_alert'] = ""
if ("recyclage_periodicite" not in user.keys()):
user['recyclage_periodicite'] = ""
RetObject.append(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 formation"
'''
Cette API retour une formation "coup de coeur".
elle effectue les controles necessaires et retour la formation

View File

@ -3249,7 +3249,6 @@ def Prepare_and_Send_Email_From_Front(tab_files, Folder, diction):
"""
for user_id in tab_related_collection_id:
user_related_collection_data = MYSY_GV.dbname[str(related_collection)].find_one(
{"_id": ObjectId(str(user_id)),
'valide': '1',
@ -3269,14 +3268,30 @@ def Prepare_and_Send_Email_From_Front(tab_files, Folder, diction):
if ("email" in user_related_collection_data.keys()):
email = user_related_collection_data['email']
# Creation du dictionnaire d'information à utiliser pour la creation du doc
convention_dictionnary_data = {}
new_diction = {}
new_diction['token'] = my_partner['token']
new_diction['list_stagiaire_id'] = []
new_diction['list_session_id'] = []
new_diction['list_class_id'] = []
new_diction['list_client_id'] = []
local_status, local_retval = mycommon.Get_Dictionnary_data_For_Template(new_diction)
if (local_status is False):
return local_status, local_retval
convention_dictionnary_data = local_retval
node = {}
node['nom'] = nom
node['prenom'] = prenom
convention_dictionnary_data['nom'] = nom
convention_dictionnary_data['prenom'] = prenom
body = {
"params": node,
"params": convention_dictionnary_data,
}
# Creation de l'email à enoyer
# Creation de l'email à enoyer zzzz
msg = MIMEMultipart("alternative")
contenu_doc_Template = jinja2.Template(str(diction['email_corps']))

29
main.py
View File

@ -374,6 +374,17 @@ def get_class():
status, retval = cm.get_class(payload)
return jsonify(status=status, message=retval)
@app.route('/myclass/api/get_class_for_partner_catalog/', methods=['POST','GET'])
@crossdomain(origin='*')
def get_class_for_partner_catalog():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### get_class_for_partner_catalog : payload = ",str(payload)+" IP requester = "+str(request.remote_addr))
status, retval = cm.get_class_for_partner_catalog(payload)
return jsonify(status=status, message=retval)
"""
Cette API retourne les X formations du meme organisme de formations
associé à une formation données : current_internal_code
@ -612,6 +623,24 @@ def recherche_text_simple():
"""
25/08/2024 -
A l'image de la recherche_text_simple, cette fonction
fait une recheche pour la catalogue public du partner
DONC LA NOTION DE PUBLICATION (PUBLISH) NE DOIT PAS ETRE PRISE EN COMPTE
"""
@app.route('/myclass/api/recherche_text_simple_for_partner_catalog/', methods=['GET','POST'])
@crossdomain(origin='*')
def recherche_text_simple_for_partner_catalog():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### recherche_text_simple_for_partner_catalog : payload = ", payload)
status, result = wp.recherche_text_simple_for_partner_catalog(payload)
return jsonify(status=status, message=result)
# recherche globale
'''
fonction NON utilisée sur le front :

View File

@ -55,7 +55,8 @@ def add_partner_account(diction):
# field_list.
'''
field_list = ['nom', 'adr_street', 'adr_city', 'adr_zip', 'adr_country','link_linkedin','link_facebook','link_twitter',
'email','pwd', 'telephone','contact_nom','contact_prenom','contact_tel','contact_mail', 'pack_service']
'email','pwd', 'telephone','contact_nom','contact_prenom','contact_tel','contact_mail', 'pack_service',
'subdomaine_catalog_pub']
incom_keys = diction.keys()
for val in incom_keys:
@ -84,6 +85,12 @@ def add_partner_account(diction):
mydata['nom'] = diction['nom']
mydata['invoice_nom'] = diction['nom']
if ("subdomaine_catalog_pub" in diction.keys()):
mydata['subdomaine_catalog_pub'] = diction['subdomaine_catalog_pub']
if ("adr_street" in diction.keys()):
if diction['adr_street']:
mydata['adr_street'] = diction['adr_street']
@ -610,7 +617,7 @@ def update_partner_account(file_logo=None, file_cachet=None, Folder=None, dictio
'invoice_adr_country', 'invoice_email', 'invoice_telephone',
'siret', 'num_nda', 'iscertitrace', 'isdatadock', 'isqualiopi', 'website',
'isbureaucertitrace', 'iscertifvoltaire', 'file_logo_recid', 'file_cachet_recid',
'partner_account_id', 'invoice_taux_vat' ]
'partner_account_id', 'invoice_taux_vat', 'subdomaine_catalog_pub' ]
incom_keys = diction.keys()
@ -676,12 +683,16 @@ def update_partner_account(file_logo=None, file_cachet=None, Folder=None, dictio
partner_account_id = diction['is_partner_admin_account']
print(" #### partner_account_id = ", partner_account_id)
#print(" #### partner_account_id = ", partner_account_id)
mydata = {}
if ("nom" in diction.keys()):
mydata['nom'] = diction['nom']
if ("subdomaine_catalog_pub" in diction.keys()):
mydata['subdomaine_catalog_pub'] = diction['subdomaine_catalog_pub']
if ("adr_street" in diction.keys()):
mydata['adr_street'] = diction['adr_street']

View File

@ -6356,7 +6356,7 @@ def Get_Partner_Data_From_Subdomain(diction):
partnair_data_count = MYSY_GV.dbname['partnair_account'].count_documents({'nom':diction['subdomain'],
partnair_data_count = MYSY_GV.dbname['partnair_account'].count_documents({'subdomaine_catalog_pub':diction['subdomain'],
'active':'1',
'locked':'0',
'firstconnexion':'0'
@ -6370,7 +6370,7 @@ def Get_Partner_Data_From_Subdomain(diction):
val_tmp = 0
# print(" ### data_cle = ", data_cle)
for retval in MYSY_GV.dbname['partnair_account'].find({'nom': diction['subdomain'],
for retval in MYSY_GV.dbname['partnair_account'].find({'subdomaine_catalog_pub': diction['subdomain'],
'active': '1',
'locked': '0',
'firstconnexion': '0'

View File

@ -418,14 +418,14 @@ def get_all_class_Given_partner_owner_recid_No_Login(diction):
partner_owner_recid = ""
if( "subdomain" in diction.keys() and diction['subdomain']):
partnair_data_count = MYSY_GV.dbname['partnair_account'].count_documents({'nom': diction['subdomain'],
partnair_data_count = MYSY_GV.dbname['partnair_account'].count_documents({'subdomaine_catalog_pub': diction['subdomain'],
'active': '1',
'locked': '0',
'firstconnexion': '0'
})
if (partnair_data_count == 1):
partnair_data = MYSY_GV.dbname['partnair_account'].find_one({'nom': diction['subdomain'],
partnair_data = MYSY_GV.dbname['partnair_account'].find_one({'subdomaine_catalog_pub': diction['subdomain'],
'active': '1',
'locked': '0',
'firstconnexion': '0'
@ -493,7 +493,7 @@ def get_all_class_Given_partner_owner_recid_No_Login(diction):
connected_client_recid = user_recid
pipe = [{'$match':
{"$and": [{"$or": [{'valide': '1', 'locked': '0', 'isalaune': '1', 'published': '1'},
{"$and": [{"$or": [{'valide': '1', 'locked': '0', 'isalaune': '1', },
{'coeur': 1, 'published': '1'}]},
{'external_code': {'$nin': alread_found}},
{'display_rank': {'$nin': []}},
@ -534,7 +534,7 @@ def get_all_class_Given_partner_owner_recid_No_Login(diction):
"""
for x in coll_name.find(
{"$and": [{"$or": [{'valide': '1', 'locked': '0', 'isalaune': '1', 'published': '1'},
{"$and": [{"$or": [{'valide': '1', 'locked': '0', 'isalaune': '1', },
{'coeur': 1, 'published': '1'}]},
{'external_code': {'$nin': alread_found}}
]},
@ -744,7 +744,8 @@ def recherche_text_simple(diction):
'''
field_list = ['token', 'user_ip', 'user_country_code', 'user_country_name', 'user_city',
'user_postal', 'user_latitude', 'user_longitude', 'user_state', 'search_text', 'certif',
'support', 'type', 'lang', 'price', 'distance', 'duration', 'cpf', 'connection_type']
'support', 'type', 'lang', 'price', 'distance', 'duration', 'cpf', 'connection_type',
'subdomain']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
@ -1165,6 +1166,437 @@ def recherche_text_simple(diction):
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de lancer la recherche"
"""
25/08/2024 -
A l'image de la recherche_text_simple, cette fonction
fait une recheche pour la catalogue public du partner
DONC LA NOTION DE PUBLICATION (PUBLISH) NE DOIT PAS ETRE PRISE EN COMPTE
"""
def recherche_text_simple_for_partner_catalog(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', 'user_ip', 'user_country_code', 'user_country_name', 'user_city',
'user_postal', 'user_latitude', 'user_longitude', 'user_state', 'search_text', 'certif',
'support', 'type', 'lang', 'price', 'distance', 'duration', 'cpf', 'connection_type',
'subdomain']
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, recherche annuléee")
return False, " Le champ '" + val + "' n'existe pas, recherche annulée"
'''
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 = ['search_text', '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, " : La valeur '" + val + "' n'est pas presente dans liste "
# recuperation des paramettre
search_text = ""
user_recid = ""
token = ""
critere_date = {}
critere_string = ""
new_diction = {}
new_diction['token'] = ""
if ("search_text" in diction.keys()):
if diction['search_text']:
search_text = diction['search_text']
if ("token" in diction.keys()):
if diction['token']:
token = diction['token']
new_diction['token'] = diction['token']
connection_type = ""
if ("connection_type" in diction.keys()):
if diction['connection_type']:
connection_type = diction['connection_type']
'''
Recuperation de donnée du user connecté si connexion (user ou partner)
/!\ Important : si le token est vide, alors c'est une recherche faite en mode non-connecté.
on doit l'accepter.
Si non le champ "connection_type" permet de savoir si c'est un user ou un partner
le controle de la validé du token est faite que ce dernier n'est pas vide.
'''
user_recid = "None"
coll_search_result = MYSY_GV.dbname['user_recherche_result']
# Verification de la validité du token/mail dans le cas des user en mode connecté
if (len(str(token)) > 0 and str(connection_type).strip() == "user"):
retval = mycommon.check_token_validity("", token)
if retval is False:
mycommon.myprint(str(inspect.stack()[0][3]) + " - La session de connexion n'est pas valide")
return "Err_Connexion", "La session de connexion n'est pas valide"
# Recuperation du recid de l'utilisateur
user_recid = mycommon.get_user_recid_from_token(token)
if user_recid is False:
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer le token de l'utilisateur")
return False, " Impossible de récupérer le token de l'utilisateur"
# Verification de la validité du token/mail dans le cas des partner en mode connecté
if (len(str(token)) > 0 and str(connection_type).strip() == "partner"):
retval = mycommon.check_partner_token_validity("", token)
if retval is False:
mycommon.myprint(str(inspect.stack()[0][3]) + " - La session de connexion n'est pas valide")
return "Err_Connexion", "La session de connexion n'est pas valide"
# Recuperation du recid de l'utilisateur
user_recid = mycommon.get_parnter_recid_from_token(token)
if user_recid is False:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - Impossible de récupérer le token de l'utilisateur")
return False, " Impossible de récupérer le token de l'utilisateur"
# mycommon.myprint(" On recehrche la phrase +'" + search_text + "' + user_recid = "+user_recid)
# Enregistrerment de la recherche
retval, message, store_recherche_Id = store_recherche(diction, user_recid)
if (retval is False):
return retval, message
'''
Verification si le texte de recherche contient un pattern de tips,
c'est a dire une chaine de type : title:"titre"
Si c'est le cas, nous sommes dans le cadre d'un recherche par type
'''
cleaned_search_text = mycommon.Parse_Clean_Search_Text(search_text)
print(" NOT CLEANED search_text = " + str(search_text))
print(" CLEANED search_text = " + str(cleaned_search_text))
regexp = r"[\w\.-]+:\"[\w\s]*\""
tips = re.findall(regexp, str(cleaned_search_text), re.MULTILINE)
nb_tips = len(tips)
final_message3 = {}
if (nb_tips > 0):
mycommon.myprint(" Une recherche par tips a été identifiée")
new_diction['token'] = token
# Traitement pour chaque recherche par tips
final_retval = False
final_message = []
insertObject = []
is_first_tip = True
for val in tips:
val2 = val.replace('"', '')
new_diction['search_text'] = val2
print(" On va recherche : #####" + str(new_diction['search_text']))
retval, message = recherche_tips_ret_ref(new_diction)
print(" pour la recherche de : " + str(new_diction) + " -- Voici le resultat " + str(message))
if (retval == True):
final_retval = True
# print(" contact de message "+str(message)+ " # final_message "+str(final_message))
if (is_first_tip is True):
final_message3 = message
else:
final_message3 = [x for x in message if x in final_message3]
print(" final_message3 = " + str(final_message3))
final_message.append(message)
is_first_tip = False
final_message = final_message3
# print(" liste defitive des ref "+str(final_message))
final_message2 = []
for t in final_message:
if (t is not False):
# print( " unique = "+str(t))
final_message2.append(t)
coll_name = MYSY_GV.dbname['myclass']
'''
A present mise à jour de la table "user_recherche" avec les resultats trouvés
'''
# store_recherche_Id
find_result = {'find_result': str(final_message2)}
tab_user_recherche = MYSY_GV.dbname['user_recherche']
# seules les formations avec locked = 0 et valide=1 sont modifiables
# print(str(inspect.stack()[0][3]) + " ENREG DES RESULT :"+str(store_recherche_Id)+" --- "+str(final_message2))
ret_val_user_rech = coll_name.find_one_and_update(
{'_id': ObjectId(store_recherche_Id)},
{"$set": find_result},
return_document=ReturnDocument.AFTER
)
if (ret_val_user_rech is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de mettre à jour la table des resultat"
" d'une recherche de formation. Voir _id = " + str(
store_recherche_Id))
return False, "La recheche est impossible "
'''
la valeur nb_result permettra de savoir si la requete a donnée un resultat.
si ce n'est pas le cas, il faudra à la fin enregistrer la requete avec un result a vide'''
nb_result = 0
for x in coll_name.find({"external_code": {"$in": final_message2}, },
{"indexed": 0, "indexed_desc": 0, "indexed_obj": 0,
"indexed_title": 0, "valide": 0, "locked": 0, }). \
sort([("display_rank", pymongo.DESCENDING), ("price", pymongo.ASCENDING),
("date_update", pymongo.DESCENDING), ]):
nb_result = nb_result + 1
my_recid = {}
my_recid['user_rec_id'] = str(user_recid)
mydict_combined = {**diction, **x, **my_recid}
mydict_combined['date_update'] = str(datetime.now())
mydict_combined['type_view'] = "summary"
if ("_id" in mydict_combined.keys()):
mydict_combined['class_id'] = mydict_combined.pop('_id')
# mycommon.myprint("COMBINED = " + str(mydict_combined))
'''
Statistique : Insertion du recherche - resultat '''
ret_val_tmp = coll_search_result.insert_one(mydict_combined)
if (ret_val_tmp is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de mettre à jour la table des resultat"
" d'une recherche de formation. Voir _id = ")
return False, "La recheche est impossible "
user = x
val = x['description']
no_html = mycommon.cleanhtml(x['description'])
if (len(no_html) > MYSY_GV.MAX_CARACT):
x['description'] = no_html[:MYSY_GV.MAX_CARACT] + " ..."
else:
x['description'] = no_html
insertObject.append(JSONEncoder().encode(user))
# mycommon.myprint(" insertObject = ", insertObject)
''' en cas de resultat vide, enregsitrement de la requete de recherche avec les filtres associé'''
if (nb_result == 0):
my_recid = {}
my_recid['user_rec_id'] = str(user_recid)
mydict_combined = {**diction, **my_recid}
mydict_combined['date_update'] = str(datetime.now())
mydict_combined['type_view'] = "summary"
'''
Statistique : Insertion du recherche - resultat '''
ret_val_tmp = coll_search_result.insert_one(mydict_combined)
if (ret_val_tmp is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de mettre à jour la table des resultat"
" d'une recherche de formation. Voir _id = ")
return False, "La recheche est impossible "
return True, insertObject
# Fin de la recherche par tips.
tab_training = []
tab_training = ela_index.ela_recherche_tokens(search_text)
'''
pour analyser la recherche, decommenter les 2 lignes ci-dessous
'''
mycommon.myprint(" pour phrase : #" + search_text + "#, voici la liste des formations")
mycommon.myprint(tab_training)
coll_name = MYSY_GV.dbname['myclass']
'''
la valeur nb_result permettra de savoir si la requete a donnée un resultat.
si ce n'est pas le cas, il faudra à la fin enregistrer la requete avec un result a vide'''
nb_result = 0
insertObject = []
connected_client_recid = ""
if (str(connection_type).strip() == "partner"):
connected_client_recid = user_recid
"""
23/02/2023 : FIN Uniquement pour des raisons de tests
"""
"""
for x in coll_name.find({"external_code":{"$in":tab_training}, 'published':'1'},
{"_id": 0, "indexed": 0, "indexed_desc": 0,
"indexed_obj": 0, "indexed_title": 0, "valide": 0,
"locked": 0 }).sort([("display_rank", pymongo.DESCENDING), ("price", pymongo.ASCENDING), ("date_update", pymongo.DESCENDING), ]):
"""
pipe = [
{'$match': {'external_code': {"$in": tab_training}, }},
{'$project': {'_id': 0, 'indexed': 0, 'indexed_desc': 0, 'indexed_obj': 0, "indexed_title": 0, "valide": 0,
"locked": 0}},
{'$lookup':
{
'from': 'business_prices',
'let': {'partner_owner_recid': "$partner_owner_recid", 'programme': '$programme'},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$partner_recid", "$$partner_owner_recid"]},
{'$eq': ["$client_recid", connected_client_recid]},
{'$eq': ["$valide", "1"]}
]
}
}
},
],
'as': 'business_prices'
}
},
{'$sort': {"display_rank": pymongo.DESCENDING, "price": pymongo.ASCENDING,
"date_update": pymongo.DESCENDING}},
]
print(" ### pipe recherche_text_simple = ", pipe)
for x in coll_name.aggregate(pipe):
nb_result = nb_result + 1
if ("business_prices" in x.keys()):
# print(" ### business_prices = ", x['business_prices'], " len(x['business_prices']) = ", len(x['business_prices']))
if (len(x['business_prices']) > 0 and "discount" in x['business_prices'][0].keys()):
"""
Calcal du prix discounté
"""
# print(" ### discount = ", x['business_prices'][0]['discount'], " PRIX initial = ", x['price'])
local_discount = mycommon.tryFloat(str(x['business_prices'][0]['discount']))
local_initial_price = mycommon.tryFloat(str(x['price']))
local_discounted_price = round(local_initial_price - (local_initial_price * (local_discount / 100)),
2)
x['business_prices'][0]['discounted_price'] = str(local_discounted_price)
# print(" #### local_discounted_price = ", local_discounted_price)
my_recid = {}
my_recid['user_rec_id'] = str(user_recid)
# print(" XXXXXXXXXX = "+str(x))
mydict_combined = {**diction, **x, **my_recid}
mydict_combined['date_update'] = str(datetime.now())
mydict_combined['type_view'] = "summary"
# print( "mydict_combined YYYYYYYYY = "+str(mydict_combined))
if ("_id" in mydict_combined.keys()):
mydict_combined['class_id'] = mydict_combined.pop('_id')
'''
Statistique : Insertion du recherche - resultat '''
ret_val_tmp = coll_search_result.insert_one(mydict_combined)
if (ret_val_tmp is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de mettre à jour la table des resultat"
" d'une recherche de formation. Voir _id = ")
return False, "La recheche est impossible "
user = x
val = mycommon.clean_emoji(str(x['description']))
no_html = mycommon.cleanhtml(val)
if (len(no_html) > MYSY_GV.MAX_CARACT):
x['description'] = no_html[:MYSY_GV.MAX_CARACT] + " ..."
else:
x['description'] = no_html
insertObject.append(JSONEncoder().encode(user))
'''
/!\ Important : Recuperation des elements de la recherche etendue
c'est a dire l'utilisation d'API externe
/!\ update du 20/05/22 : Cette approche relentie bcp le systeme avec l'appel externe.
donc on annule
# aller chercher la recherche etendue et la rajouter ici.
ext_status, external_code_prefixe = mycommon.Get_Extended_Result(search_text)
if(ext_status is True):
exten_coll = MYSY_GV.YTUBES_dbname['mysyserpapi']
for x in exten_coll.find({'external_code': {'$regex': re.compile(r".*" + str(external_code_prefixe) + ".*")}},
{"_id": 0, "valide": 0, }):
nb_result = nb_result + 1
my_recid = {}
my_recid['user_rec_id'] = str(user_recid)
user = x
val = x['description']
if (len(x['description']) > MYSY_GV.MAX_CARACT):
x['description'] = val[:MYSY_GV.MAX_CARACT] + " ..."
else:
x['description'] = val[:MYSY_GV.MAX_CARACT]
x['extented_search'] = "1"
if str(x['url']) not in str(insertObject):
insertObject.append(JSONEncoder().encode(user))
else:
print(str(x['url'])+" existe deja, pas d'ajout à faire ")
'''
# print("#### #", insertObject)
# print(" result ok ")
''' en cas de resultat vide, enregsitrement de la requete de recherche avec les filtres associé'''
if (nb_result == 0):
my_recid = {}
my_recid['user_rec_id'] = str(user_recid)
mydict_combined = {**diction, **my_recid}
mydict_combined['date_update'] = str(datetime.now())
mydict_combined['type_view'] = "summary"
'''
Statistique : Insertion du recherche - resultat '''
ret_val_tmp = coll_search_result.insert_one(mydict_combined)
if (ret_val_tmp is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de mettre à jour la table des resultat"
" d'une recherche de formation. Voir _id = ")
return False, "La recheche est impossible "
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 lancer la recherche"
'''
@ -1207,7 +1639,8 @@ def store_recherche(diction, user_recid=""):
field_list = ['token', 'user_ip', 'user_country_code', 'user_country_name', 'user_city',
'user_postal', 'user_latitude', 'user_longitude', 'user_state', 'search_text', 'certif',
'support', 'type', 'lang', 'price', 'distance', 'duration', 'cpf', 'connection_type']
'support', 'type', 'lang', 'price', 'distance', 'duration', 'cpf', 'connection_type',
'subdomain']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False: