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"> <project version="4">
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="ddd"> <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$/.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$/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$/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$/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> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <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" order_header_montant_reduction = "0"
partner_invoice_header_data['order_header_montant_reduction'] = order_header_montant_reduction 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 # Calcul du Totol HT sans reduction
total_ht = 0 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 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 05/06/2024 Gestion E-Facture
Apres la creation de la facture, on va aller créer le document securisé 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'] 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 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" order_header_montant_reduction = "0"
partner_invoice_header_data['order_header_montant_reduction'] = order_header_montant_reduction 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()) now = str(datetime.now())
tab_date_invoice.append(str(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 05/06/2024 Gestion E-Facture
Apres la creation de la facture, on va aller créer le document securisé 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['_id']
del diction['token'] del diction['token']
result = MYSY_GV.dbname['config_partner_catalog'].find_one_and_update( if( my_id ):
{'_id': ObjectId(str(my_id)), diction['date_update'] = str(datetime.now())
'partner_owner_recid': str(my_partner['recid'])}, diction['update_by'] = str(my_partner['_id'])
{"$set": diction}, result = MYSY_GV.dbname['config_partner_catalog'].find_one_and_update(
upsert=True, {'_id': ObjectId(str(my_id)),
return_document=ReturnDocument.AFTER '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()): if (result is None or "_id" not in result.keys()):
mycommon.myprint( mycommon.myprint(
" Impossible d'ajouter ou mettre à jour la configuration du catalogue public (2) ") " 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) " 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" 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['valide'] = "1"
data_cle['locked'] = "0" data_cle['locked'] = "0"
print(" ### data_cle = ", data_cle)
RetObject = [] RetObject = []
val_tmp = 0 val_tmp = 0
@ -244,7 +260,7 @@ def Get_Partner_Catalog_Pub_Config(diction):
RetObject.append(mycommon.JSONEncoder().encode(user)) RetObject.append(mycommon.JSONEncoder().encode(user))
#print(" ### RetObject = ", RetObject); print(" ### Get_Partner_Catalog_Pub_Config = RetObject = ", RetObject);
return True, RetObject return True, RetObject

View File

@ -2322,6 +2322,409 @@ def get_class(diction):
return False, " Impossible de récupérer la formation" 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". Cette API retour une formation "coup de coeur".
elle effectue les controles necessaires et retour la formation 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: for user_id in tab_related_collection_id:
user_related_collection_data = MYSY_GV.dbname[str(related_collection)].find_one( user_related_collection_data = MYSY_GV.dbname[str(related_collection)].find_one(
{"_id": ObjectId(str(user_id)), {"_id": ObjectId(str(user_id)),
'valide': '1', '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()): if ("email" in user_related_collection_data.keys()):
email = user_related_collection_data['email'] 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 = {}
node['nom'] = nom convention_dictionnary_data['nom'] = nom
node['prenom'] = prenom convention_dictionnary_data['prenom'] = prenom
body = { body = {
"params": node, "params": convention_dictionnary_data,
} }
# Creation de l'email à enoyer # Creation de l'email à enoyer zzzz
msg = MIMEMultipart("alternative") msg = MIMEMultipart("alternative")
contenu_doc_Template = jinja2.Template(str(diction['email_corps'])) 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) status, retval = cm.get_class(payload)
return jsonify(status=status, message=retval) 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 Cette API retourne les X formations du meme organisme de formations
associé à une formation données : current_internal_code 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 # recherche globale
''' '''
fonction NON utilisée sur le front : fonction NON utilisée sur le front :

View File

@ -55,7 +55,8 @@ def add_partner_account(diction):
# field_list. # field_list.
''' '''
field_list = ['nom', 'adr_street', 'adr_city', 'adr_zip', 'adr_country','link_linkedin','link_facebook','link_twitter', 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() incom_keys = diction.keys()
for val in incom_keys: for val in incom_keys:
@ -84,6 +85,12 @@ def add_partner_account(diction):
mydata['nom'] = diction['nom'] mydata['nom'] = diction['nom']
mydata['invoice_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 ("adr_street" in diction.keys()):
if diction['adr_street']: if diction['adr_street']:
mydata['adr_street'] = 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', 'invoice_adr_country', 'invoice_email', 'invoice_telephone',
'siret', 'num_nda', 'iscertitrace', 'isdatadock', 'isqualiopi', 'website', 'siret', 'num_nda', 'iscertitrace', 'isdatadock', 'isqualiopi', 'website',
'isbureaucertitrace', 'iscertifvoltaire', 'file_logo_recid', 'file_cachet_recid', '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() 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'] partner_account_id = diction['is_partner_admin_account']
print(" #### partner_account_id = ", partner_account_id) #print(" #### partner_account_id = ", partner_account_id)
mydata = {} mydata = {}
if ("nom" in diction.keys()): if ("nom" in diction.keys()):
mydata['nom'] = diction['nom'] 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()): if ("adr_street" in diction.keys()):
mydata['adr_street'] = diction['adr_street'] 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', 'active':'1',
'locked':'0', 'locked':'0',
'firstconnexion':'0' 'firstconnexion':'0'
@ -6370,7 +6370,7 @@ def Get_Partner_Data_From_Subdomain(diction):
val_tmp = 0 val_tmp = 0
# print(" ### data_cle = ", data_cle) # 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', 'active': '1',
'locked': '0', 'locked': '0',
'firstconnexion': '0' 'firstconnexion': '0'

View File

@ -418,14 +418,14 @@ def get_all_class_Given_partner_owner_recid_No_Login(diction):
partner_owner_recid = "" partner_owner_recid = ""
if( "subdomain" in diction.keys() and diction['subdomain']): 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', 'active': '1',
'locked': '0', 'locked': '0',
'firstconnexion': '0' 'firstconnexion': '0'
}) })
if (partnair_data_count == 1): 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', 'active': '1',
'locked': '0', 'locked': '0',
'firstconnexion': '0' 'firstconnexion': '0'
@ -493,7 +493,7 @@ def get_all_class_Given_partner_owner_recid_No_Login(diction):
connected_client_recid = user_recid connected_client_recid = user_recid
pipe = [{'$match': pipe = [{'$match':
{"$and": [{"$or": [{'valide': '1', 'locked': '0', 'isalaune': '1', 'published': '1'}, {"$and": [{"$or": [{'valide': '1', 'locked': '0', 'isalaune': '1', },
{'coeur': 1, 'published': '1'}]}, {'coeur': 1, 'published': '1'}]},
{'external_code': {'$nin': alread_found}}, {'external_code': {'$nin': alread_found}},
{'display_rank': {'$nin': []}}, {'display_rank': {'$nin': []}},
@ -534,7 +534,7 @@ def get_all_class_Given_partner_owner_recid_No_Login(diction):
""" """
for x in coll_name.find( 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'}]}, {'coeur': 1, 'published': '1'}]},
{'external_code': {'$nin': alread_found}} {'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', field_list = ['token', 'user_ip', 'user_country_code', 'user_country_name', 'user_city',
'user_postal', 'user_latitude', 'user_longitude', 'user_state', 'search_text', 'certif', '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() incom_keys = diction.keys()
for val in incom_keys: for val in incom_keys:
if val not in field_list and val.startswith('my_') is False: 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)) mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de lancer la recherche" 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', field_list = ['token', 'user_ip', 'user_country_code', 'user_country_name', 'user_city',
'user_postal', 'user_latitude', 'user_longitude', 'user_state', 'search_text', 'certif', '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() incom_keys = diction.keys()
for val in incom_keys: for val in incom_keys:
if val not in field_list and val.startswith('my_') is False: if val not in field_list and val.startswith('my_') is False: