Elyos_FI_Back_Office/Session_Formation.py

14810 lines
724 KiB
Python

"""
Ce fichier gere les sessions de formation
"""
import ast
import smtplib
from email import encoders
from email.mime.base import MIMEBase
from calendar import monthrange
import jinja2
import pymongo
from flask import send_file
from pymongo import MongoClient
import json
from bson import ObjectId
import re
from datetime import datetime, date
from xhtml2pdf import pisa
import Contact
import E_Sign_Document
import Session_Formation_Sequence
import attached_file_mgt
import module_editique
import partner_client
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 Inscription_mgt as Inscription_mgt
from zipfile import ZipFile
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import partner_base_setup as partner_base_setup
"""
Fonction de creation et mise à jour d'une session de formation.
/!\ : le champ 'source' definit la source de la creation de la session
si le champ 'session_id' est renseigné alors c'est une mise à jour.
"""
def Add_Update_SessionFormation(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', 'date_debut', 'date_fin', 'nb_participant', 'adresse',
'code_postal', 'ville', 'code_session',
'class_internal_url', 'session_status', 'date_debut_inscription', 'date_fin_inscription',
'attestation_certif', "distantiel", "presentiel", "prix_session", 'contenu_ftion', 'lms_class_code',
'session_ondemande', 'source', 'session_id', 'session_etape', 'pays', 'formateur_id',
'titre', 'location_type', 'is_bpf', 'site_formation_id', 'price_by', 'mode_animation']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé.")
return False, " Toutes les informations fournies ne sont pas valables"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', 'class_internal_url','code_session']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, "Toutes les informations necessaires n'ont pas été fournies"
mydata = {}
query_key = {}
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_token = diction['token']
# Verifier la validité du token
retval = mycommon.check_partner_token_validity("", my_token)
if retval is False:
return "Err_Connexion", " La session de connexion n'est pas valide"
data_for_check_connexion = {'token':my_token}
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(data_for_check_connexion)
if (local_status is not True):
return local_status, my_partner
session_id = ""
if ("session_id" in diction.keys()):
session_id = diction['session_id']
code_session = ""
if ("code_session" in diction.keys()):
mydata['code_session'] = diction['code_session']
query_key['code_session'] = diction['code_session']
class_internal_url = ""
if ("class_internal_url" in diction.keys()):
mydata['class_internal_url'] = diction['class_internal_url']
class_internal_url = diction['class_internal_url']
query_key['class_internal_url'] = diction['class_internal_url']
class_source = ""
if ("source" in diction.keys()):
if diction['source']:
class_source = diction['source']
partner_recid = mycommon.get_parnter_recid_from_token(my_token)
if (partner_recid is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer les données du partenaire ")
return False, "Impossible de récupérer les données du partenaire "
"""
update du 20/08/23 :
on ajouter un champs 'owner_recid' a la session.
en effet 2 partenaire peuvent avoir exactement la meme formation et les memes code session.
il faut arriver à les distinguer tout de meme
"""
mydata['partner_owner_recid'] = str(partner_recid)
if ("date_debut" in diction.keys()):
mydata['date_debut'] = str(diction['date_debut'])[0:10]
etape = ""
if ("session_etape" in diction.keys()):
etape = str(diction['session_etape'])
mydata['session_etape'] = etape
if ("date_fin" in diction.keys()):
mydata['date_fin'] = str(diction['date_fin'])[0:10]
if ("distantiel" in diction.keys()):
mydata['distantiel'] = str(mycommon.tryInt(str(diction['distantiel'])))
else:
mydata['distantiel'] = "0"
if ("presentiel" in diction.keys()):
mydata['presentiel'] = str(mycommon.tryInt(str(diction['presentiel'])))
else:
mydata['presentiel'] = "0"
"""
Pour le mode d'animation d'une session de formation, on a :
0 => Présentiel
1 => Distanciel
2 => Hybride
"""
if ("mode_animation" in diction.keys() and diction['mode_animation'] in ['0', '1', '2']):
mydata['mode_animation'] = str(diction['mode_animation'])
else:
mydata['mode_animation'] = "0"
if ("session_ondemande" in diction.keys()):
mydata['session_ondemande'] = str(mycommon.tryInt(str(diction['session_ondemande'])))
else:
mydata['session_ondemande'] = "0"
if ("nb_participant" in diction.keys()):
nb_particants = str(mycommon.tryInt(str(diction['nb_participant'])))
if( nb_particants == "0" ):
nb_particants = "1"
mydata['nb_participant'] = str(mycommon.tryInt(str(diction['nb_participant'])))
else:
mydata['nb_participant'] = "1"
if ("prix_session" in diction.keys()):
mydata['prix_session'] = diction['prix_session']
if ("price_by" in diction.keys()):
if( str(diction['price_by']) not in MYSY_GV.TRAINING_PRICE):
mycommon.myprint(str(inspect.stack()[0][3]) + " Le prix par "+str(diction['price_by'])+" n'est valide. Les valeurs autorisées sont "+str(MYSY_GV.TRAINING_PRICE) )
return False, " Le prix par "+str(diction['price_by'])+" n'est valide. Les valeurs autorisées sont "+str(MYSY_GV.TRAINING_PRICE)+" "
mydata['price_by'] = diction['price_by']
else:
mydata['price_by'] = "perstagiaire"
if ("titre" in diction.keys()):
mydata['titre'] = diction['titre']
else:
mydata['titre'] = ""
if ("site_formation_id" in diction.keys()):
mydata['site_formation_id'] = diction['site_formation_id']
else:
mydata['site_formation_id'] = ""
if ("location_type" in diction.keys()):
mydata['location_type'] = str(diction['location_type']).lower()
if (str(diction['location_type']).lower() not in MYSY_GV.TRAINING_LOCATION_TYPE):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Le champ 'location_type' est incorrecte.")
return False, "Le champ 'location_type' est incorrect."
if ("is_bpf" in diction.keys()):
if( str(diction['is_bpf']) not in ['0', '1']):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Le champ 'bpf' est incorrect. Les valeurs acceptées sont : '1' ou '0' ")
return False, "Le champ 'bpf' est incorrect. Les valeurs acceptées sont : '1' ou '0' "
mydata['is_bpf'] = diction['is_bpf']
formateur_id = ""
if ("formateur_id" in diction.keys() and diction['formateur_id']):
formateur_id = diction['formateur_id']
# Verification de la validité du formateur (collection employé)
is_formateur_id_ok = MYSY_GV.dbname['ressource_humaine'].count_documents({'_id':ObjectId(str(formateur_id)),
'partner_recid':str(partner_recid),
'valide':'1',
'locked':'0'
})
if(is_formateur_id_ok <= 0 ):
mycommon.myprint(str(inspect.stack()[0][3]) + " - L'identifiant du formateur est invalide")
return False, " L'identifiant du formateur est invalide "
mydata['formateur_id'] = formateur_id
if ("adresse" in diction.keys()):
if diction['adresse']:
mydata['adresse'] = diction['adresse']
else:
mydata['adresse'] = " "
if ("code_postal" in diction.keys()):
if diction['code_postal']:
if( "." in str(diction['code_postal']) ):
#/!\ : l'utilisateur envoie un code poster au format entier, plutot que string.
mydata['code_postal'] = str(diction['code_postal']).split(".")[0]
elif( "." in str(diction['code_postal']) ):
#/!\ : l'utilisateur envoie un code poster au format entier, plutot que string.
mydata['code_postal'] = str(diction['code_postal']).split(",")[0]
else:
mydata['code_postal'] = str(diction['code_postal'])
else:
mydata['code_postal'] = ""
if ("ville" in diction.keys()):
if diction['ville']:
mydata['ville'] = diction['ville']
else:
mydata['ville'] = ""
if ("pays" in diction.keys()):
if diction['pays']:
mydata['pays'] = diction['pays']
else:
mydata['pays'] = ""
"""
if ("attestation_certif" in diction.keys()):
mydata['attestation_certif'] = diction['attestation_certif']
"""
if ("session_status" in diction.keys()):
mydata['session_status'] = str(mycommon.tryInt(str(diction['session_status'])))
else:
mydata['session_status'] = ""
if ("date_debut_inscription" in diction.keys()):
mydata['date_debut_inscription'] = str(diction['date_debut_inscription'])[0:10]
else:
mydata['date_debut_inscription'] = ""
if ("date_fin_inscription" in diction.keys()):
mydata['date_fin_inscription'] = str(diction['date_fin_inscription'])[0:10]
else:
mydata['date_fin_inscription'] = ""
""""
if ("formateur" in diction.keys()):
mydata['formateur'] = diction['formateur']
"""
if ("contenu_ftion" in diction.keys()):
mydata['contenu_ftion'] = diction['contenu_ftion']
else:
mydata['contenu_ftion'] = ""
"""
Update du 22/10/2023 - Gestion des champs spécifiques ajoutés par le partenaire
"""
# Recuperation des champs spécifiques se trouvant dans le dictionnaire. ils commencent tous par 'my_'
for val in diction.keys():
if (val.startswith('my_')):
if (MYSY_GV.dbname['base_specific_fields'].count_documents(
{'partner_owner_recid': str(partner_recid),
'related_collection': 'session_formation',
'field_name': str(val),
'valide': '1',
'locked': '0'}) != 1):
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ")
return False, " Les informations fournies sont incorrectes"
mydata[str(val)] = diction[str(val)]
mydata['date_update'] = str(datetime.now())
mydata['update_by'] = str(my_partner['_id'])
mydata['valide'] = "1"
# Controle de cohérence sur les dates
local_status = mycommon.CheckisDate(str(diction['date_debut'])[0:10])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Formation : "+str(code_session)+" : Impossible de créer/mettre à jour la session de formation. La date de debut n'est pas au format jj/mm/aaaa ")
return False, " - Formation : "+str(code_session)+" : Impossible de créer/mettre à jour la session de formation. La date de debut n'est pas au format jj/mm/aaaa "
local_status = mycommon.CheckisDate(str(diction['date_fin'])[0:10])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " -Formation : "+str(code_session)+" : Impossible de créer/mettre à jour la session de formation. La date de fin n'est pas au format jj/mm/aaaa ")
return False, " -Formation : "+str(code_session)+" : La date de fin n'est pas au format jj/mm/aaaa "
if (datetime.strptime(str(diction['date_debut'])[0:10], '%d/%m/%Y') > datetime.strptime(str(diction['date_fin'])[0:10], '%d/%m/%Y')):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Session de Formation : La date debut " + str(
diction['date_debut'])[0:10] +
" est postérieure à la date de fin " + str(diction['date_fin'])[0:10] )
return False, " Session de Formation : La date debut de formation " + str(diction['date_debut'])[0:10] + \
" est postérieure à la date de fin de formation " + str(diction['date_fin'])[0:10] + " "
# Verification de la cohérence des dates d'inscription si on a bien une date debut et une date de fin
if( "date_debut_inscription" in diction.keys() and "date_fin_inscription" in diction.keys() ):
if (str(diction['date_debut_inscription']).strip() != "" and str(
diction['date_fin_inscription']).strip() != ""):
local_status = mycommon.CheckisDate(str(diction['date_debut_inscription'])[0:10])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Formation : " + str(
code_session) + " : Impossible de créer/mettre à jour la session de formation. La date_debut_inscription n'est pas au format jj/mm/aaaa ")
return False, " -Formation : " + str(
code_session) + " : La date de début d'inscription n'est pas au format jj/mm/aaaa "
local_status = mycommon.CheckisDate(str(diction['date_fin_inscription'])[0:10])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " -Formation : " + str(
code_session) + " : La date de fin d'inscription n'est pas au format jj/mm/aaaa ")
return False, " - Formation : " + str(
code_session) + " :La date de fin d'inscription n'est pas au format jj/mm/aaaa "
if (datetime.strptime(str(diction['date_debut_inscription'])[0:10], '%d/%m/%Y') > datetime.strptime(
str(diction['date_fin_inscription'])[0:10], '%d/%m/%Y')):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Formation : "+str(code_session)+" : La date de début d'inscription " + str(diction['date_debut_inscription'])[0:10] + \
" est postérieure à la date de fin d'inscription " + str(diction['date_fin_inscription'])[0:10] + " " )
return False, " Formation : "+str(code_session)+" : La date de début d'inscription " + str(diction['date_debut_inscription'])[0:10] + \
" est postérieure à la date de fin d'inscription " + str(diction['date_fin_inscription'])[0:10] + " "
# Verification : Date de debut inscription n'est pas > date de fin de formation
if (datetime.strptime(str(diction['date_debut_inscription'])[0:10], '%d/%m/%Y') > datetime.strptime(
str(diction['date_fin'])[0:10], '%d/%m/%Y')):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - Session de Formation : La date de debut d'inscription " + str( diction['date_debut_inscription'])+ " est postérieure à la date de fin de formation " + str(diction['date_fin']))
return False, " Session de Formation : La date de debut d'inscription " + str( diction['date_debut_inscription'])[0:10] + " est postérieure à la date de fin de formation " + str(diction['date_fin'])[0:10]+" "
# Verification : Date de fin inscription n'est pas > date de fin de formation
if (datetime.strptime(str(diction['date_fin_inscription'])[0:10], '%d/%m/%Y') > datetime.strptime(
str(diction['date_fin'])[0:10], '%d/%m/%Y')):
mycommon.myprint(
str(inspect.stack()[0][3]) + " -Formation : "+str(code_session)+" : La date de fin d'inscription " + str(
diction['date_fin_inscription'])[0:10] + " est postérieure à la date de fin de la formation " + str(
diction['date_fin'])[0:10])
return False, " Formation : "+str(code_session)+" : La date de fin d'inscription " + str(
diction['date_fin_inscription'])[0:10] + " est postérieure à la date de fin de la formation " + str(
diction['date_fin'])[0:10] + " "
"""
mytoday = datetime.today().strftime("%d/%m/%Y")
if (datetime.strptime(str(diction['date_debut'])[0:10], '%d/%m/%Y') < datetime.strptime(str(mytoday).strip(), '%d/%m/%Y')) :
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation : La date de debut de sessions " + str(
diction['date_debut']) +" est antérieure à la date du jour ")
return False, " - Impossible de créer/mettre à jour la session de formation : La date de debut de sessions " + str(
diction['date_debut']) +" est antérieure à la date du jour "
"""
# Fin Controle de cohérence sur les dates
"""
Verification avant ajout ou mise à jour
1 - si le champ 'session_id' est renseingé alors c'est une mise à jour.
Dans le cas d'une mise à jour,
je verifie s'il y a des inscription avec les code session actuellement en base, si oui, alors on refuse la modication
/!\ : DU CODE SESSION, mais on accepte les autres champs car le session est deja utilisé.
2 - Si le champ 'session_id' N'EST PAS renseingé alors c'est une creation.
On verifie que ce code session n'est pas deja utilisé pour cette formation.
.
"""
Warning_Message = ""
if(len(str(session_id)) > 0 ):
# Il s'agit d'une mise à jour
# Etape 1 : recuperation du code session en base
local_retval1 = MYSY_GV.dbname['session_formation'].find_one({'_id':ObjectId(str(session_id))})
if( local_retval1 is None or 'code_session' not in local_retval1.keys() or 'class_internal_url' not in local_retval1.keys() ):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Cette session n'as pas de code session ")
return False, "Impossible de récupérer le code de la session (1) "
existing_session_code = local_retval1['code_session']
existing_class_internal_url = local_retval1['class_internal_url']
current_step = local_retval1['session_etape']
local_retval = MYSY_GV.dbname['inscription'].count_documents({'session_id':str(existing_session_code),
'class_internal_url':str(existing_class_internal_url)})
if( local_retval > 0):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Cette session a déjà des inscriptions. Le code de la session ne peut etre modifié. Les autres champs ont été correctement mis à jour")
mydata['code_session'] = existing_session_code # On remet le actuellement en base de données
Warning_Message = "Cette session a déjà des inscriptions. Le code de la session ne peut etre modifié. Les autres champs ont été correctement mis à jour"
#print(" ###laaa mydata = ", mydata)
coll_name = MYSY_GV.dbname['session_formation']
ret_val = coll_name.find_one_and_update(
{'_id':ObjectId(str(session_id)), 'valide':'1'},
{"$set": mydata},
upsert=False,
return_document=ReturnDocument.AFTER
)
if (ret_val is None or '_id' not in ret_val.keys()):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Impossible d'ajouter/mettre à jour la session '" + str(
diction['code_session']) + "' ")
return False, "Impossible d'ajouter/mettre à jour la session '" + str(diction['code_session']) + "' "
new_step = ret_val['session_etape']
"""
# Ajout de l'evenement dans l'historique
"""
# Cas particulier : Verifier s'il y a eu changement d'session_etape, pour préciser cela dans le log de l'historique
major_change_text = ""
if( str(new_step) != str(current_step)):
major_change_text = " Changement étape : "+str(current_step)+" ==> "+str(new_step)+" "
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = diction['token']
history_event_dict['related_collection'] = "session_formation"
history_event_dict['related_collection_recid'] = str(ret_val['_id'])
history_event_dict['action_date'] = str(now)
if( major_change_text == "" ):
history_event_dict['action_description'] = "Mise à jour "
else:
history_event_dict['action_description'] = str(major_change_text)
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
#print("len(str(Warning_Message)) = ", len(str(Warning_Message)), )
if(len(str(Warning_Message)) > 2 ):
return True, str(Warning_Message)
return True, " La session de formation à bien été mise à jour"
if (len(str(session_id)) <= 0):
# La session n'existe pas, on fait une simple creation
mydata['date_created'] = str(datetime.now())
"""
21/02/2025
Il faut aller chercher la configuration des envois automatic de document.
Il faut regarder dans la collection - base_document_automatic_setup -
"""
#print(" ## ICIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII ")
mydata['automatic_traitement'] = []
qry_automatic_setup = {'collection_target':'session_formation',
'valide':'1',
'locked':'0',
'partner_owner_recid':str(my_partner['recid'])}
for base_document_automatic_setup_for_partner in MYSY_GV.dbname['base_document_automatic_setup'].find(qry_automatic_setup):
new_local_data = base_document_automatic_setup_for_partner
new_local_data['statut'] = "0"
new_local_data['created_date'] = str(datetime.now())
new_local_data['created_by'] = str(my_partner['_id'])
mydata['automatic_traitement'].append(new_local_data)
#print(" ### mydata ICIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII = ", mydata)
coll_name = MYSY_GV.dbname['session_formation']
ret_val = coll_name.insert_one(mydata)
local_inserted_id = ret_val.inserted_id
if (ret_val is None or not hasattr(ret_val, 'inserted_id') ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Impossible d'ajouter la session '" + str(
diction['code_session']) + "' ")
return False, "Impossible d'ajouter la session '" + str(diction['code_session']) + "' "
"""
# Ajout de l'evenement dans l'historique
"""
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = diction['token']
history_event_dict['related_collection'] = "session_formation"
history_event_dict['related_collection_recid'] = str(local_inserted_id)
history_event_dict['action_date'] = str(now)
if( "session_id" in diction.keys() and diction['session_id']):
history_event_dict['action_description'] = "Mise à jour "
else:
history_event_dict['action_description'] = "Creation "
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
return True, " La session de formation à bien été créée"
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 créer / mettre à jour la session de formation"
"""
Gestion de mise à jour JUSTE de l'etape, notamment utilisé dans le mode kanban
/!\ : Une session est modifiable tanque la facturation n'a pas demarré. Apres tous est bloqué
"""
def Update_SessionFormation_Only_Step(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', '_id', 'session_etape', ]
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé.")
return False, " Toutes les informations fournies ne sont pas valables"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', '_id', 'session_etape', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, "Toutes les informations necessaires n'ont pas été fournies"
mydata = {}
query_key = {}
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_token = diction['token']
data_for_check_connexion = {'token': my_token}
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(data_for_check_connexion)
if (local_status is not True):
return local_status, my_partner
"""
Verifier la valididé de la session de formation
"""
is_valide_session = MYSY_GV.dbname['session_formation'].count_documents({'_id':ObjectId(str(diction['_id'])),
'valide':'1', 'partner_owner_recid':str(my_partner['recid'])})
if( is_valide_session != 1 ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - L'identifiant de la session de formation est invalide ")
return False, "L'identifiant de la session de formation est invalide"
is_valide_session_data = MYSY_GV.dbname['session_formation'].find_one({'_id': ObjectId(str(diction['_id'])),
'valide': '1',
'partner_owner_recid': str(
my_partner['recid'])})
if( "invoiced_statut" in is_valide_session_data.keys() and is_valide_session_data['invoiced_statut'] == '1'):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - Cette session est partiellement facturée. Impossible de modifier l'étape ")
return False, "Cette session est partiellement facturée. Impossible de modifier l'étape"
if ("invoiced_statut" in is_valide_session_data.keys() and is_valide_session_data['invoiced_statut'] == '2'):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Cette session est complètement facturée. Impossible de modifier l'étape ")
return False, "Cette session est complètement facturée. Impossible de modifier l'étape"
new_data = {}
new_data['date_update'] = str(datetime.now())
new_data['update_by'] = str(my_partner['_id'])
new_data['valide'] = "1"
new_data['session_etape'] = str(diction['session_etape'])
# print(" ###laaa mydata = ", mydata)
coll_name = MYSY_GV.dbname['session_formation']
ret_val = coll_name.find_one_and_update(
{'_id': ObjectId(str(diction['_id'])),
'valide': '1', 'partner_owner_recid': str(my_partner['recid'])},
{"$set": new_data},
upsert=False,
return_document=ReturnDocument.AFTER
)
if (ret_val is None or '_id' not in ret_val.keys()):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Impossible d'ajouter/mettre à jour la session '" + str(
diction['code_session']) + "' ")
return False, "Impossible d'ajouter/mettre à jour la session '" + str(diction['code_session']) + "' "
"""
# Ajout de l'evenement dans l'historique
"""
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = diction['token']
history_event_dict['related_collection'] = "session_formation"
history_event_dict['related_collection_recid'] = str(ret_val['_id'])
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Mise à jour : Session Etape passe à "+str(diction['session_etape'])
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
return True, " La session de formation à bien été mise à jour"
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible mettre à jour la session de formation"
"""
Fonction de recuperation d'une session de formation.
/!\ : il ne doit pas y avoir plus d'une session.
si le result > 1 une session, alors erreur d'inchorence d'info.
"""
def GetSessionFormation(diction):
try:
field_list = ['token', 'class_internal_url', 'session_id', ]
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée")
return False, "Toutes les informations fournies ne sont pas valables"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', 'class_internal_url', 'session_id', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, "Toutes les informations necessaires n'ont pas été fournies"
# Recuperation du recid du partner
mydata = {}
mytoken = ""
if ("token" in diction.keys()):
if diction['token']:
mytoken = diction['token']
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data({'token':str(diction['token'])})
if (local_status is not True):
return local_status, my_partner
partner_recid = my_partner['recid']
class_internal_url = ""
if ("class_internal_url" in diction.keys()):
if diction['class_internal_url']:
class_internal_url = diction['class_internal_url']
session_id = ""
if ("session_id" in diction.keys()):
if diction['session_id']:
session_id = diction['session_id']
if(str(session_id).strip() == ""):
return True, []
coll_session = MYSY_GV.dbname['session_formation']
myquery = [{'$match':{'_id':ObjectId(str(session_id)), 'class_internal_url':class_internal_url, 'partner_owner_recid':str(partner_recid)}},
{'$lookup':
{
'from': 'myclass',
'localField': 'class_internal_url',
'foreignField': 'internal_url',
'pipeline': [{'$project': {'title': 1, 'lms_class_code':1, 'external_code':1, 'published':1, 'recyclage_delai':1, 'recyclage_periodicite':1,
'lms_class_code':1}}],
'as': 'myclass'
}
}
]
#print(" ##### myquery GetSessionFormation = "+str(myquery))
RetObject = []
nb_val = 0
for retval in coll_session.aggregate(myquery):
#print(" ##### retval = " + str(retval))
user = {}
user = retval
user['id'] = str(nb_val)
nb_val = nb_val + 1
title = ""
lms_class_code = ""
class_external_code = ""
class_ispublished = "0"
class_lms_class_code = ""
if ("automatic_traitement" not in user.keys() ):
user['automatic_traitement'] = []
if ('myclass' in retval.keys() and len(retval['myclass']) > 0):
if( "title" in retval['myclass'][0].keys()):
title = retval['myclass'][0]['title']
if ("lms_class_code" in retval['myclass'][0].keys()):
lms_class_code = retval['myclass'][0]['lms_class_code']
if ("external_code" in retval['myclass'][0].keys()):
class_external_code = retval['myclass'][0]['external_code']
if ("published" in retval['myclass'][0].keys()):
class_ispublished = retval['myclass'][0]['published']
if ("lms_class_code" in retval['myclass'][0].keys()):
class_lms_class_code = retval['myclass'][0]['lms_class_code']
user['title'] = title
user['lms_class_code'] = lms_class_code
user['class_external_code'] = class_external_code
user['class_ispublished'] = class_ispublished
user['class_lms_class_code'] = class_lms_class_code
if ("invoiced_statut" in retval.keys()):
user['invoiced_statut'] = retval['invoiced_statut']
else:
user['invoiced_statut'] = "0"
formateur_nom_prenom = ""
# Si il y a un code formateur_id, alors on va recuperer les nom et prenom du formation
if( "formateur_id" in retval.keys() and retval['formateur_id']):
formateur_data = MYSY_GV.dbname['ressource_humaine'].find_one({'_id':ObjectId(str(retval['formateur_id'])),
'valide':'1',
'locked':'0',
'partner_recid':str(partner_recid)
})
if(formateur_data and "nom" in formateur_data.keys() and "prenom" in formateur_data.keys() ):
formateur_nom_prenom = str(formateur_data['nom'])+" "+str(formateur_data['prenom'])
user['formateur_nom_prenom'] = formateur_nom_prenom
site_formation_id = ""
site_formation_code = ""
if("site_formation_id" in retval.keys() and retval['site_formation_id']) :
site_formation_data = MYSY_GV.dbname['site_formation'].find_one({'_id':ObjectId(str(retval['site_formation_id'])),
'valide':'1',
'locked':'0',
'partner_owner_recid':str(my_partner['recid'])})
if( site_formation_data and "code_site" in site_formation_data.keys() ):
site_formation_code = site_formation_data['code_site']
site_formation_id = str(retval['site_formation_id'])
user['site_formation_id'] = site_formation_id
user['site_formation_code'] = site_formation_code
"""
Regarder si cette inscription a des inscriptions (validées) d'entreprise
"""
tmp_count = MYSY_GV.dbname['inscription'].count_documents({'partner_owner_recid': str(my_partner['recid']),
'valide': '1',
'status': '1',
'session_id': str(diction['session_id']),
'client_rattachement_id': {'$exists': True,
'$ne': ""}})
user['nb_valide_inscription_entreprise'] = str(tmp_count)
"""
Regarder si cette inscriptiona des inscriptions (validées) d'individuelle
"""
tmp_count = MYSY_GV.dbname['inscription'].count_documents({'$or': [
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1',
'status': '1',
'session_id': str(diction['session_id']),
'client_rattachement_id': {'$exists': False}}
,
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1',
'status': '1',
'session_id': str(diction['session_id']),
'client_rattachement_id': ""}
]}
)
user['nb_valide_inscription_individuelle'] = str(tmp_count)
#print(" ### user = ", user)
RetObject.append(mycommon.JSONEncoder().encode(user))
# Si le nombre de session trouvé est > 1 alors incohérence, retourner une message d'erreur
if( nb_val > 1 ):
mycommon.myprint(str(inspect.stack()[0][3]) + " - la query "+str(myquery)+" retourne "+str(nb_val)+" session. ceci n'est pas normal. il ne doit pas y avoir plus 1 session")
return False, " Les informations de la session "+str(session_id)+" sont incohérentes. Merci de contacter le support"
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de récupérer la session de formation"
"""
Recuperer les données d'un session de formation à partir du _Id seulement et token
"""
def Get_Given_SessionFormation_From_Id(diction):
try:
field_list = ['token', 'session_id', ]
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée")
return False, "de récupérer la liste des stagiaires . Toutes les informations fournies ne sont pas valables"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', 'session_id', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, "Impossible de récupérer la liste des stagiaires, Toutes les informations necessaires n'ont pas été fournies"
# Recuperation du recid du partner
mydata = {}
mytoken = ""
if ("token" in diction.keys()):
if diction['token']:
mytoken = diction['token']
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data({'token':str(diction['token'])})
if (local_status is not True):
return local_status, my_partner
partner_recid = my_partner['recid']
session_id = ""
if ("session_id" in diction.keys()):
if diction['session_id']:
session_id = diction['session_id']
if(str(session_id).strip() == ""):
return True, []
coll_session = MYSY_GV.dbname['session_formation']
myquery = [{'$match':{'_id':ObjectId(str(session_id)), 'partner_owner_recid':str(partner_recid)}},
{'$lookup':
{
'from': 'myclass',
'localField': 'class_internal_url',
'foreignField': 'internal_url',
'pipeline': [{'$project': {'title': 1, 'lms_class_code':1, 'external_code':1, 'published':1, 'recyclage_delai':1, 'recyclage_periodicite':1,
'lms_class_code':1}}],
'as': 'myclass'
}
}
]
print(" ##### myquery Get_Given_SessionFormation_From_Is = "+str(myquery))
RetObject = []
nb_val = 0
for retval in coll_session.aggregate(myquery):
#print(" ##### retval = " + str(retval))
user = {}
user = retval
user['id'] = str(nb_val)
nb_val = nb_val + 1
title = ""
lms_class_code = ""
class_external_code = ""
class_ispublished = "0"
class_lms_class_code = ""
if ('myclass' in retval.keys() and len(retval['myclass']) > 0):
if( "title" in retval['myclass'][0].keys()):
title = retval['myclass'][0]['title']
if ("lms_class_code" in retval['myclass'][0].keys()):
lms_class_code = retval['myclass'][0]['lms_class_code']
if ("external_code" in retval['myclass'][0].keys()):
class_external_code = retval['myclass'][0]['external_code']
if ("published" in retval['myclass'][0].keys()):
class_ispublished = retval['myclass'][0]['published']
if ("lms_class_code" in retval['myclass'][0].keys()):
class_lms_class_code = retval['myclass'][0]['lms_class_code']
user['title'] = title
user['lms_class_code'] = lms_class_code
user['class_external_code'] = class_external_code
user['class_ispublished'] = class_ispublished
user['class_lms_class_code'] = class_lms_class_code
if ("invoiced_statut" in retval.keys() ):
user['invoiced_statut'] = retval['invoiced_statut']
else:
user['invoiced_statut'] = "0"
formateur_nom_prenom = ""
# Si il y a un code formateur_id, alors on va recuperer les nom et prenom du formation
if( "formateur_id" in retval.keys() and retval['formateur_id']):
formateur_data = MYSY_GV.dbname['ressource_humaine'].find_one({'_id':ObjectId(str(retval['formateur_id'])),
'valide':'1',
'locked':'0',
'partner_recid':str(partner_recid)
})
if(formateur_data and "nom" in formateur_data.keys() and "prenom" in formateur_data.keys() ):
formateur_nom_prenom = str(formateur_data['nom'])+" "+str(formateur_data['prenom'])
user['formateur_nom_prenom'] = formateur_nom_prenom
"""
Regarder si cette inscription a des inscriptions (validées) d'entreprise
"""
tmp_count = MYSY_GV.dbname['inscription'].count_documents({'partner_owner_recid': str(my_partner['recid']),
'valide': '1',
'status': '1',
'session_id': str(diction['session_id']),
'client_rattachement_id': {'$exists': True,
'$ne': ""}})
user['nb_valide_inscription_entreprise'] = str(tmp_count)
"""
Regarder si cette inscriptiona des inscriptions (validées) d'individuelle
"""
tmp_count = MYSY_GV.dbname['inscription'].count_documents({'$or': [
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1',
'status': '1',
'session_id': str(diction['session_id']),
'client_rattachement_id': {'$exists': False}}
,
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1',
'status': '1',
'session_id': str(diction['session_id']),
'client_rattachement_id': ""}
]}
)
user['nb_valide_inscription_individuelle'] = str(tmp_count)
#print(" ### user = ", user)
RetObject.append(mycommon.JSONEncoder().encode(user))
# Si le nombre de session trouvé est > 1 alors incohérence, retourner une message d'erreur
if( nb_val > 1 ):
mycommon.myprint(str(inspect.stack()[0][3]) + " - la query "+str(myquery)+" retourne "+str(nb_val)+" session. ceci n'est pas normal. il ne doit pas y avoir plus 1 session")
return False, " Les informations de la session "+str(session_id)+" sont incohérentes. Merci de contacter le support"
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de récupérer la session de formation"
"""
Cette fonction recupere la liste de toutes les sessions de formation actives et valides
d'une formation données ET les sessions "on demande"
/!\ : Cette fonction est utilisée en mode non connecté et en mode connecté.
Donc faire attention au controle de la connexion
"""
def GetActiveSessionFormation_List(diction):
try:
field_list = ['token', 'class_internal_url']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée")
return False, " Impossible de récupérer la liste des session de formation"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = [ 'class_internal_url', ]
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 liste des session de formation"
# Le controle de token n'est effectué que une valeur est fournie dans le token
if( 'token' in diction.keys() and len(str(diction['token'])) > 0) :
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
if (local_status is not True):
return local_status, my_partner
# Recuperation du recid du partner
mydata = {}
class_internal_url = ""
if ("class_internal_url" in diction.keys()):
if diction['class_internal_url']:
class_internal_url = diction['class_internal_url']
coll_session = MYSY_GV.dbname['session_formation']
myquery = {}
myquery['class_internal_url'] = class_internal_url
myquery['valide'] = "1"
myquery['session_status'] = "1"
RetObject = []
print(" ### GetActiveSessionFormation_List myquery = ", myquery)
for retval in coll_session.find(myquery):
local_tmp = retval
## Verification des conditions supplementaires :
# en realité c'est parce que c'est chaud de le faire avec pymongo
tmp_debut_inscritp = str(local_tmp['date_debut_inscription']).strip().split(" ")
tmp_fin_inscritp = str(local_tmp['date_fin_inscription']).strip().split(" ")
debut_inscr = datetime.strptime(str(tmp_debut_inscritp[0]).strip(), '%d/%m/%Y')
fin_inscr = datetime.strptime(str(tmp_fin_inscritp[0]).strip(), '%d/%m/%Y')
#print(" #### date_debut_inscription = ", debut_inscr, " date_fin_inscription = ", fin_inscr, " NOW = ",datetime.now())
if(debut_inscr <= datetime.now() and fin_inscr >= datetime.now()):
RetObject.append(mycommon.JSONEncoder().encode(retval))
else:
if ("session_ondemande" in local_tmp.keys()):
if( str(local_tmp['session_ondemande']).strip() == "1"):
RetObject.append(mycommon.JSONEncoder().encode(retval))
#print("#### GetActiveSessionFormation_List RetObject = "+str(RetObject))
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de récupérer la liste des sessions de formation valides et actives."
"""
Cette fonction recuperer les liste de sessions de formations
d'un partenaire, mais avec une liste reduite de champs
- _id
- code_session
- titre
- class_internal_url
- date_debut
- date_fin
"""
def Get_Partner_Session_Ftion_Reduice_Fields(diction):
try:
field_list = ['token',]
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée")
return False, " Impossible de récupérer la liste des session de formation"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = [ 'token', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, "Impossible de récupérer la liste des session de formation"
# Le controle de token n'est effectué que une valeur est fournie dans le token
if( 'token' in diction.keys() and len(str(diction['token'])) > 0) :
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
if (local_status is not True):
return local_status, my_partner
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
if (local_status is not True):
return local_status, my_partner
RetObject = []
RetObject = []
val_tmp = 0
for retval in MYSY_GV.dbname['session_formation'].find({'partner_owner_recid':str(my_partner['recid']),
'valide':'1'},
{'_id':1, 'code_session':1, 'titre':1,
'class_internal_url':1, 'date_debut':1,
'date_fin':1}):
user = retval
user['id'] = str(val_tmp)
RetObject.append(mycommon.JSONEncoder().encode(user))
val_tmp = val_tmp + 1
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de récupérer la liste des sessions de formation valides et actives."
"""
Cette fonction recupere UNIQUEMENT LES VILLES ET SI A DISTANCEsessions de formation actives et valides
d'une formation données ET les sessions "on demande"
on doit renvoyer les villes de manière unique et eviter les doublon de villes
"""
def GetActiveSession_Cities_And_Distance_Formation_List(diction):
try:
field_list = ['token', 'class_internal_url']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée")
return False, " Impossible de récupérer la liste des session de formation"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = [ 'class_internal_url', ]
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 liste des session de formation"
# Le controle de token n'est effectué que une valeur est fournie dans le token
if( 'token' in diction.keys() and len(str(diction['token'])) > 0) :
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
if (local_status is not True):
return local_status, my_partner
# Recuperation du recid du partner
mydata = {}
liste_session_cities = []
class_internal_url = ""
if ("class_internal_url" in diction.keys()):
if diction['class_internal_url']:
class_internal_url = diction['class_internal_url']
coll_session = MYSY_GV.dbname['session_formation']
myquery = {}
myquery['class_internal_url'] = class_internal_url
myquery['valide'] = "1"
myquery['session_status'] = "1"
RetObject = []
print(" ### GetActiveSession_Cities_And_Distance_Formation_List myquery = ", myquery)
for retval in coll_session.find(myquery):
local_tmp = retval
## Verification des conditions supplementaires :
# en realité c'est parce que c'est chaud de le faire avec pymongo
tmp_debut_inscritp = str(local_tmp['date_debut_inscription']).strip().split(" ")
tmp_fin_inscritp = str(local_tmp['date_fin_inscription']).strip().split(" ")
local_status_tmp_debut_inscritp = mycommon.CheckisDate(str(tmp_debut_inscritp[0]))
local_status_tmp_fin_inscritp = mycommon.CheckisDate(str(tmp_fin_inscritp[0]))
if( local_status_tmp_debut_inscritp and local_status_tmp_fin_inscritp ):
debut_inscr = datetime.strptime(str(tmp_debut_inscritp[0]).strip(), '%d/%m/%Y')
fin_inscr = datetime.strptime(str(tmp_fin_inscritp[0]).strip(), '%d/%m/%Y')
#print(" #### date_debut_inscription = ", debut_inscr, " date_fin_inscription = ", fin_inscr, " NOW = ",datetime.now())
if(debut_inscr <= datetime.now() and fin_inscr >= datetime.now()):
if( "ville" in retval.keys() and retval['ville']):
if( str(retval['ville']) not in liste_session_cities):
liste_session_cities.append(str(retval['ville']))
RetObject.append(mycommon.JSONEncoder().encode(str(retval['ville'])))
elif( "mode_animation" in retval.keys() and str(retval['mode_animation']) == "1"):
if ( "A Distance" not in liste_session_cities):
liste_session_cities.append("A Distance")
RetObject.append(mycommon.JSONEncoder().encode("A Distance"))
else:
if ("session_ondemande" in local_tmp.keys()):
if( str(local_tmp['session_ondemande']).strip() == "1"):
if ("A la demande" not in liste_session_cities):
liste_session_cities.append("A la demande")
RetObject.append(mycommon.JSONEncoder().encode("A la demande"))
#print("#### GetActiveSessionFormation_List RetObject = "+str(RetObject))
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de récupérer la liste des villes des sessions de formation valides et actives."
"""
Cette fonction récupérer la liste des toutes les sessions
de formation valides pour une formation données.
Qu'elles soient cloturées ou pas."""
def GetAllValideSessionFormation_List(diction):
try:
field_list = ['token', 'class_internal_url']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée")
return False, " Impossible de récupérer la liste des session de formation"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', 'class_internal_url', ]
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 liste des session de formation"
# Recuperation du recid du partner
mydata = {}
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
if (local_status is not True):
return local_status, my_partner
class_internal_url = ""
if ("class_internal_url" in diction.keys()):
if diction['class_internal_url']:
class_internal_url = diction['class_internal_url']
coll_session = MYSY_GV.dbname['session_formation']
myquery = {}
myquery['class_internal_url'] = class_internal_url
myquery['partner_owner_recid'] = str(my_partner['recid'])
myquery['valide'] = "1"
print(" ##### myquery tt = "+str(myquery))
RetObject = []
for retval in coll_session.find(myquery):
#print(" ##### retval = " + str(retval))
RetObject.append(mycommon.JSONEncoder().encode(retval))
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de récupérer la liste des sessions de formation valides et actives."
"""
Cette fonction recupere toutes les sessions de formation d'un partenaire
"""
def GetAllValideSessionPartner_List(diction):
try:
field_list = ['token']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée")
return False, " Impossible de récupérer la liste des session de formation"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, "Impossible de récupérer la liste des session de formation"
# Recuperation du recid du partner
mydata = {}
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
coll_session = MYSY_GV.dbname['session_formation']
filt_class_partner_recid = {'partner_owner_recid': str(my_partner['recid'])}
query = [{'$match': {'partner_owner_recid':str(my_partner['recid'])}},
{ '$sort': {'_id': -1}},
{'$lookup':
{
'from': 'myclass',
'localField': 'class_internal_url',
'foreignField':'internal_url',
'pipeline': [{'$match': filt_class_partner_recid}, {'$project': {'title': 1, 'domaine': 1,
'duration': 1, 'duration_unit': 1, 'external_code':1,
'published':1, 'recyclage_delai':1, 'recyclage_periodicite':1,
'lms_class_code':1}}],
'as': 'myclass_collection'
}
}
]
#print("#### query = ", query)
RetObject = []
cpt = 0
for retVal in MYSY_GV.dbname['session_formation'].aggregate(query):
if ('myclass_collection' in retVal.keys() and len(retVal['myclass_collection']) > 0):
val = {}
val['id'] = str(cpt)
cpt = cpt + 1
val['class_internal_url'] = retVal['class_internal_url']
val['_id'] = retVal['_id']
val['code_session'] = retVal['code_session']
if( "session_etape" in retVal.keys()):
val['session_etape'] = retVal['session_etape']
else:
val['session_etape'] = ""
if ("invoiced_statut" in retVal.keys()):
val['invoiced_statut'] = retVal['invoiced_statut']
else:
val['invoiced_statut'] = "0"
if( "titre" in retVal.keys()):
val['titre'] = retVal['titre']
else:
val['titre'] = ""
if ("location_type" in retVal.keys()):
val['location_type'] = retVal['location_type']
else:
val['location_type'] = ""
if ("is_bpf" in retVal.keys()):
val['is_bpf'] = retVal['is_bpf']
else:
val['is_bpf'] = ""
if ("session_status" in retVal.keys()):
val['session_status'] = retVal['session_status']
else:
val['session_status'] = "0"
val['date_debut'] = retVal['date_debut'][0:10]
val['date_fin'] = retVal['date_fin'][0:10]
val['date_debut_inscription'] = retVal['date_debut_inscription'][0:10]
val['date_fin_inscription'] = retVal['date_fin_inscription'][0:10]
val['distantiel'] = retVal['distantiel']
if( "mode_animation" in retVal.keys() ):
val['mode_animation'] = retVal['mode_animation']
else:
val['mode_animation'] = "0"
site_formation_id = ""
site_formation_code = ""
if ("site_formation_id" in retVal.keys() and retVal['site_formation_id']):
site_formation_data = MYSY_GV.dbname['site_formation'].find_one(
{'_id': ObjectId(str(retVal['site_formation_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (site_formation_data and "code_site" in site_formation_data.keys()):
site_formation_code = site_formation_data['code_site']
site_formation_id = str(retVal['site_formation_id'])
val['site_formation_id'] = site_formation_id
val['site_formation_code'] = site_formation_code
if ("formateur_id" in retVal.keys() and retVal['formateur_id']):
val['formateur_id'] = retVal['formateur_id']
# On va aller chercher le nom et prenom du formateur
fomateur_data = MYSY_GV.dbname['ressource_humaine'].find_one(
{'_id': ObjectId(str(retVal['formateur_id'])),
'valide': '1',
'locked': '0',
'partner_recid': str(my_partner['recid'])})
if (fomateur_data is None):
val['formateur'] = " Invalide"
else:
nom = ""
prenom = ""
if ("nom" in fomateur_data.keys()):
nom = fomateur_data['nom']
if ("prenom" in fomateur_data.keys()):
prenom = fomateur_data['prenom']
val['formateur'] = str(nom) + " " + str(prenom)
else:
val['formateur_id'] = ""
nb_participant = "1"
if( "nb_participant" in retVal.keys()):
nb_participant = retVal['nb_participant']
val['nb_participant'] = nb_participant
val['presentiel'] = retVal['presentiel']
val['prix_session'] = retVal['prix_session']
val['title'] = retVal['myclass_collection'][0]['title']
val['class_published'] = retVal['myclass_collection'][0]['published']
if ("domaine" in retVal['myclass_collection'][0].keys()):
val['domaine'] = retVal['myclass_collection'][0]['domaine']
else:
val['domaine'] = ""
if ("lms_class_code" in retVal['myclass_collection'][0].keys()):
val['class_lms_class_code'] = retVal['myclass_collection'][0]['lms_class_code']
else:
val['class_lms_class_code'] = ""
val['class_id'] = retVal['myclass_collection'][0]['_id']
val['class_external_code'] = retVal['myclass_collection'][0]['external_code']
if( str(retVal['myclass_collection'][0]['duration_unit']) == "heure"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration'])+" h"
elif (str(retVal['myclass_collection'][0]['duration_unit']) == "jour"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " j"
elif (str(retVal['myclass_collection'][0]['duration_unit']) == "semaine"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " s"
elif (str(retVal['myclass_collection'][0]['duration_unit']) == "mois"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " m"
elif (str(retVal['myclass_collection'][0]['duration_unit']) == "annee"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " a"
elif (str(retVal['myclass_collection'][0]['duration_unit']) == "user_rythme"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " u"
else :
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " ?"
if( "duration" in retVal['myclass_collection'][0].keys()):
val['duration'] = str(retVal['myclass_collection'][0]['duration'])
else:
val['duration'] = "1"
if ("duration_unit" in retVal['myclass_collection'][0].keys()):
val['duration_unit'] = retVal['myclass_collection'][0]['duration_unit']
else:
val['duration_unit'] = "jour"
## Recuperation du nombre d'inscrits
Count_Inscrit = MYSY_GV.dbname['inscription'].count_documents({'session_id':str(retVal['_id']), 'class_internal_url':str(retVal['class_internal_url']),
'status':"1", 'partner_owner_recid':str(my_partner['recid'])})
qry_nb_inscrit = {'session_id':str(retVal['_id']), 'class_internal_url':str(retVal['class_internal_url']),
'status':"1", 'partner_owner_recid':str(my_partner['recid'])}
val['nb_inscrit'] = str(Count_Inscrit)
## Recuperation du nombre de preinscrits
Count_Preinscrit = MYSY_GV.dbname['inscription'].count_documents(
{'session_id': str(retVal['_id']), 'class_internal_url': str(retVal['class_internal_url']),
'status': "0",
'partner_owner_recid':str(my_partner['recid'])})
val['nb_preinscrit'] = str(Count_Preinscrit)
taux_remplissage = "0"
if( str(nb_participant) != "0" and str(nb_participant).strip() != ""):
taux_remplissage = round(int(mycommon.tryInt(Count_Inscrit)) / int(mycommon.tryInt(nb_participant)), 2)
val['taux_remplissage'] = str(taux_remplissage)
"""
29/05/2024 : On va aller recuperer le nombre de personnes inscrites sur des devis non envoyés et non validés.
Ceci permet de connaitre le nombre potentiel d'inscription en attentes.
Regles : Cela concerne uniquement les devis envoyés aux clients et prospects mais non validé
"""
locl_find_qry = {
'$and': [{'partner_owner_recid': str(my_partner['recid']), 'valide': '1', 'locked': '0',
'order_header_type':'devis', 'is_validated':'0', 'date_envoi_quotation': { "$exists": True } }, {}, ]}
local_new_myquery_find_order = [{'$match': locl_find_qry},
{'$sort': {'_id': -1}},
{"$addFields": {"partner_order_header_Id": {"$toString": "$_id"}}},
{'$lookup':
{
'from': 'partner_order_line',
'localField': "partner_order_header_Id",
'foreignField': 'order_header_id',
'pipeline': [
{'$match':
{'$and':
[
{'order_line_formation':str(retVal['class_internal_url'])},
{'partner_owner_recid': str(my_partner['recid']),
'order_line_session_id':str(retVal['_id'])},
{'valide': '1'}]}}, ],
'as': 'partner_order_line_collection'
}
},
{
'$unwind': '$partner_order_line_collection'
}
]
total_qty = 0
tab_quotation_ref = []
for local_New_retVal in MYSY_GV.dbname['partner_order_header'].aggregate(local_new_myquery_find_order):
#print(" ### local_New_retVal = ", local_New_retVal)
if( "partner_order_line_collection" in local_New_retVal.keys() ):
if( "order_line_qty" in local_New_retVal['partner_order_line_collection'].keys() and
len(str(local_New_retVal['date_envoi_quotation'])) > 5 ):
total_qty = total_qty + mycommon.tryFloat(local_New_retVal['partner_order_line_collection']['order_line_qty'])
tab_quotation_ref.append(str(local_New_retVal['order_header_ref_interne']))
#print(" ### total_qty = ", total_qty)
#print(" ### tab_quotation_ref = ", tab_quotation_ref)
val['qty_in_quotation'] = str(total_qty)
val['qty_in_quotation_list_quotation'] = ', '.join(tab_quotation_ref)
"""
Pour chaque session recuperer le statut de controle d'alert
"""
is_session_alert = ""
session_alert_message = ""
local_diction = {}
local_diction['token'] = str(diction['token'])
local_diction['session_id'] = str(retVal['_id'])
local_check_session_alert_status, local_check_session_alert_retval, local_check_session_alert_is_warning = mycommon.Check_Partner_Session_Alert(local_diction)
if( local_check_session_alert_status ):
is_session_alert = local_check_session_alert_is_warning
session_alert_message = local_check_session_alert_retval
val['is_session_alert'] = is_session_alert
val['session_alert_message'] = session_alert_message
RetObject.append(mycommon.JSONEncoder().encode(val))
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de récupérer la liste des sessions de formation valides et actives."
"""
Recuperation de la liste avec des filter du type like
"""
def GetAllValideSessionPartner_List_filter_like(diction):
try:
field_list = ['token','class_title', 'code_session', 'class_external_code',
'session_start_date', 'session_end_date',
'class_internal_url']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée")
return False, " Impossible de récupérer la liste des session de formation"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, "Impossible de récupérer la liste des session de formation"
# Recuperation du recid du partner
mydata = {}
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
nb_hour_per_day = mycommon.Get_Partner_Hour_Per_Day(str(my_partner['recid']))
if (nb_hour_per_day is False):
nb_hour_per_day = "7"
filt_class_title = {}
if ("class_title" in diction.keys()):
filt_class_title = {'title': {'$regex': str(diction['class_title']),"$options": "i"}}
filt_class_internal_url = {}
if ("class_internal_url" in diction.keys()):
filt_class_internal_url = {'internal_url': {'$regex': str(diction['class_internal_url']),"$options": "i"}}
filt_class_external_code = {}
if ("class_external_code" in diction.keys()):
filt_class_external_code = {'external_code': {'$regex': str(diction['class_external_code']), "$options": "i"}}
filt_code_session = {}
if ("code_session" in diction.keys()):
filt_code_session = {'code_session': {'$regex': str(diction['code_session']), "$options": "i"}}
filt_session_start_date = ""
if ("session_start_date" in diction.keys()):
filt_session_start_date = str(diction['session_start_date'])[0:10]
local_status = mycommon.CheckisDate(filt_session_start_date)
if (local_status is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " Le filtre : 'date de debut de session' n'est pas au format jj/mm/aaaa.")
return False, " Le filtre : 'date de debut de session' n'est pas au format jj/mm/aaaa."
filt_session_end_date = ""
if ("session_end_date" in diction.keys()):
filt_session_end_date = str(diction['session_end_date'])[0:10]
local_status = mycommon.CheckisDate(filt_session_end_date)
if (local_status is False):
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le filtre : 'date de fin de session' n'est pas au format jj/mm/aaaa.")
return False, " Le filtre : 'date de fin de session' n'est pas au format jj/mm/aaaa."
coll_session = MYSY_GV.dbname['session_formation']
query = [ {'$match':{ '$and' : [ filt_code_session,{'partner_owner_recid':str(my_partner['recid'])}] }} ,
{'$sort': {'_id': -1}},
{'$lookup':
{
'from': 'myclass',
'localField': 'class_internal_url',
'foreignField': 'internal_url',
'pipeline': [{'$match': { '$and' : [ filt_class_title, filt_class_internal_url, filt_class_external_code, {'partner_owner_recid':str(my_partner['recid'])} ]} }, {'$project': {'title': 1, 'domaine':1,
'duration':1, 'duration_unit':1, 'external_code':1, 'recyclage_delai':1, 'recyclage_periodicite':1,
'lms_class_code':1}}],
'as': 'myclass_collection'
}
}
]
#print("#### GetAllValideSessionPartner_List_filter_likequery = ", query)
RetObject = []
cpt = 0
for retVal in MYSY_GV.dbname['session_formation'].aggregate(query):
if( 'myclass_collection' in retVal.keys() and len(retVal['myclass_collection']) > 0 ):
val = {}
val['id'] = str(cpt)
cpt = cpt + 1
val['_id'] = retVal['_id']
val['class_internal_url'] = retVal['class_internal_url']
val['code_session'] = retVal['code_session']
if ("titre" in retVal.keys()):
val['titre'] = retVal['titre']
else:
val['titre'] = ""
if ("location_type" in retVal.keys()):
val['location_type'] = retVal['location_type']
else:
val['location_type'] = ""
if ("is_bpf" in retVal.keys()):
val['is_bpf'] = retVal['is_bpf']
else:
val['is_bpf'] = ""
if( "session_etape" in retVal.keys()):
val['session_etape'] = retVal['session_etape']
else:
val['session_etape'] = ""
if ("invoiced_statut" in retVal.keys()):
val['invoiced_statut'] = retVal['invoiced_statut']
else:
val['invoiced_statut'] = "0"
if( "session_status" in retVal.keys()):
val['session_status'] = retVal['session_status']
else:
val['session_status'] = "0"
val['date_debut'] = retVal['date_debut'][0:10]
val['date_fin'] = retVal['date_fin'][0:10]
val['date_debut_inscription'] = retVal['date_debut_inscription'][0:10]
val['date_fin_inscription'] = retVal['date_fin_inscription'][0:10]
if ("distantiel" in retVal.keys()):
val['distantiel'] = retVal['distantiel']
else:
val['distantiel'] = "0"
if ("mode_animation" in retVal.keys()):
val['mode_animation'] = retVal['mode_animation']
else:
val['mode_animation'] = "0"
site_formation_id = ""
site_formation_code = ""
if ("site_formation_id" in retVal.keys() and retVal['site_formation_id']):
site_formation_data = MYSY_GV.dbname['site_formation'].find_one(
{'_id': ObjectId(str(retVal['site_formation_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (site_formation_data and "code_site" in site_formation_data.keys()):
site_formation_code = site_formation_data['code_site']
site_formation_id = str(retVal['site_formation_id'])
val['site_formation_id'] = site_formation_id
val['site_formation_code'] = site_formation_code
if ("formateur_id" in retVal.keys() and retVal['formateur_id']):
val['formateur_id'] = retVal['formateur_id']
# On va aller chercher le nom et prenom du formateur
fomateur_data = MYSY_GV.dbname['ressource_humaine'].find_one({'_id':ObjectId(str(retVal['formateur_id'])),
'valide':'1',
'locked':'0',
'partner_recid':str(my_partner['recid'])})
if( fomateur_data is None):
val['formateur'] = " Invalide"
else:
nom = ""
prenom = ""
if( "nom" in fomateur_data.keys()):
nom = fomateur_data['nom']
if ("prenom" in fomateur_data.keys()):
prenom = fomateur_data['prenom']
val['formateur'] = str(nom)+" "+str(prenom)
else:
val['formateur_id'] = ""
nb_participant = "1"
if ("nb_participant" in retVal.keys()):
nb_participant = retVal['nb_participant']
val['nb_participant'] = nb_participant
if ("presentiel" in retVal.keys()):
val['presentiel'] = retVal['presentiel']
else:
val['presentiel'] = "0"
if ("prix_session" in retVal.keys()):
val['prix_session'] = retVal['prix_session']
else:
val['prix_session'] = "0"
val['title'] = retVal['myclass_collection'][0]['title']
if( "domaine" in retVal['myclass_collection'][0].keys() ):
val['domaine'] = retVal['myclass_collection'][0]['domaine']
else:
val['domaine'] = ""
if ("lms_class_code" in retVal['myclass_collection'][0].keys()):
val['class_lms_class_code'] = retVal['myclass_collection'][0]['lms_class_code']
else:
val['class_lms_class_code'] = ""
val['class_external_code'] = retVal['myclass_collection'][0]['external_code']
if (str(retVal['myclass_collection'][0]['duration_unit']) == "heure"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " h"
elif (str(retVal['myclass_collection'][0]['duration_unit']) == "jour"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " j"
elif (str(retVal['myclass_collection'][0]['duration_unit']) == "semaine"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " s"
elif (str(retVal['myclass_collection'][0]['duration_unit']) == "mois"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " m"
elif (str(retVal['myclass_collection'][0]['duration_unit']) == "annee"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " a"
elif (str(retVal['myclass_collection'][0]['duration_unit']) == "user_rythme"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " u"
else:
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " ?"
if ("duration" in retVal['myclass_collection'][0].keys()):
val['duration'] = str(retVal['myclass_collection'][0]['duration'])
else:
val['duration'] = "1"
if ("duration_unit" in retVal['myclass_collection'][0].keys()):
val['duration_unit'] = retVal['myclass_collection'][0]['duration_unit']
else:
val['duration_unit'] = "jour"
## Recuperation du nombre d'inscrits
Count_Inscrit = MYSY_GV.dbname['inscription'].count_documents(
{'session_id': str(retVal['_id']), 'class_internal_url': str(retVal['class_internal_url']),
'status': "1"})
val['nb_inscrit'] = str(Count_Inscrit)
## Recuperation du nombre de preinscrits
Count_Preinscrit = MYSY_GV.dbname['inscription'].count_documents(
{'session_id': str(retVal['_id']), 'class_internal_url': str(retVal['class_internal_url']),
'status': "0"})
val['nb_preinscrit'] = str(Count_Preinscrit)
taux_remplissage = "0"
if (str(nb_participant) != "0"):
taux_remplissage = round(int(mycommon.tryInt(Count_Inscrit)) / int(mycommon.tryInt(nb_participant)),
2)
val['taux_remplissage'] = str(taux_remplissage)
"""
29/05/2024 : On va aller recuperer le nombre de personnes inscrites sur des devis non envoyés et non validés.
Ceci permet de connaitre le nombre potentiel d'inscription en attentes.
Regles : Cela concerne uniquement les devis envoyés aux clients et prospects mais non validé
"""
locl_find_qry = {
'$and': [{'partner_owner_recid': str(my_partner['recid']), 'valide': '1', 'locked': '0',
'order_header_type': 'devis', 'is_validated': '0',
'date_envoi_quotation': {"$exists": True}}, {}, ]}
local_new_myquery_find_order = [{'$match': locl_find_qry},
{'$sort': {'_id': -1}},
{"$addFields": {"partner_order_header_Id": {"$toString": "$_id"}}},
{'$lookup':
{
'from': 'partner_order_line',
'localField': "partner_order_header_Id",
'foreignField': 'order_header_id',
'pipeline': [
{'$match':
{'$and':
[
{'order_line_formation': str(
retVal['class_internal_url'])},
{'partner_owner_recid': str(
my_partner['recid']),
'order_line_session_id': str(retVal['_id'])},
{'valide': '1'}]}}, ],
'as': 'partner_order_line_collection'
}
},
{
'$unwind': '$partner_order_line_collection'
}
]
total_qty = 0
tab_quotation_ref = []
for local_New_retVal in MYSY_GV.dbname['partner_order_header'].aggregate(local_new_myquery_find_order):
# print(" ### local_New_retVal = ", local_New_retVal)
if ("partner_order_line_collection" in local_New_retVal.keys()):
if ("order_line_qty" in local_New_retVal['partner_order_line_collection'].keys() and
len(str(local_New_retVal['date_envoi_quotation'])) > 5):
total_qty = total_qty + mycommon.tryFloat(
local_New_retVal['partner_order_line_collection']['order_line_qty'])
tab_quotation_ref.append(str(local_New_retVal['order_header_ref_interne']))
# print(" ### total_qty = ", total_qty)
# print(" ### tab_quotation_ref = ", tab_quotation_ref)
val['qty_in_quotation'] = str(total_qty)
val['qty_in_quotation_list_quotation'] = ', '.join(tab_quotation_ref)
"""
Pour chaque session recuperer le statut de controle d'alert
"""
is_session_alert = ""
session_alert_message = ""
local_diction = {}
local_diction['token'] = str(diction['token'])
local_diction['session_id'] = str(retVal['_id'])
local_check_session_alert_status, local_check_session_alert_retval, local_check_session_alert_is_warning = mycommon.Check_Partner_Session_Alert(
local_diction)
if (local_check_session_alert_status):
is_session_alert = local_check_session_alert_is_warning
session_alert_message = local_check_session_alert_retval
val['is_session_alert'] = is_session_alert
val['session_alert_message'] = session_alert_message
if (filt_session_start_date and filt_session_end_date):
# Si on a un filtre sur la date debut et de fin de session
if ((datetime.strptime(str(retVal['date_debut'][0:10]).strip(), '%d/%m/%Y') >= datetime.strptime(
str(filt_session_start_date).strip(), '%d/%m/%Y'))
and
(datetime.strptime(str(retVal['date_fin'][0:10]).strip(),
'%d/%m/%Y') <= datetime.strptime(str(filt_session_end_date).strip(),
'%d/%m/%Y'))
):
RetObject.append(mycommon.JSONEncoder().encode(val))
elif (filt_session_start_date):
# Si on a un filtre uniquement sur la date de debut de session
if ((datetime.strptime(str(retVal['date_debut'][0:10]).strip(), '%d/%m/%Y') >= datetime.strptime(
str(filt_session_start_date).strip(), '%d/%m/%Y'))):
RetObject.append(mycommon.JSONEncoder().encode(val))
elif (filt_session_end_date):
# Si on a un filtre uniquement sur la date de fin session
if ((datetime.strptime(str(retVal['date_fin'][0:10]).strip(), '%d/%m/%Y') <= datetime.strptime(
str(filt_session_end_date).strip(), '%d/%m/%Y'))):
RetObject.append(mycommon.JSONEncoder().encode(val))
else:
RetObject.append(mycommon.JSONEncoder().encode(val))
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de récupérer la liste des sessions de formation valides et actives."
"""
Recuperation de la liste sans filtre
"""
def GetAllValideSessionPartner_List_no_filter(diction):
try:
field_list = ['token','class_title', 'code_session']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée")
return False, " Impossible de récupérer la liste des session de formation"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, "Impossible de récupérer la liste des session de formation"
# Recuperation du recid du partner
mydata = {}
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
coll_session = MYSY_GV.dbname['session_formation']
query = [{'$match':{'partner_owner_recid': str(my_partner['recid'])} },
{'$lookup':
{
'from': 'myclass',
'localField': 'class_internal_url',
'foreignField': 'internal_url',
'pipeline': [{'$match': {'partner_owner_recid': str(my_partner['recid'])} },
{'$project': {'title': 1, 'domaine': 1,
'duration': 1, 'duration_unit': 1, 'external_code':1, 'recyclage_delai':1, 'recyclage_periodicite':1,
'lms_class_code':1}}],
'as': 'myclass_collection'
}
}
]
print("#### GetAllValideSessionPartner_List_filter_likequery = ", query)
RetObject = []
cpt = 0
for retVal in MYSY_GV.dbname['session_formation'].aggregate(query):
if( 'myclass_collection' in retVal.keys() and len(retVal['myclass_collection']) > 0 ):
val = {}
val['id'] = str(cpt)
cpt = cpt + 1
val['_id'] = retVal['_id']
val['class_internal_url'] = retVal['class_internal_url']
val['code_session'] = retVal['code_session']
if ("titre" in retVal.keys()):
val['titre'] = retVal['titre']
else:
val['titre'] = ""
if ("location_type" in retVal.keys()):
val['location_type'] = retVal['location_type']
else:
val['location_type'] = ""
if ("is_bpf" in retVal.keys()):
val['is_bpf'] = retVal['is_bpf']
else:
val['is_bpf'] = ""
if( "session_etape" in retVal.keys()):
val['session_etape'] = retVal['session_etape']
else:
val['session_etape'] = ""
if ("invoiced_statut" in retVal.keys()):
val['invoiced_statut'] = retVal['invoiced_statut']
else:
val['invoiced_statut'] = "0"
if( "session_status" in retVal.keys()):
val['session_status'] = retVal['session_status']
else:
val['session_status'] = "0"
val['date_debut'] = retVal['date_debut'][0:10]
val['date_fin'] = retVal['date_fin'][0:10]
val['date_debut_inscription'] = retVal['date_debut_inscription'][0:10]
val['date_fin_inscription'] = retVal['date_fin_inscription'][0:10]
if ("distantiel" in retVal.keys()):
val['distantiel'] = retVal['distantiel']
else:
val['distantiel'] = "0"
if ("mode_animation" in retVal.keys()):
val['mode_animation'] = retVal['mode_animation']
else:
val['mode_animation'] = "0"
if ("formateur_id" in retVal.keys() and retVal['formateur_id']):
val['formateur_id'] = retVal['formateur_id']
# On va aller chercher le nom et prenom du formateur
fomateur_data = MYSY_GV.dbname['ressource_humaine'].find_one(
{'_id': ObjectId(str(retVal['formateur_id'])),
'valide': '1',
'locked': '0',
'partner_recid': str(my_partner['recid'])})
if (fomateur_data is None):
val['formateur'] = " Invalide"
else:
nom = ""
prenom = ""
if ("nom" in fomateur_data.keys()):
nom = fomateur_data['nom']
if ("prenom" in fomateur_data.keys()):
prenom = fomateur_data['prenom']
val['formateur'] = str(nom) + " " + str(prenom)
else:
val['formateur_id'] = ""
nb_participant = "1"
if ("nb_participant" in retVal.keys()):
nb_participant = retVal['nb_participant']
val['nb_participant'] = nb_participant
if ("presentiel" in retVal.keys()):
val['presentiel'] = retVal['presentiel']
else:
val['presentiel'] = "0"
if ("prix_session" in retVal.keys()):
val['prix_session'] = retVal['prix_session']
else:
val['prix_session'] = "0"
val['title'] = retVal['myclass_collection'][0]['title']
if( "domaine" in retVal['myclass_collection'][0].keys() ):
val['domaine'] = retVal['myclass_collection'][0]['domaine']
else:
val['domaine'] = ""
if ("lms_class_code" in retVal['myclass_collection'][0].keys()):
val['class_lms_class_code'] = retVal['myclass_collection'][0]['lms_class_code']
else:
val['class_lms_class_code'] = ""
val['class_external_code'] = retVal['myclass_collection'][0]['external_code']
if (str(retVal['myclass_collection'][0]['duration_unit']) == "heure"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " h"
elif (str(retVal['myclass_collection'][0]['duration_unit']) == "jour"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " j"
elif (str(retVal['myclass_collection'][0]['duration_unit']) == "semaine"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " s"
elif (str(retVal['myclass_collection'][0]['duration_unit']) == "mois"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " m"
elif (str(retVal['myclass_collection'][0]['duration_unit']) == "annee"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " a"
elif (str(retVal['myclass_collection'][0]['duration_unit']) == "user_rythme"):
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " u"
else:
val['duration_concat'] = str(retVal['myclass_collection'][0]['duration']) + " ?"
if ("duration" in retVal['myclass_collection'][0].keys()):
val['duration'] = str(retVal['myclass_collection'][0]['duration'])
else:
val['duration'] = "1"
if ("duration_unit" in retVal['myclass_collection'][0].keys()):
val['duration_unit'] = retVal['myclass_collection'][0]['duration_unit']
else:
val['duration_unit'] = "jour"
## Recuperation du nombre d'inscrits
Count_Inscrit = MYSY_GV.dbname['inscription'].count_documents(
{'session_id': str(retVal['_id']), 'class_internal_url': str(retVal['class_internal_url']),
'status': "1"})
val['nb_inscrit'] = str(Count_Inscrit)
## Recuperation du nombre de preinscrits
Count_Preinscrit = MYSY_GV.dbname['inscription'].count_documents(
{'session_id': str(retVal['_id']), 'class_internal_url': str(retVal['class_internal_url']),
'status': "0"})
val['nb_preinscrit'] = str(Count_Preinscrit)
taux_remplissage = "0"
if (str(nb_participant) != "0"):
taux_remplissage = round(int(mycommon.tryInt(Count_Inscrit)) / int(mycommon.tryInt(nb_participant)),
2)
val['taux_remplissage'] = str(taux_remplissage)
"""
29/05/2024 : On va aller recuperer le nombre de personnes inscrites sur des devis non envoyés et non validés.
Ceci permet de connaitre le nombre potentiel d'inscription en attentes.
Regles : Cela concerne uniquement les devis envoyés aux clients et prospects mais non validé
"""
locl_find_qry = {
'$and': [{'partner_owner_recid': str(my_partner['recid']), 'valide': '1', 'locked': '0',
'order_header_type': 'devis', 'is_validated': '0',
'date_envoi_quotation': {"$exists": True}}, {}, ]}
local_new_myquery_find_order = [{'$match': locl_find_qry},
{'$sort': {'_id': -1}},
{"$addFields": {"partner_order_header_Id": {"$toString": "$_id"}}},
{'$lookup':
{
'from': 'partner_order_line',
'localField': "partner_order_header_Id",
'foreignField': 'order_header_id',
'pipeline': [
{'$match':
{'$and':
[
{'order_line_formation': str(
retVal['class_internal_url'])},
{'partner_owner_recid': str(
my_partner['recid']),
'order_line_session_id': str(retVal['_id'])},
{'valide': '1'}]}}, ],
'as': 'partner_order_line_collection'
}
},
{
'$unwind': '$partner_order_line_collection'
}
]
total_qty = 0
tab_quotation_ref = []
for local_New_retVal in MYSY_GV.dbname['partner_order_header'].aggregate(local_new_myquery_find_order):
# print(" ### local_New_retVal = ", local_New_retVal)
if ("partner_order_line_collection" in local_New_retVal.keys()):
if ("order_line_qty" in local_New_retVal['partner_order_line_collection'].keys() and
len(str(local_New_retVal['date_envoi_quotation'])) > 5):
total_qty = total_qty + mycommon.tryFloat(
local_New_retVal['partner_order_line_collection']['order_line_qty'])
tab_quotation_ref.append(str(local_New_retVal['order_header_ref_interne']))
# print(" ### total_qty = ", total_qty)
# print(" ### tab_quotation_ref = ", tab_quotation_ref)
val['qty_in_quotation'] = str(total_qty)
val['qty_in_quotation_list_quotation'] = ', '.join(tab_quotation_ref)
RetObject.append(mycommon.JSONEncoder().encode(val))
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de récupérer la liste des sessions de formation valides et actives."
"""
Cette fonction crée les sessions de formation en mass
par exemple avec l'import d'un fichier csv
"""
def Add_Update_SessionFormation_mass(file=None, Folder=None, diction=None):
try:
diction = mycommon.strip_dictionary(diction)
'''
# 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', 'class_internal_url']
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 session annulée")
return False, " Le champ '" + val + "' n'existe pas, Creation session 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 = ['token', 'class_internal_url']
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"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_token = diction['token']
# Verifier la validité du token
retval = mycommon.check_partner_token_validity("", my_token)
if retval is False:
return "Err_Connexion", " La session de connexion n'est pas valide"
class_internal_url = ""
if ("class_internal_url" in diction.keys()):
if diction['class_internal_url']:
class_internal_url = diction['class_internal_url']
if (len(str(class_internal_url).strip()) <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Le code de la formation est vide : Impossible d'importer la liste des sessions ")
return False, "Le code de la formation est vide. Impossible d'importer la liste des sessions"
partner_recid = mycommon.get_parnter_recid_from_token(my_token)
if (partner_recid is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - partner_recid KO : Impossible d'importer la liste des sessions ")
return False, "les information de connexion sont incorrectes. Impossible d'importer la liste des sessions"
status, saved_file = mycommon.Upload_Save_CSV_File(file, Folder)
if (status == False):
return False, "Impossible d'importer la liste des sessions, le nom du fichier est incorrect "
# " Lecture du fichier "
# print(" Lecture du fichier : "+saved_file)
nb_line = 0
""""
update du 31/08/23 : Controle de l'integrité du fichier avant import
"""
local_controle_status, local_controle_message = Controle_Add_Update_SessionFormation_mass(saved_file,
Folder,
diction)
if (local_controle_status is False):
return local_controle_status, local_controle_message
print(" #### local_controle_message = ", local_controle_message)
df = pd.read_csv(saved_file, encoding='utf8', on_bad_lines='skip', sep=';', encoding_errors='ignore')
df = df.fillna('')
df = df.applymap(lambda x: x.strip() if isinstance(x, str) else x)
# Dictionnaire des champs utilisables
'''
# Verification que les noms des colonne sont bien corrects"
'''
field_list = ['date_debut', 'date_fin', 'nb_participant', 'adresse', 'code_postal', 'ville', 'pays',
'session_status', 'date_debut_inscription', 'date_fin_inscription', 'attestation', 'formateur',
'code_session', "distanciel", "presentiel", "mode_animation", "prix_session", 'contenu_ftion', 'lms_class_code',
'session_ondemande', 'session_etape', 'formation_code_externe', 'formateur_email', 'titre', 'location_type', 'is_bpf']
# Controle du nombre de lignes dans le fichier.
total_rows = len(df)
if (total_rows > MYSY_GV.MAX_PARTICIPANT_BY_CSV):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le fichier comporte plus de " + str(
MYSY_GV.MAX_PARTICIPANT_BY_CSV) + " lignes.")
return False, " Le fichier comporte plus de " + str(MYSY_GV.MAX_PARTICIPANT_BY_CSV) + " lignes."
# print(df.columns)
for val in df.columns:
if str(val).lower() not in field_list:
mycommon.myprint(
str(inspect.stack()[0][3]) + " : entete du fichier csv. '" + val + "' n'est pas acceptée")
return False, " Entete du fichier csv. La Colonne '" + val + "' n'est pas acceptée"
# Verification des champs obligatoires dans le fichier
field_list_obligatoire_file = ['date_debut', 'date_fin', 'session_status', 'code_session', 'formation_code_externe']
for val in field_list_obligatoire_file:
if val not in df.columns:
mycommon.myprint(
str(inspect.stack()[0][3]) + " : Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire")
return False, " Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire "
# Recuperation des info de la formation.
formation_data = MYSY_GV.dbname['myclass'].find_one({'internal_url': str(class_internal_url), 'valide':'1', 'locked':'0'})
if (formation_data is None):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La session de formation n'existe pas : Impossible d'importer la liste des participants ")
return False, "la session de formation n'existe pas. Impossible d'importer la liste des participants"
x = range(0, total_rows)
ignored_line = ""
nb_inserted_line = 0
for n in x:
mydata = {}
nb_inserted_line = nb_inserted_line + 1
# Si une ligne n'a aucune information obligatoire, alors on ignore la ligne
if (str(df['code_session'].values[n]) == "nan" or str(df['session_status'].values[n]) == "nan" or
str(df['date_debut'].values[n]) == "nan" or str(df['date_fin'].values[n]) == "nan" ):
mycommon.myprint(str(
inspect.stack()[0][
3]) + " - La ligne " + str(n + 2) + " a été ignorée")
ignored_line = str(n + 2) + " , " + str(ignored_line)
nb_inserted_line = nb_inserted_line - 1
continue
external_code = ""
if ("formation_code_externe" in df.keys()):
if (str(df['formation_code_externe'].values[n])):
external_code = str(df['formation_code_externe'].values[n]).strip()
# On verifie l'existance de l'external code pour ce une des formations de ce partner
count_class = MYSY_GV.dbname['myclass'].count_documents(
{'external_code': str(external_code), 'valide': '1',
'locked': '0', 'partner_owner_recid': str(partner_recid)})
if (count_class < 0):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Ligne " + str( n + 2) + " : Le code_externe n'est pas valide.")
return False, " Ligne " + str( n + 2) + " : Le code_externe n'est pas valide."
if (count_class > 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Erreur : Ligne " + str(n + 2) + " : Le code_externe corresponds à plus d'une formation.")
return False, " Erreur : Ligne " + str(n + 2) + " : Le code_externe corresponds à plus d'une formation."
class_date = MYSY_GV.dbname['myclass'].find_one(
{'external_code': str(external_code), 'valide': '1',
'locked': '0', 'partner_owner_recid': str(partner_recid)})
if( class_date['external_code'] != formation_data['external_code']):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Erreur : Ligne " + str( n + 2) + " : Le code externe dans le fichier excel ne correpond pas au code externe de la formation sur la quelle vous etes")
return False, " Erreur : Ligne " + str( n + 2) + " : Le code externe dans le fichier excel ne correpond pas au code externe de la formation sur la quelle vous etes"
mydata['date_debut'] = str(df['date_debut'].values[n]).strip().split(" ")[0]
local_status = mycommon.CheckisDate(mydata['date_debut'])
if(local_status is False ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne "+str(n+2)+"."
"La date debut n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne "+str(n+2)+". La date debut n'est pas au format jj/mm/aaaa "
mydata['date_fin'] = str(df['date_fin'].values[n]).strip().split(" ")[0]
local_status = mycommon.CheckisDate(mydata['date_fin'])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne " + str(n+2) + "."
"La date date_fin n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n+1) + ". La date fin n'est pas au format jj/mm/aaaa "
## Verification de la cohérence des dates. Date_du doit <= Date_au
if (datetime.strptime(str(mydata['date_debut']).strip(), '%d/%m/%Y') > datetime.strptime(
str(mydata['date_fin']).strip(), '%d/%m/%Y')):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer la session de formation : La date debut " + str(mydata['date_debut']) +
" est postérieure à la date de fin " + str(mydata['date_fin']) + " pour la ligne "+str(n+2)+" ")
return False, " Impossible de créer la session de formation : La date debut " + str(mydata['date_debut'])[0:10] +\
" est postérieure à la date de fin " + str(mydata['date_fin'])[0:10] + " pour la ligne "+str(n+2)+" "
local_nb_participants = "1"
if ("nb_participant" in df.keys()):
if (str(df['nb_participant'].values[n])):
local_nb_participants = str(df['nb_participant'].values[n]).strip()
local_status, new_participants = mycommon.IsInt(local_nb_participants)
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'nb_participant' de la ligne " + str(n+2) + " est incorrecte.")
return False, " Le champ nb_participant de la ligne " + str(n+2) + " est incorrecte. "
mydata['nb_participant'] = str(new_participants)
prix_session = "0"
if ("prix_session" in df.keys()):
if (str(df['prix_session'].values[n])):
prix_session = str(df['prix_session'].values[n]).strip()
local_status, new_prix_session = mycommon.IsFloat(prix_session)
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'prix_session' de la ligne " + str(n+2) + " est incorrecte.")
return False, " Le champ prix_session de la ligne " + str(n+2) + " est incorrecte. "
mydata['prix_session'] = str(new_prix_session)
local_code_session = ""
if ("code_session" in df.keys()):
if (str(df['code_session'].values[n])):
local_code_session = str(df['code_session'].values[n]).strip()
if (len(str(local_code_session).strip()) < 2):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'code_session' de la ligne " + str(
n + 2) + " doit faire plus de deux caractères.")
return False, " Le champ code_session de la ligne " + str(
n + 2) + " doit faire plus de deux caractères. "
mydata['code_session'] = local_code_session
local_adresse = ""
if ("adresse" in df.keys()):
if (str(df['adresse'].values[n])):
local_adresse = str(df['adresse'].values[n]).strip()
mydata['adresse'] = local_adresse
""" lms_class_code = ""
if ("lms_class_code" in df.keys()):
if (str(df['lms_class_code'].values[n])):
lms_class_code = str(df['lms_class_code'].values[n]).strip()
mydata['lms_class_code'] = lms_class_code """
session_ondemande = "0"
if ("session_ondemande" in df.keys()):
if (str(df['session_ondemande'].values[n])):
session_ondemande = str(mycommon.tryInt(str(df['session_ondemande'].values[n]).strip()))
if( session_ondemande != "1" and session_ondemande != "0"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'session_ondemande' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ 'session_ondemande' de la ligne " + str(n + 2) + " est incorrecte. Les valeurs acceptées sont '1' ou '0' ou vide"
mydata['session_ondemande'] = session_ondemande
local_code_postal = ""
if ("code_postal" in df.keys()):
if (str(df['code_postal'].values[n])):
local_code_postal = str(df['code_postal'].values[n]).strip()
if ("." in str(local_code_postal)):
# /!\ : l'utilisateur envoie un code poster au format entier, plutot que string.
local_code_postal = str(local_code_postal).split(".")[0]
elif ("." in str(local_code_postal)):
# /!\ : l'utilisateur envoie un code poster au format entier, plutot que string.
local_code_postal = str(local_code_postal).split(",")[0]
else:
local_code_postal = str(local_code_postal)
mydata['code_postal'] = local_code_postal
distanciel = ""
if ("distanciel" in df.keys()):
if (str(df['distanciel'].values[n])):
distanciel = str(df['distanciel'].values[n]).strip()
distanciel = str(mycommon.tryInt(distanciel))
if (distanciel != "1" and distanciel != "0"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'distanciel' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ 'distanciel' de la ligne " + str(
n + 2) + " est incorrecte. Les valeurs acceptées sont '1' ou '0' ou vide"
mydata['distantiel'] = distanciel
presentiel = ""
if ("presentiel" in df.keys()):
if (str(df['presentiel'].values[n])):
presentiel = str(df['presentiel'].values[n]).strip()
presentiel = str(mycommon.tryInt(presentiel))
if (presentiel != "1" and presentiel != "0"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'presentiel' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ 'presentiel' de la ligne " + str(
n + 2) + " est incorrecte. Les valeurs acceptées sont '1' ou '0' ou vide"
mydata['presentiel'] = presentiel
mode_animation = ""
if ("mode_animation" in df.keys()):
if (str(df['mode_animation'].values[n])):
mode_animation = str(df['mode_animation'].values[n]).strip()
mode_animation = str(mycommon.tryInt(mode_animation))
if (mode_animation != "1" and mode_animation != "0" and mode_animation != "2"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'mode_animation' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ 'mode_animation' de la ligne " + str(
n + 2) + " est incorrecte. Les valeurs acceptées sont '0', '1', ou '2' ou vide"
mydata['mode_animation'] = mode_animation
#mydata['code_postal'] = str(df['code_postal'].values[n]).strip()
local_ville = ""
if ("ville" in df.keys()):
if (str(df['ville'].values[n])):
local_ville = str(df['ville'].values[n]).strip()
mydata['ville'] = local_ville
local_pays = ""
if ("pays" in df.keys()):
if (str(df['pays'].values[n])):
local_pays = str(df['pays'].values[n]).strip()
mydata['pays'] = local_pays
contenu_ftion = ""
if ("contenu_ftion" in df.keys()):
if (str(df['contenu_ftion'].values[n])):
contenu_ftion = str(df['contenu_ftion'].values[n]).strip()
mydata['contenu_ftion'] = contenu_ftion
#mydata['ville'] = str(df['ville'].values[n]).strip()
local_attestation_certif = ""
if ("attestation" in df.keys()):
if (str(df['attestation'].values[n])):
local_attestation_certif = str(df['attestation'].values[n]).strip()
mydata['attestation_certif'] = local_attestation_certif
#mydata['attestation_certif'] = str(df['attestation'].values[n]).strip()
session_status = ""
if ("session_status" in df.keys()):
if (str(df['session_status'].values[n])):
session_status = str(df['session_status'].values[n]).strip()
session_status = str(mycommon.tryInt(session_status))
mydata['session_status'] = session_status
session_etape = ""
if ("session_etape" in df.keys()):
if (str(df['session_etape'].values[n])):
session_etape = str(df['session_etape'].values[n]).strip()
mydata['session_etape'] = session_etape
"""
Update du 11/08/23 :
- le status va etre geré en 0 (desactivé) et 1 (activé)
- mise en commentaire du code ci-dessous
local_session = str(df['session_status'].values[n]).strip()
if( str(local_session) != "0" and str(local_session) != "1" and str(local_session) != "2"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'session_status' de la ligne " + str(n+2) + " est incorrecte. Les valeurs acceptées sont 0,1,2")
return False, " Le champ 'session_status' de la ligne " + str(n+2) + " est incorrecte. Les valeurs acceptées sont 0,1,2"
if( str(local_session) == "1"):
mydata['session_status'] = str("true")
"""
mydata['date_debut_inscription'] = str(df['date_debut_inscription'].values[n]).strip().split(" ")[0]
if( str(mydata['date_debut_inscription']).strip() != ""):
local_status = mycommon.CheckisDate(mydata['date_debut_inscription'])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne " + str(n+2) + "."
"La date_debut_inscription n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n+2) + ". La date_debut_inscription n'est pas au format jj/mm/aaaa "
mydata['date_fin_inscription'] = str(df['date_fin_inscription'].values[n]).strip().split(" ")[0]
if (str(mydata['date_fin_inscription']).strip() != ""):
local_status = mycommon.CheckisDate(mydata['date_fin_inscription'])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne " + str(n+2) + "."
"La date_fin_inscription n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n+1) + ". La date_fin_inscription n'est pas au format jj/mm/aaaa "
## Verification de la cohérence des dates. date_debut_inscription doit <= date_fin_inscription
if( str(mydata['date_debut_inscription']).strip() != "" and str(mydata['date_fin_inscription']).strip() != "" ):
if (datetime.strptime(str(mydata['date_debut_inscription']).strip(), '%d/%m/%Y') > datetime.strptime(
str(mydata['date_fin_inscription']).strip(), '%d/%m/%Y')):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer la session de formation : La date debut des inscriptions " + str(
mydata['date_debut_inscription']) +
" est postérieure à la date de fin des inscriptions " + str(mydata['date_fin_inscription']) + " pour la ligne "+str(n+2)+" ")
return False, " Impossible de créer la session de formation : La date de fin des inscriptions est antérieure à la date de début des inscriptions : Ligne "+str(n+2)+" "
mydata['token'] = str(my_token)
mydata['class_internal_url'] = str(class_internal_url)
#print(" ### mydata ", mydata)
diction_for_session_id = {}
diction_for_session_id['date_du'] = str(mydata['date_debut']).split(" ")[0]
diction_for_session_id['date_au'] = str(mydata['date_fin']).split(" ")[0]
diction_for_session_id['code_postal'] = str(mydata['code_postal'] )
diction_for_session_id['adresse'] = str(mydata['adresse'])
"""
Verifier si la session existe deja en base, si c'est le cas récupérer le '_id'
la clé pour verifier l'existance d'une session est :
- code_session
- class_internal_url
- partner_owner_recid
"""
existing_session = MYSY_GV.dbname['session_formation'].find_one(
{'code_session': str(local_code_session), 'class_internal_url': str(class_internal_url),
'partner_owner_recid': str(partner_recid), 'valide': '1'})
if (existing_session is not None):
if ('_id' in existing_session.keys()):
mydata['session_id'] = existing_session['_id']
clean_dict = {k: mydata[k] for k in mydata if (str(mydata[k]) != "nan")}
#print("#### Add_Update_SessionFormation_mass : clean_dict ", clean_dict)
status, retval = Add_Update_SessionFormation(clean_dict)
if (status is False):
return status, retval
print(str(total_rows) + " sessions ont été inserées")
message_ignored_line = ""
if (ignored_line):
message_ignored_line = " ATTENTION - Les lignes [" + str(
ignored_line) + "] ont été ignorées. car les toutes informations obligatoires ne sont pas fournies"
return True, str(nb_inserted_line) + " sessions ont été inserées / Mises à jour. " + str(message_ignored_line)
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible d'importer les sessions de formation en masse "
"""
Cette fonction permet de faire des controles du fichier excel avant l'import.
cela permet d'eviter des imports partiels.
c'est soit le fichier est TOUT bon ou pas.
"""
def Controle_Add_Update_SessionFormation_mass(saved_file=None, Folder=None, diction=None):
try:
diction = mycommon.strip_dictionary(diction)
'''
# 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', 'class_internal_url']
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 session annulée")
return False, " Le champ '" + val + "' n'existe pas, Creation session 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 = ['token', 'class_internal_url']
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"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_token = diction['token']
# Verifier la validité du token
retval = mycommon.check_partner_token_validity("", my_token)
if retval is False:
return "Err_Connexion", " La session de connexion n'est pas valide"
class_internal_url = ""
if ("class_internal_url" in diction.keys()):
if diction['class_internal_url']:
class_internal_url = diction['class_internal_url']
if (len(str(class_internal_url).strip()) <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Le code de la formation est vide : Impossible d'importer la liste des sessions ")
return False, "Le code de la formation est vide. Impossible d'importer la liste des sessions"
partner_recid = mycommon.get_parnter_recid_from_token(my_token)
if (partner_recid is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - partner_recid KO : Impossible d'importer la liste des sessions ")
return False, "les information de connexion sont incorrectes. Impossible d'importer la liste des sessions"
nb_line = 0
df = pd.read_csv(saved_file, encoding='utf8', on_bad_lines='skip', sep=';', encoding_errors='ignore')
df = df.fillna('')
df = df.applymap(lambda x: x.strip() if isinstance(x, str) else x)
# Dictionnaire des champs utilisables
'''
# Verification que les noms des colonne sont bien corrects"
'''
field_list = ['date_debut', 'date_fin', 'nb_participant', 'adresse', 'code_postal', 'ville', 'pays',
'session_status', 'date_debut_inscription', 'date_fin_inscription', 'attestation',
'code_session', "distanciel", "presentiel", "mode_animation", "prix_session", 'contenu_ftion', 'lms_class_code',
'session_ondemande', 'session_etape', 'formation_code_externe','formateur_email', 'titre', 'location_type', 'is_bpf']
# Controle du nombre de lignes dans le fichier.
total_rows = len(df)
if (total_rows > MYSY_GV.MAX_PARTICIPANT_BY_CSV):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le fichier comporte plus de " + str(
MYSY_GV.MAX_PARTICIPANT_BY_CSV) + " lignes.")
return False, " Le fichier comporte plus de " + str(MYSY_GV.MAX_PARTICIPANT_BY_CSV) + " lignes."
# print(df.columns)
for val in df.columns:
if str(val).lower() not in field_list:
mycommon.myprint(
str(inspect.stack()[0][3]) + " : entete du fichier csv. '" + val + "' n'est pas acceptée")
return False, " Entete du fichier csv. La Colonne '" + val + "' n'est pas acceptée"
# Verification des champs obligatoires dans le fichier
field_list_obligatoire_file = ['date_debut', 'date_fin', 'session_status', 'code_session',
'formation_code_externe']
for val in field_list_obligatoire_file:
if val not in df.columns:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " : Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire")
return False, " Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire "
# Recuperation des info de la formation.
formation_data = MYSY_GV.dbname['myclass'].find_one(
{'internal_url': str(class_internal_url), 'valide': '1', 'locked': '0'})
if (formation_data is None):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La session de formation n'existe pas : Impossible d'importer la liste des participants ")
return False, "la session de formation n'existe pas. Impossible d'importer la liste des participants"
x = range(0, total_rows)
ignored_line = ""
nb_inserted_line = 0
for n in x:
mydata = {}
nb_inserted_line = nb_inserted_line + 1
# Si une ligne n'a aucune information obligatoire, alors on ignore la ligne
if (str(df['code_session'].values[n]) == "nan" or str(df['session_status'].values[n]) == "nan" or
str(df['date_debut'].values[n]) == "nan" or str(df['date_fin'].values[n]) == "nan"):
mycommon.myprint(str(
inspect.stack()[0][
3]) + " - La ligne " + str(n + 2) + " a été ignorée")
ignored_line = str(n + 2) + " , " + str(ignored_line)
nb_inserted_line = nb_inserted_line - 1
continue
external_code = ""
if ("formation_code_externe" in df.keys()):
if (str(df['formation_code_externe'].values[n])):
external_code = str(df['formation_code_externe'].values[n]).strip()
# On verifie l'existance de l'external code pour ce une des formations de ce partner
count_class = MYSY_GV.dbname['myclass'].count_documents(
{'external_code': str(external_code), 'valide': '1',
'locked': '0', 'partner_owner_recid': str(partner_recid)})
if (count_class < 0):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Ligne " + str(
n + 2) + " : Le code_externe n'est pas valide.")
return False, " Ligne " + str(n + 2) + " : Le code_externe n'est pas valide."
if (count_class > 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Erreur : Ligne " + str(
n + 2) + " : Le code_externe corresponds à plus d'une formation.")
return False, " Erreur : Ligne " + str(
n + 2) + " : Le code_externe corresponds à plus d'une formation."
class_date = MYSY_GV.dbname['myclass'].find_one(
{'external_code': str(external_code), 'valide': '1',
'locked': '0', 'partner_owner_recid': str(partner_recid)})
if (class_date['external_code'] != formation_data['external_code']):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Erreur : Ligne " + str(
n + 2) + " : Le code externe dans le fichier excel ne correpond pas au code externe de la formation sur la quelle vous etes")
return False, " Erreur : Ligne " + str(
n + 2) + " : Le code externe dans le fichier excel ne correpond pas au code externe de la formation sur la quelle vous etes"
mydata['date_debut'] = str(df['date_debut'].values[n]).strip().split(" ")[0]
local_status = mycommon.CheckisDate(mydata['date_debut'])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + "."
"La date debut n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + ". La date debut n'est pas au format jj/mm/aaaa "
mydata['date_fin'] = str(df['date_fin'].values[n]).strip().split(" ")[0]
local_status = mycommon.CheckisDate(mydata['date_fin'])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + "."
"La date date_fin n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 1) + ". La date fin n'est pas au format jj/mm/aaaa "
# Verifier que l'adresse email du formateur est valide
formateur_email = ""
formateur_id = ""
if ("formateur_email" in df.keys()):
if (str(df['formateur_email'].values[n]) and str(df['formateur_email'].values[n]) != ""):
formateur_email = str(df['formateur_email'].values[n]).strip()
if (mycommon.isEmailValide(formateur_email) is False):
mycommon.myprint(str(
inspect.stack()[0][3]) + " - L'email du formateur '" + str(
formateur_email) + "' pour la formation à la ligne " + str(
n + 2) + " n'est pas valide.")
return False, " L'email du formateur '" + str(
formateur_email) + "' pour la formation à la ligne " + str(
n + 2) + " n'est pas valide."
is_formateur_email_ok = MYSY_GV.dbname['ressource_humaine'].count_documents(
{'email': formateur_email,
'valide': '1',
'locked': '0',
'partner_recid': str(
partner_recid)})
if (is_formateur_email_ok <= 0):
mycommon.myprint(str(
inspect.stack()[0][3]) + " - L'email du formateur '" + str(
formateur_email) + "' pour la formation à la ligne " + str(
n + 2) + " n'est pas valide (2).")
return False, " L'email du formateur '" + str(
formateur_email) + "' pour la formation à la ligne " + str(
n + 2) + " n'est pas valide (2)."
formateur_data = MYSY_GV.dbname['ressource_humaine'].find_one({'email': formateur_email,
'valide': '1',
'locked': '0',
'partner_recid': str(
partner_recid)})
formateur_id = str(formateur_data['_id'])
mydata['formateur_id'] = formateur_id
if ("titre" in df.keys()):
mydata['titre'] = str(df['titre'].values[n]).strip()
if ("location_type" in df.keys()):
mydata['location_type'] = str(df['location_type'].values[n]).strip().lower()
if (str(df['location_type'].values[n]).strip().lower() not in MYSY_GV.TRAINING_LOCATION_TYPE):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Le champ 'location_type' est incorrecte.")
return False, "Le champ 'location_type' est incorrect."
if ("is_bpf" in df.keys()):
if (str(df['is_bpf'].values[n]).strip() not in ['0', '1']):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Le champ 'bpf' est incorrect. Les valeurs acceptées sont : '1' ou '0' ")
return False, "Le champ 'bpf' est incorrect. Les valeurs acceptées sont : '1' ou '0' "
mydata['is_bpf'] = str(df['is_bpf'].values[n]).strip()
## Verification de la cohérence des dates. Date_du doit <= Date_au
if (datetime.strptime(str(mydata['date_debut']).strip(), '%d/%m/%Y') > datetime.strptime(
str(mydata['date_fin']).strip(), '%d/%m/%Y')):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer la session de formation : La date debut " + str(
mydata['date_debut']) +
" est postérieure à la date de fin " + str(mydata['date_fin']) + " pour la ligne " + str(
n + 2) + " ")
return False, " Impossible de créer la session de formation : La date debut " + str(
mydata['date_debut'])[0:10] + \
" est postérieure à la date de fin " + str(mydata['date_fin'])[0:10] + " pour la ligne " + str(
n + 2) + " "
local_nb_participants = "1"
if ("nb_participant" in df.keys()):
if (str(df['nb_participant'].values[n])):
local_nb_participants = str(df['nb_participant'].values[n]).strip()
local_status, new_participants = mycommon.IsInt(local_nb_participants)
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'nb_participant' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ nb_participant de la ligne " + str(n + 2) + " est incorrecte. Un nombre Entier Positif doit être fourni "
mydata['nb_participant'] = str(new_participants)
prix_session = "0"
if ("prix_session" in df.keys()):
if (str(df['prix_session'].values[n])):
prix_session = str(df['prix_session'].values[n]).strip()
local_status, new_prix_session = mycommon.IsFloat(prix_session)
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'prix_session' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ prix_session de la ligne " + str(n + 2) + " est incorrecte. "
mydata['prix_session'] = str(new_prix_session)
local_code_session = ""
if ("code_session" in df.keys()):
if (str(df['code_session'].values[n])):
local_code_session = str(df['code_session'].values[n]).strip()
if(len(str(local_code_session).strip()) < 2 ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'code_session' de la ligne " + str(
n + 2) + " doit faire plus de deux caractères.")
return False, " Le champ code_session de la ligne " + str(n + 2) + " doit faire plus de deux caractères. "
mydata['code_session'] = local_code_session
local_adresse = ""
if ("adresse" in df.keys()):
if (str(df['adresse'].values[n])):
local_adresse = str(df['adresse'].values[n]).strip()
mydata['adresse'] = local_adresse
session_ondemande = "0"
if ("session_ondemande" in df.keys()):
if (str(df['session_ondemande'].values[n])):
session_ondemande = str(df['session_ondemande'].values[n]).strip()
session_ondemande = str(mycommon.tryInt(str(session_ondemande)))
if (session_ondemande != "1" and session_ondemande != "0"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'session_ondemande' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ 'session_ondemande' de la ligne " + str(
n + 2) + " est incorrecte. Les valeurs acceptées sont '1' ou '0' ou vide"
mydata['session_ondemande'] = session_ondemande
local_code_postal = ""
if ("code_postal" in df.keys()):
if (str(df['code_postal'].values[n])):
local_code_postal = str(df['code_postal'].values[n]).strip()
if ("." in str(local_code_postal)):
# /!\ : l'utilisateur envoie un code poster au format entier, plutot que string.
local_code_postal = str(local_code_postal).split(".")[0]
elif ("." in str(local_code_postal)):
# /!\ : l'utilisateur envoie un code poster au format entier, plutot que string.
local_code_postal = str(local_code_postal).split(",")[0]
else:
local_code_postal = str(local_code_postal)
mydata['code_postal'] = local_code_postal
distanciel = ""
if ("distanciel" in df.keys()):
if (str(df['distanciel'].values[n])):
distanciel = str(df['distanciel'].values[n]).strip()
distanciel = str(mycommon.tryInt(distanciel))
if (distanciel != "1" and distanciel != "0"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'distanciel' de la ligne " + str(
n + 2) + " est incorrecte. La valeur fournie est "+str(distanciel) )
return False, " Le champ 'distanciel' de la ligne " + str(
n + 2) + " est incorrecte. Les valeurs acceptées sont '1' ou '0'. La valeur fournie est "+str(distanciel)
mydata['distantiel'] = distanciel
presentiel = ""
if ("presentiel" in df.keys()):
if (str(df['presentiel'].values[n])):
presentiel = str(df['presentiel'].values[n]).strip()
presentiel = str(mycommon.tryInt(presentiel))
if (presentiel != "1" and presentiel != "0"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'presentiel' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ 'presentiel' de la ligne " + str(
n + 2) + " est incorrecte. Les valeurs acceptées sont '1' ou '0' ou vide"
mydata['presentiel'] = presentiel
mydata['presentiel'] = presentiel
mode_animation = ""
if ("mode_animation" in df.keys()):
if (str(df['mode_animation'].values[n])):
mode_animation = str(df['mode_animation'].values[n]).strip()
mode_animation = str(mycommon.tryInt(mode_animation))
if (mode_animation != "1" and mode_animation != "0" and mode_animation != "2"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'mode_animation' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ 'mode_animation' de la ligne " + str(
n + 2) + " est incorrecte. Les valeurs acceptées sont '0', '1', ou '2' ou vide"
mydata['mode_animation'] = mode_animation
# mydata['code_postal'] = str(df['code_postal'].values[n]).strip()
local_ville = ""
if ("ville" in df.keys()):
if (str(df['ville'].values[n])):
local_ville = str(df['ville'].values[n]).strip()
mydata['ville'] = local_ville
local_pays = ""
if ("pays" in df.keys()):
if (str(df['pays'].values[n])):
local_pays = str(df['pays'].values[n]).strip()
mydata['pays'] = local_pays
contenu_ftion = ""
if ("contenu_ftion" in df.keys()):
if (str(df['contenu_ftion'].values[n])):
contenu_ftion = str(df['contenu_ftion'].values[n]).strip()
mydata['contenu_ftion'] = contenu_ftion
# mydata['ville'] = str(df['ville'].values[n]).strip()
local_attestation_certif = ""
if ("attestation" in df.keys()):
if (str(df['attestation'].values[n])):
local_attestation_certif = str(df['attestation'].values[n]).strip()
mydata['attestation_certif'] = local_attestation_certif
# mydata['attestation_certif'] = str(df['attestation'].values[n]).strip()
session_status = ""
if ("session_status" in df.keys()):
if (str(df['session_status'].values[n])):
session_status = str(df['session_status'].values[n]).strip()
mydata['session_status'] = session_status
session_etape = ""
if ("session_etape" in df.keys()):
if (str(df['session_etape'].values[n])):
session_etape = str(df['session_etape'].values[n]).strip()
mydata['session_etape'] = session_etape
"""
Update du 11/08/23 :
- le status va etre geré en 0 (desactivé) et 1 (activé)
- mise en commentaire du code ci-dessous
local_session = str(df['session_status'].values[n]).strip()
if( str(local_session) != "0" and str(local_session) != "1" and str(local_session) != "2"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'session_status' de la ligne " + str(n+2) + " est incorrecte. Les valeurs acceptées sont 0,1,2")
return False, " Le champ 'session_status' de la ligne " + str(n+2) + " est incorrecte. Les valeurs acceptées sont 0,1,2"
if( str(local_session) == "1"):
mydata['session_status'] = str("true")
"""
mydata['date_debut_inscription'] = str(df['date_debut_inscription'].values[n]).strip().split(" ")[0]
local_status = mycommon.CheckisDate(mydata['date_debut_inscription'])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + "."
"La date_debut_inscription n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + ". La date_debut_inscription n'est pas au format jj/mm/aaaa "
mydata['date_fin_inscription'] = str(df['date_fin_inscription'].values[n]).strip().split(" ")[0]
local_status = mycommon.CheckisDate(mydata['date_fin_inscription'])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + "."
"La date_fin_inscription n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 1) + ". La date_fin_inscription n'est pas au format jj/mm/aaaa "
## Verification de la cohérence des dates. Date_du doit <= Date_au
if (datetime.strptime(str(mydata['date_debut_inscription']).strip(), '%d/%m/%Y') > datetime.strptime(
str(mydata['date_fin_inscription']).strip(), '%d/%m/%Y')):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer la session de formation : La date debut des inscriptions " + str(
mydata['date_debut_inscription'])[0:10] +
" est postérieure à la date de fin des inscriptions " + str(
mydata['date_fin_inscription'])[0:10] + " pour la ligne " + str(n + 2) + " ")
return False, " Impossible de créer la session de formation : La date de fin des inscriptions est antérieure à la date de début des inscriptions : Ligne " + str(
n + 2) + " "
mydata['token'] = str(my_token)
mydata['class_internal_url'] = str(class_internal_url)
# print(" ### mydata ", mydata)
diction_for_session_id = {}
diction_for_session_id['date_du'] = str(mydata['date_debut']).split(" ")[0]
diction_for_session_id['date_au'] = str(mydata['date_fin']).split(" ")[0]
diction_for_session_id['code_postal'] = str(mydata['code_postal'])
diction_for_session_id['adresse'] = str(mydata['adresse'])
return True, str(total_rows)+" sessions dans le fichier"
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 controler le fichier des sessions de formation en masse "
"""
import des sessions de formation en masse
pour plusieurs formation.
Cela veut dire qu'on fourni 'external_code' pour chaque ligne du fichier excel, mais on ne fourni pas de 'internal_url'
"""
def Add_Update_SessionFormation_mass_for_many_class(file=None, Folder=None, diction=None):
try:
diction = mycommon.strip_dictionary(diction)
'''
# 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', 'session_id']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas, Creation session annulée")
return False, " Le champ '" + val + "' n'existe pas, Creation session 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 = ['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"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_token = diction['token']
# Verifier la validité du token
retval = mycommon.check_partner_token_validity("", my_token)
if retval is False:
return "Err_Connexion", " La session de connexion n'est pas valide"
# Verifier la validité du token
retval = mycommon.check_partner_token_validity("", my_token)
if retval is False:
return "Err_Connexion", " La session de connexion n'est pas valide"
partner_recid = mycommon.get_parnter_recid_from_token(my_token)
if (partner_recid is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - partner_recid KO : Impossible d'importer la liste des sessions ")
return False, "les information de connexion sont incorrectes. Impossible d'importer la liste des sessions"
status, saved_file = mycommon.Upload_Save_CSV_File(file, Folder)
if (status == False):
return False, "Impossible d'importer la liste des sessions, le nom du fichier est incorrect "
# " Lecture du fichier "
# print(" Lecture du fichier : "+saved_file)
nb_line = 0
exclusive_session_id = ""
exclusive_session_id_data = None
if( "session_id" in diction.keys() and diction['session_id']):
exclusive_session_id = str(diction['session_id'])
exclusive_session_id_count = MYSY_GV.dbname['session_formation'].count_documents({'_id':ObjectId(str(exclusive_session_id)),
'valide':'1',
'partner_owner_recid':str(partner_recid)})
if(exclusive_session_id_count != "1" ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
exclusive_session_id_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(exclusive_session_id)),
'valide': '1',
'partner_owner_recid': str(partner_recid)})
""""
update du 31/08/23 : Controle de l'integrité du fichier avant import
"""
local_controle_status, local_controle_message = Controle_Add_Update_SessionFormation_mass_for_many_class(saved_file,
Folder,
diction)
if (local_controle_status is False):
return local_controle_status, local_controle_message
print(" #### local_controle_message = ", local_controle_message)
df = pd.read_csv(saved_file, encoding='utf8', on_bad_lines='skip', sep=';', encoding_errors='ignore')
df = df.fillna('')
df = df.applymap(lambda x: x.strip() if isinstance(x, str) else x)
# Dictionnaire des champs utilisables
'''
# Verification que les noms des colonne sont bien corrects"
'''
field_list = ['date_debut', 'date_fin', 'nb_participant', 'adresse', 'code_postal', 'ville', 'pays',
'session_status', 'date_debut_inscription', 'date_fin_inscription', 'attestation',
'code_session', "distanciel", "presentiel", "mode_animation", "prix_session", 'contenu_ftion', 'lms_class_code',
'session_ondemande', 'session_etape', 'formation_code_externe', 'formateur_email', 'titre', 'location_type', 'is_bpf']
# Controle du nombre de lignes dans le fichier.
total_rows = len(df)
if (total_rows > MYSY_GV.MAX_PARTICIPANT_BY_CSV):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le fichier comporte plus de " + str(
MYSY_GV.MAX_PARTICIPANT_BY_CSV) + " lignes.")
return False, " Le fichier comporte plus de " + str(MYSY_GV.MAX_PARTICIPANT_BY_CSV) + " lignes."
# print(df.columns)
for val in df.columns:
if str(val).lower() not in field_list:
mycommon.myprint(
str(inspect.stack()[0][3]) + " : entete du fichier csv. '" + val + "' n'est pas acceptée")
return False, " Entete du fichier csv. La Colonne '" + val + "' n'est pas acceptée"
# Verification des champs obligatoires dans le fichier
field_list_obligatoire_file = ['date_debut', 'date_fin', 'session_status', 'code_session', 'formation_code_externe']
for val in field_list_obligatoire_file:
if val not in df.columns:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " : Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire")
return False, " Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire "
x = range(0, total_rows)
ignored_line = ""
nb_inserted_line = 0
for n in x:
mydata = {}
nb_inserted_line = nb_inserted_line + 1
# Si une ligne n'a aucune information obligatoire, alors on ignore la ligne
if (str(df['code_session'].values[n]) == "nan" or str(df['session_status'].values[n]) == "nan" or
str(df['date_debut'].values[n]) == "nan" or str(df['date_fin'].values[n]) == "nan"):
mycommon.myprint(str(
inspect.stack()[0][
3]) + " - La ligne " + str(n + 2) + " a été ignorée")
ignored_line = str(n + 2) + " , " + str(ignored_line)
nb_inserted_line = nb_inserted_line - 1
continue
mydata['date_debut'] = str(df['date_debut'].values[n]).strip().split(" ")[0]
local_status = mycommon.CheckisDate(mydata['date_debut'])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + "."
"La date debut n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + ". La date debut n'est pas au format jj/mm/aaaa "
mydata['date_fin'] = str(df['date_fin'].values[n]).strip().split(" ")[0]
local_status = mycommon.CheckisDate(mydata['date_fin'])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + "."
"La date date_fin n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 1) + ". La date fin n'est pas au format jj/mm/aaaa "
# Verifier que l'adresse email du formateur est valide
formateur_email = ""
formateur_id = ""
if ("formateur_email" in df.keys()):
if (str(df['formateur_email'].values[n]) and str(df['formateur_email'].values[n]) != ""):
formateur_email = str(df['formateur_email'].values[n]).strip()
if (mycommon.isEmailValide(formateur_email) is False):
mycommon.myprint(str(
inspect.stack()[0][3]) + " - L'email du formateur '" + str(
formateur_email) + "' pour la formation à la ligne " + str(
n + 2) + " n'est pas valide.")
return False, " L'email du formateur '" + str(
formateur_email) + "' pour la formation à la ligne " + str(
n + 2) + " n'est pas valide."
is_formateur_email_ok = MYSY_GV.dbname['ressource_humaine'].count_documents(
{'email': formateur_email,
'valide': '1',
'locked': '0',
'partner_recid': str(
partner_recid)})
if (is_formateur_email_ok <= 0):
mycommon.myprint(str(
inspect.stack()[0][3]) + " - L'email du formateur '" + str(
formateur_email) + "' pour la formation à la ligne " + str(
n + 2) + " n'est pas valide (2).")
return False, " L'email du formateur '" + str(
formateur_email) + "' pour la formation à la ligne " + str(
n + 2) + " n'est pas valide (2)."
formateur_data = MYSY_GV.dbname['ressource_humaine'].find_one({'email': formateur_email,
'valide': '1',
'locked': '0',
'partner_recid': str(
partner_recid)})
formateur_id = str(formateur_data['_id'])
mydata['formateur_id'] = formateur_id
if ("titre" in df.keys()):
mydata['titre'] = str(df['titre'].values[n]).strip()
if ("location_type" in df.keys()):
mydata['location_type'] = str(df['location_type'].values[n]).strip().lower()
if (str(df['location_type'].values[n]).strip().lower() not in MYSY_GV.TRAINING_LOCATION_TYPE):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Le champ 'location_type' est incorrecte.")
return False, "Le champ 'location_type' est incorrect."
if ("is_bpf" in df.keys()):
if (str(df['is_bpf'].values[n]).strip() not in ['0', '1']):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Le champ 'bpf' est incorrect. Les valeurs acceptées sont : '1' ou '0' ")
return False, "Le champ 'bpf' est incorrect. Les valeurs acceptées sont : '1' ou '0' "
mydata['is_bpf'] = str(df['is_bpf'].values[n]).strip()
## Verification de la cohérence des dates. Date_du doit <= Date_au
if (datetime.strptime(str(mydata['date_debut']).strip(), '%d/%m/%Y') > datetime.strptime(
str(mydata['date_fin']).strip(), '%d/%m/%Y')):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer la session de formation : La date debut " + str(
mydata['date_debut']) +
" est postérieure à la date de fin " + str(mydata['date_fin']) + " pour la ligne " + str(
n + 2) + " ")
return False, " Impossible de créer la session de formation : La date debut " + str(
mydata['date_debut'])[0:10] + \
" est postérieure à la date de fin " + str(mydata['date_fin'])[0:10] + " pour la ligne " + str(
n + 2) + " "
local_nb_participants = "1"
if ("nb_participant" in df.keys()):
if (str(df['nb_participant'].values[n])):
local_nb_participants = str(df['nb_participant'].values[n]).strip()
local_status, new_participants = mycommon.IsInt(local_nb_participants)
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'nb_participant' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ nb_participant de la ligne " + str(n + 2) + " est incorrecte. "
mydata['nb_participant'] = str(new_participants)
prix_session = "0"
if ("prix_session" in df.keys()):
if (str(df['prix_session'].values[n])):
prix_session = str(df['prix_session'].values[n]).strip()
local_status, new_prix_session = mycommon.IsFloat(prix_session)
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'prix_session' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ prix_session de la ligne " + str(n + 2) + " est incorrecte. "
mydata['prix_session'] = str(new_prix_session)
class_internal_url = ""
external_code = ""
if ("formation_code_externe" in df.keys()):
if (str(df['formation_code_externe'].values[n])):
external_code = str(df['formation_code_externe'].values[n]).strip()
#On verifie l'existance de l'external code pour ce une des formations de ce partner
count_class = MYSY_GV.dbname['myclass'].count_documents({'external_code':str(external_code), 'valide':'1',
'locked':'0', 'partner_owner_recid':str(partner_recid)})
if( count_class != 1 ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'code_externe' de la ligne " + str(
n + 2) + " ne correspond pas à une formation valide.")
return False, " Le champ 'code_externe' de la ligne " + str(
n + 2) + " ne correspond pas à une formation valide."
class_from_external_code = MYSY_GV.dbname['myclass'].find({'external_code':str(external_code), 'valide':'1',
'locked':'0', 'partner_owner_recid':str(partner_recid)})
if(class_from_external_code is None ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'code_exyer' de la ligne " + str(
n + 2) + " ne correspond pas à une formation valide (2).")
return False, " Le champ 'code_exyer' de la ligne " + str( n + 2) + " ne correspond pas à une formation valide (2)."
class_internal_url = str(class_from_external_code[0]['internal_url'])
local_code_session = ""
if ("code_session" in df.keys()):
if (str(df['code_session'].values[n])):
local_code_session = str(df['code_session'].values[n]).strip()
if (len(str(local_code_session).strip()) < 2):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'code_session' de la ligne " + str(
n + 2) + " doit faire plus de deux caractères.")
return False, " Le champ code_session de la ligne " + str(
n + 2) + " doit faire plus de deux caractères. "
mydata['code_session'] = local_code_session
local_adresse = ""
if ("adresse" in df.keys()):
if (str(df['adresse'].values[n])):
local_adresse = str(df['adresse'].values[n]).strip()
mydata['adresse'] = local_adresse
session_ondemande = ""
if ("session_ondemande" in df.keys()):
if (str(df['session_ondemande'].values[n])):
session_ondemande = str(df['session_ondemande'].values[n]).strip()
if (session_ondemande != "1" and session_ondemande != "0"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'session_ondemande' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ 'session_ondemande' de la ligne " + str(
n + 2) + " est incorrecte. Les valeurs acceptées sont '1' ou '0' ou vide"
mydata['session_ondemande'] = session_ondemande
local_code_postal = ""
if ("code_postal" in df.keys()):
if (str(df['code_postal'].values[n])):
local_code_postal = str(df['code_postal'].values[n]).strip()
if ("." in str(local_code_postal)):
# /!\ : l'utilisateur envoie un code poster au format entier, plutot que string.
local_code_postal = str(local_code_postal).split(".")[0]
elif ("." in str(local_code_postal)):
# /!\ : l'utilisateur envoie un code poster au format entier, plutot que string.
local_code_postal = str(local_code_postal).split(",")[0]
else:
local_code_postal = str(local_code_postal)
mydata['code_postal'] = local_code_postal
distanciel = ""
if ("distanciel" in df.keys()):
if (str(df['distanciel'].values[n])):
distanciel = str(df['distanciel'].values[n]).strip()
distanciel = str(mycommon.tryInt(distanciel))
if (distanciel != "1" and distanciel != "0"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'distanciel' de la ligne " + str(
n + 2) + " est incorrecte. Valeur reçue : "+str(distanciel))
return False, " Le champ 'distanciel' de la ligne " + str(
n + 2) + " est incorrecte. Les valeurs acceptées sont '1' ou '0' ou vide. Valeur reçue : "+str(distanciel)
mydata['distantiel'] = distanciel
presentiel = ""
if ("presentiel" in df.keys()):
if (str(df['presentiel'].values[n])):
presentiel = str(df['presentiel'].values[n]).strip()
presentiel = str(mycommon.tryInt(presentiel))
if (presentiel != "1" and presentiel != "0"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'presentiel' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ 'presentiel' de la ligne " + str(
n + 2) + " est incorrecte. Les valeurs acceptées sont '1' ou '0' ou vide"
mydata['presentiel'] = presentiel
mydata['presentiel'] = presentiel
mode_animation = ""
if ("mode_animation" in df.keys()):
if (str(df['mode_animation'].values[n])):
mode_animation = str(df['mode_animation'].values[n]).strip()
mode_animation = str(mycommon.tryInt(mode_animation))
if (mode_animation != "1" and mode_animation != "0" and mode_animation != "2"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'mode_animation' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ 'mode_animation' de la ligne " + str(
n + 2) + " est incorrecte. Les valeurs acceptées sont '0', '1', ou '2' ou vide"
mydata['mode_animation'] = mode_animation
# mydata['code_postal'] = str(df['code_postal'].values[n]).strip()
local_ville = ""
if ("ville" in df.keys()):
if (str(df['ville'].values[n])):
local_ville = str(df['ville'].values[n]).strip()
mydata['ville'] = local_ville
pays = ""
if ("pays" in df.keys()):
if (str(df['pays'].values[n])):
pays = str(df['pays'].values[n]).strip()
mydata['pays'] = pays
contenu_ftion = ""
if ("contenu_ftion" in df.keys()):
if (str(df['contenu_ftion'].values[n])):
contenu_ftion = str(df['contenu_ftion'].values[n]).strip()
mydata['contenu_ftion'] = contenu_ftion
# mydata['ville'] = str(df['ville'].values[n]).strip()
"""
local_attestation_certif = ""
if ("attestation" in df.keys()):
if (str(df['attestation'].values[n])):
local_attestation_certif = str(df['attestation'].values[n]).strip()
mydata['attestation_certif'] = local_attestation_certif
# mydata['attestation_certif'] = str(df['attestation'].values[n]).strip()
"""
session_status = ""
if ("session_status" in df.keys()):
if (str(df['session_status'].values[n])):
session_status = str(df['session_status'].values[n]).strip()
session_status = str(mycommon.tryInt(session_status))
mydata['session_status'] = session_status
session_etape = ""
if ("session_etape" in df.keys()):
if (str(df['session_etape'].values[n])):
session_etape = str(df['session_etape'].values[n]).strip()
mydata['session_etape'] = session_etape
"""
Update du 11/08/23 :
- le status va etre geré en 0 (desactivé) et 1 (activé)
- mise en commentaire du code ci-dessous
local_session = str(df['session_status'].values[n]).strip()
if( str(local_session) != "0" and str(local_session) != "1" and str(local_session) != "2"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'session_status' de la ligne " + str(n+2) + " est incorrecte. Les valeurs acceptées sont 0,1,2")
return False, " Le champ 'session_status' de la ligne " + str(n+2) + " est incorrecte. Les valeurs acceptées sont 0,1,2"
if( str(local_session) == "1"):
mydata['session_status'] = str("true")
"""
mydata['date_debut_inscription'] = str(df['date_debut_inscription'].values[n]).strip().split(" ")[0]
if( str(mydata['date_debut_inscription']).strip() != ""):
local_status = mycommon.CheckisDate(mydata['date_debut_inscription'])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + "."
"La date_debut_inscription n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + ". La date_debut_inscription n'est pas au format jj/mm/aaaa "
mydata['date_fin_inscription'] = str(df['date_fin_inscription'].values[n]).strip().split(" ")[0]
if (str(mydata['date_fin_inscription']).strip() != ""):
local_status = mycommon.CheckisDate(mydata['date_fin_inscription'])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + "."
"La date_fin_inscription n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 1) + ". La date_fin_inscription n'est pas au format jj/mm/aaaa "
## Verification de la cohérence des dates. Date_du doit <= Date_au
if (str(mydata['date_debut_inscription']).strip() != "" and str(mydata['date_fin_inscription']).strip() != ""):
if (datetime.strptime(str(mydata['date_debut_inscription']).strip(), '%d/%m/%Y') > datetime.strptime(
str(mydata['date_fin_inscription']).strip(), '%d/%m/%Y')):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer la session de formation : La date debut des inscriptions " + str(
mydata['date_debut_inscription']) +
" est postérieure à la date de fin des inscriptions " + str(
mydata['date_fin_inscription']) + " pour la ligne " + str(n + 2) + " ")
return False, " Impossible de créer la session de formation : La date de fin des inscriptions est antérieure à la date de début des inscriptions : Ligne " + str(
n + 2) + " "
mydata['token'] = str(my_token)
mydata['class_internal_url'] = str(class_internal_url)
#print(" ### mydata ", mydata)
diction_for_session_id = {}
diction_for_session_id['date_du'] = str(mydata['date_debut']).split(" ")[0]
diction_for_session_id['date_au'] = str(mydata['date_fin']).split(" ")[0]
diction_for_session_id['code_postal'] = str(mydata['code_postal'])
diction_for_session_id['adresse'] = str(mydata['adresse'])
"""
Verifier si la session existe deja en base, si c'est le cas récupérer le '_id'
la clé pour verifier l'existance d'une session est :
- code_session
- class_internal_url
- partner_owner_recid
"""
existing_session = MYSY_GV.dbname['session_formation'].find_one({'code_session':str(local_code_session), 'class_internal_url':str(class_internal_url),
'partner_owner_recid':str(partner_recid), 'valide':'1'})
if( existing_session is not None):
if( '_id' in existing_session.keys()):
mydata['session_id'] = existing_session['_id']
clean_dict = {k: mydata[k] for k in mydata if (str(mydata[k]) != "nan")}
print("#### Add_Update_SessionFormation_mass_for_many_class : clean_dict ", clean_dict)
status, retval = Add_Update_SessionFormation(clean_dict)
if (status is False):
return status, retval
print(str(total_rows) + " sessions ont été inserées")
message_ignored_line = ""
if (ignored_line):
message_ignored_line = " ATTENTION - Les lignes [" + str(
ignored_line) + "] ont été ignorées. car les toutes informations obligatoires ne sont pas fournies"
return True, str(nb_inserted_line) + " sessions ont été inserées / Mises à jour. " + str(message_ignored_line)
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible d'importer les sessions de formation en masse "
"""
Controle fichier avant import
"""
def Controle_Add_Update_SessionFormation_mass_for_many_class(saved_file=None, Folder=None, diction=None):
try:
diction = mycommon.strip_dictionary(diction)
'''
# 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']
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 session annulée")
return False, " Le champ '" + val + "' n'existe pas, Creation session 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 = ['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"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_token = diction['token']
# Verifier la validité du token
retval = mycommon.check_partner_token_validity("", my_token)
if retval is False:
return "Err_Connexion", " La session de connexion n'est pas valide"
partner_recid = mycommon.get_parnter_recid_from_token(my_token)
if (partner_recid is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - partner_recid KO : Impossible d'importer la liste des sessions ")
return False, "les information de connexion sont incorrectes. Impossible d'importer la liste des sessions"
nb_line = 0
df = pd.read_csv(saved_file, encoding='utf8', on_bad_lines='skip', sep=';', encoding_errors='ignore')
df = df.fillna('')
df = df.applymap(lambda x: x.strip() if isinstance(x, str) else x)
# Dictionnaire des champs utilisables
'''
# Verification que les noms des colonne sont bien corrects"
'''
field_list = ['date_debut', 'date_fin', 'nb_participant', 'adresse', 'code_postal', 'ville', 'pays',
'session_status', 'date_debut_inscription', 'date_fin_inscription', 'attestation',
'code_session', "distanciel", "presentiel", "mode_animation", "prix_session", 'contenu_ftion', 'lms_class_code',
'session_ondemande', 'session_etape', 'formation_code_externe', 'formateur_email', 'titre', 'location_type', 'is_bpf']
# Controle du nombre de lignes dans le fichier.
total_rows = len(df)
if (total_rows > MYSY_GV.MAX_PARTICIPANT_BY_CSV):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le fichier comporte plus de " + str(
MYSY_GV.MAX_PARTICIPANT_BY_CSV) + " lignes.")
return False, " Le fichier comporte plus de " + str(MYSY_GV.MAX_PARTICIPANT_BY_CSV) + " lignes."
# print(df.columns)
for val in df.columns:
if str(val).lower() not in field_list:
mycommon.myprint(
str(inspect.stack()[0][3]) + " : entete du fichier csv. '" + val + "' n'est pas acceptée")
return False, " Entete du fichier csv. La Colonne '" + val + "' n'est pas acceptée"
# Verification des champs obligatoires dans le fichier
field_list_obligatoire_file = ['date_debut', 'date_fin', 'session_status', 'code_session',
'formation_code_externe']
for val in field_list_obligatoire_file:
if val not in df.columns:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " : Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire")
return False, " Le champ '" + val + "' n'est pas présent dans le fichier. Il est obligatoire "
x = range(0, total_rows)
ignored_line = ""
nb_inserted_line = 0
for n in x:
mydata = {}
nb_inserted_line = nb_inserted_line + 1
# Si une ligne n'a aucune information obligatoire, alors on ignore la ligne
if (str(df['code_session'].values[n]) == "nan" or str(df['session_status'].values[n]) == "nan" or
str(df['date_debut'].values[n]) == "nan" or str(df['date_fin'].values[n]) == "nan"):
mycommon.myprint(str(
inspect.stack()[0][
3]) + " - La ligne " + str(n + 2) + " a été ignorée")
ignored_line = str(n + 2) + " , " + str(ignored_line)
nb_inserted_line = nb_inserted_line - 1
continue
external_code = ""
if ("formation_code_externe" in df.keys()):
if (str(df['formation_code_externe'].values[n])):
external_code = str(df['formation_code_externe'].values[n]).strip()
# On verifie l'existance de l'external code pour ce une des formations de ce partner
count_class = MYSY_GV.dbname['myclass'].count_documents(
{'external_code': str(external_code), 'valide': '1',
'locked': '0', 'partner_owner_recid': str(partner_recid)})
if (count_class < 0):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Ligne " + str(
n + 2) + " : Le code_externe n'est pas valide.")
return False, " Ligne " + str(n + 2) + " : Le code_externe n'est pas valide."
if (count_class > 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Erreur : Ligne " + str(
n + 2) + " : Le code_externe corresponds à plus d'une formation.")
return False, " Erreur : Ligne " + str(
n + 2) + " : Le code_externe corresponds à plus d'une formation."
class_date = MYSY_GV.dbname['myclass'].find_one(
{'external_code': str(external_code), 'valide': '1',
'locked': '0', 'partner_owner_recid': str(partner_recid)})
else:
mycommon.myprint(
str(inspect.stack()[0][3]) + " Erreur : Ligne " + str(
n + 2) + " : Le code_externe de la formation n'est pas invalide.")
return False, " Erreur : Ligne " + str(
n + 2) + " : Le code_externe de la formation n'est pas invalide."
mydata['date_debut'] = str(df['date_debut'].values[n]).strip().split(" ")[0]
local_status = mycommon.CheckisDate(mydata['date_debut'])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + "."
"La date debut n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + ". La date debut n'est pas au format jj/mm/aaaa "
mydata['date_fin'] = str(df['date_fin'].values[n]).strip().split(" ")[0]
local_status = mycommon.CheckisDate(mydata['date_fin'])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + "."
"La date date_fin n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 1) + ". La date fin n'est pas au format jj/mm/aaaa "
## Verification de la cohérence des dates. Date_du doit <= Date_au
if (datetime.strptime(str(mydata['date_debut']).strip(), '%d/%m/%Y') > datetime.strptime(
str(mydata['date_fin']).strip(), '%d/%m/%Y')):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer la session de formation : La date debut " + str(
mydata['date_debut']) +
" est postérieure à la date de fin " + str(mydata['date_fin']) + " pour la ligne " + str(
n + 2) + " ")
return False, " Impossible de créer la session de formation : La date debut " + str(
mydata['date_debut']) + \
" est postérieure à la date de fin " + str(mydata['date_fin'])[0:10] + " pour la ligne " + str(
n + 2) + " "
# Verifier que l'adresse email du formateur est valide
formateur_email = ""
formateur_id = ""
if ("formateur_email" in df.keys()):
if (str(df['formateur_email'].values[n]) and str(df['formateur_email'].values[n]) != ""):
formateur_email = str(df['formateur_email'].values[n]).strip()
if (mycommon.isEmailValide(formateur_email) is False):
mycommon.myprint(str(
inspect.stack()[0][3]) + " - L'email du formateur '" + str(
formateur_email) + "' pour la formation à la ligne " + str(
n + 2) + " n'est pas valide.")
return False, " L'email du formateur '" + str(
formateur_email) + "' pour la formation à la ligne " + str(
n + 2) + " n'est pas valide."
is_formateur_email_ok = MYSY_GV.dbname['ressource_humaine'].count_documents(
{'email': formateur_email,
'valide': '1',
'locked': '0',
'partner_recid': str(
partner_recid)})
if (is_formateur_email_ok <= 0):
mycommon.myprint(str(
inspect.stack()[0][3]) + " - L'email du formateur '" + str(
formateur_email) + "' pour la formation à la ligne " + str(
n + 2) + " n'est pas valide (2).")
return False, " L'email du formateur '" + str(
formateur_email) + "' pour la formation à la ligne " + str(
n + 2) + " n'est pas valide (2)."
formateur_data = MYSY_GV.dbname['ressource_humaine'].find_one({'email': formateur_email,
'valide': '1',
'locked': '0',
'partner_recid': str(
partner_recid)})
formateur_id = str(formateur_data['_id'])
mydata['formateur_id'] = formateur_id
if ("titre" in df.keys()):
mydata['titre'] = str(df['titre'].values[n]).strip()
if ("location_type" in df.keys()):
mydata['location_type'] = str(df['location_type'].values[n]).strip().lower()
if (str(df['location_type'].values[n]).strip().lower() not in MYSY_GV.TRAINING_LOCATION_TYPE):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Le champ 'location_type' est incorrecte. Les valeurs acceptés sont : "+str(MYSY_GV.TRAINING_LOCATION_TYPE))
return False, "Le champ 'location_type' est incorrect. . Les valeurs acceptés sont : "+str(MYSY_GV.TRAINING_LOCATION_TYPE)+ " "
if ("is_bpf" in df.keys()):
if (str(df['is_bpf'].values[n]).strip() not in ['0', '1']):
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ 'bpf' est incorrect. Les valeurs acceptées sont : '1' ou '0' ")
return False, "Le champ 'bpf' est incorrect. Les valeurs acceptées sont : '1' ou '0' "
mydata['is_bpf'] = str(df['is_bpf'].values[n]).strip()
local_nb_participants = "1"
if ("nb_participant" in df.keys()):
if (str(df['nb_participant'].values[n])):
local_nb_participants = str(df['nb_participant'].values[n]).strip()
local_status, new_participants = mycommon.IsInt(local_nb_participants)
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'nb_participant' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ nb_participant de la ligne " + str(n + 2) + " est incorrecte. Un nombre Entier Positif doit être fourni "
mydata['nb_participant'] = str(new_participants)
prix_session = "0"
if ("prix_session" in df.keys()):
if (str(df['prix_session'].values[n])):
prix_session = str(df['prix_session'].values[n]).strip()
local_status, new_prix_session = mycommon.IsFloat(prix_session)
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'prix_session' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ prix_session de la ligne " + str(n + 2) + " est incorrecte. "
mydata['prix_session'] = str(new_prix_session)
local_code_session = ""
if ("code_session" in df.keys()):
if (str(df['code_session'].values[n])):
local_code_session = str(df['code_session'].values[n]).strip()
if (len(str(local_code_session).strip()) < 2):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'code_session' de la ligne " + str(
n + 2) + " doit faire plus de deux caractères.")
return False, " Le champ code_session de la ligne " + str(
n + 2) + " doit faire plus de deux caractères. "
mydata['code_session'] = local_code_session
local_adresse = ""
if ("adresse" in df.keys()):
if (str(df['adresse'].values[n])):
local_adresse = str(df['adresse'].values[n]).strip()
mydata['adresse'] = local_adresse
session_ondemande = "0"
if ("session_ondemande" in df.keys()):
if (str(df['session_ondemande'].values[n])):
session_ondemande = str(df['session_ondemande'].values[n]).strip()
session_ondemande = str(mycommon.tryInt(str(session_ondemande)))
if (session_ondemande != "1" and session_ondemande != "0"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'session_ondemande' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ 'session_ondemande' de la ligne " + str(
n + 2) + " est incorrecte. Les valeurs acceptées sont '1' ou '0' ou vide"
mydata['session_ondemande'] = session_ondemande
local_code_postal = ""
if ("code_postal" in df.keys()):
if (str(df['code_postal'].values[n])):
local_code_postal = str(df['code_postal'].values[n]).strip()
if ("." in str(local_code_postal)):
# /!\ : l'utilisateur envoie un code poster au format entier, plutot que string.
local_code_postal = str(local_code_postal).split(".")[0]
elif ("." in str(local_code_postal)):
# /!\ : l'utilisateur envoie un code poster au format entier, plutot que string.
local_code_postal = str(local_code_postal).split(",")[0]
else:
local_code_postal = str(local_code_postal)
mydata['code_postal'] = local_code_postal
distanciel = ""
if ("distanciel" in df.keys()):
if (str(df['distanciel'].values[n])):
distanciel = str(df['distanciel'].values[n]).strip()
distanciel = str(mycommon.tryInt(distanciel))
if (distanciel != "1" and distanciel != "0"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'distanciel' de la ligne " + str(
n + 2) + " est incorrecte. La valeur fournie est "+str(distanciel) )
return False, " Le champ 'distanciel' de la ligne " + str(
n + 2) + " est incorrecte. Les valeurs acceptées sont '1' ou '0'. La valeur fournie est "+str(distanciel)
mydata['distantiel'] = distanciel
presentiel = ""
if ("presentiel" in df.keys()):
if (str(df['presentiel'].values[n])):
presentiel = str(df['presentiel'].values[n]).strip()
presentiel = str(mycommon.tryInt(presentiel))
if (presentiel != "1" and presentiel != "0"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'presentiel' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ 'presentiel' de la ligne " + str(
n + 2) + " est incorrecte. Les valeurs acceptées sont '1' ou '0' ou vide"
mydata['presentiel'] = presentiel
mydata['presentiel'] = presentiel
mode_animation = ""
if ("mode_animation" in df.keys()):
if (str(df['mode_animation'].values[n])):
mode_animation = str(df['mode_animation'].values[n]).strip()
mode_animation = str(mycommon.tryInt(mode_animation))
if (mode_animation != "1" and mode_animation != "0" and mode_animation != "2"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'mode_animation' de la ligne " + str(
n + 2) + " est incorrecte.")
return False, " Le champ 'mode_animation' de la ligne " + str(
n + 2) + " est incorrecte. Les valeurs acceptées sont '0', '1', ou '2' ou vide"
mydata['mode_animation'] = mode_animation
# mydata['code_postal'] = str(df['code_postal'].values[n]).strip()
local_ville = ""
if ("ville" in df.keys()):
if (str(df['ville'].values[n])):
local_ville = str(df['ville'].values[n]).strip()
mydata['ville'] = local_ville
local_pays = ""
if ("pays" in df.keys()):
if (str(df['pays'].values[n])):
local_pays = str(df['pays'].values[n]).strip()
mydata['pays'] = local_pays
contenu_ftion = ""
if ("contenu_ftion" in df.keys()):
if (str(df['contenu_ftion'].values[n])):
contenu_ftion = str(df['contenu_ftion'].values[n]).strip()
mydata['contenu_ftion'] = contenu_ftion
# mydata['ville'] = str(df['ville'].values[n]).strip()
local_attestation_certif = ""
if ("attestation" in df.keys()):
if (str(df['attestation'].values[n])):
local_attestation_certif = str(df['attestation'].values[n]).strip()
mydata['attestation_certif'] = local_attestation_certif
# mydata['attestation_certif'] = str(df['attestation'].values[n]).strip()
session_status = ""
if ("session_status" in df.keys()):
if (str(df['session_status'].values[n])):
session_status = str(df['session_status'].values[n]).strip()
mydata['session_status'] = session_status
session_etape = ""
if ("session_etape" in df.keys()):
if (str(df['session_etape'].values[n])):
session_etape = str(df['session_etape'].values[n]).strip()
mydata['session_etape'] = session_etape
"""
Update du 11/08/23 :
- le status va etre geré en 0 (desactivé) et 1 (activé)
- mise en commentaire du code ci-dessous
local_session = str(df['session_status'].values[n]).strip()
if( str(local_session) != "0" and str(local_session) != "1" and str(local_session) != "2"):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le champ 'session_status' de la ligne " + str(n+2) + " est incorrecte. Les valeurs acceptées sont 0,1,2")
return False, " Le champ 'session_status' de la ligne " + str(n+2) + " est incorrecte. Les valeurs acceptées sont 0,1,2"
if( str(local_session) == "1"):
mydata['session_status'] = str("true")
"""
mydata['date_debut_inscription'] = str(df['date_debut_inscription'].values[n]).strip().split(" ")[0]
local_status = mycommon.CheckisDate(mydata['date_debut_inscription'])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + "."
"La date_debut_inscription n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + ". La date_debut_inscription n'est pas au format jj/mm/aaaa "
mydata['date_fin_inscription'] = str(df['date_fin_inscription'].values[n]).strip().split(" ")[0]
local_status = mycommon.CheckisDate(mydata['date_fin_inscription'])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 2) + "."
"La date_fin_inscription n'est pas au format jj/mm/aaaa ")
return False, " - Impossible de créer/mettre à jour la session de formation à ligne " + str(
n + 1) + ". La date_fin_inscription n'est pas au format jj/mm/aaaa "
## Verification de la cohérence des dates. Date_du doit <= Date_au
if (datetime.strptime(str(mydata['date_debut_inscription']).strip(), '%d/%m/%Y') > datetime.strptime(
str(mydata['date_fin_inscription']).strip(), '%d/%m/%Y')):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de créer la session de formation : La date debut des inscriptions " + str(
mydata['date_debut_inscription']) +
" est postérieure à la date de fin des inscriptions " + str(
mydata['date_fin_inscription']) + " pour la ligne " + str(n + 2) + " ")
return False, " Impossible de créer la session de formation : La date de fin des inscriptions est antérieure à la date de début des inscriptions : Ligne " + str(
n + 2) + " "
mydata['token'] = str(my_token)
# print(" ### mydata ", mydata)
diction_for_session_id = {}
diction_for_session_id['date_du'] = str(mydata['date_debut']).split(" ")[0]
diction_for_session_id['date_au'] = str(mydata['date_fin']).split(" ")[0]
diction_for_session_id['code_postal'] = str(mydata['code_postal'])
diction_for_session_id['adresse'] = str(mydata['adresse'])
return True, str(total_rows)+" sessions dans le fichier"
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 controler le fichier des sessions de formation en masse "
"""
Cette fonction supprime une session de formation.
/!\ : il faut s'assurer qu'il n'y a aucune inscription avant de supprimer valide.
Et la session est supprimé, alors supprimer toutes inscriptions (annulée) associés
Ensuite supprimer les affectations d'enseignants et de materiels associée
12/01/2024 :
- Supprimer les sequences de cette session
- Dealloué les agenda
"""
def Delete_SessionFormation(diction):
try:
field_list = ['token', 'session_id', ]
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée")
return False, "de récupérer la liste des stagiaires . Toutes les informations fournies ne sont pas valables"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', 'session_id', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, "Impossible de récupérer la liste des stagiaires, Toutes les informations necessaires n'ont pas été fournies"
# Recuperation du recid du partner
mydata = {}
mytoken = ""
if ("token" in diction.keys()):
if diction['token']:
mytoken = diction['token']
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
if (local_status is not True):
return local_status, my_partner
partner_recid = str(my_partner['recid'])
session_id = ""
if ("session_id" in diction.keys()):
if diction['session_id']:
session_id = diction['session_id']
# Verifier qu'il n'y a pas d'incription valide
inscription_count_qry = {'session_id':str(session_id), 'status':{'$in':['0', '1', '2']} , 'partner_owner_recid':str(partner_recid)}
#print(" #### inscription_count_qry aa =", inscription_count_qry)
inscription_count = MYSY_GV.dbname['inscription'].count_documents(inscription_count_qry)
if( inscription_count > 0 ):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de supprimer la session. Vous avez "+str(inscription_count)+" inscription(s) associée(s) ")
return False, "Impossible de supprimer la session. Vous avez "+str(inscription_count)+" inscription(s) associée(s)"
"""
Verifier que l'inscription n'est pas utilisée dans un devis : 'partner_order_line'
"""
is_session_in_partner_order_line_count = MYSY_GV.dbname['partner_order_line'].count_documents({'order_line_session_id':str(session_id),
'partner_owner_recid':str(partner_recid)})
if( is_session_in_partner_order_line_count > 0 ):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de supprimer la session. Vous avez " + str(
is_session_in_partner_order_line_count) + " devis ou commandes (s) associé(s) ")
return False, "Impossible de supprimer la session. Vous avez " + str(
is_session_in_partner_order_line_count) + " devis ou commandes (s) associé(s) "
# Suppression des insciption eventuellement annulées
MYSY_GV.dbname['inscription'].delete_many({'session_id':str(session_id)})
# Suppression des affectation de ressources associées
delete_affectation_qry = {'related_target_collection':'session_formation', 'related_target_collection_id':str(session_id),
'partner_owner_recid': str(partner_recid)
}
# Pour les Ressource Humaine
MYSY_GV.dbname['ressource_humaine_affectation'].delete_many(delete_affectation_qry)
# Pour le materiel
MYSY_GV.dbname['ressource_materielle_affectation'].delete_many(delete_affectation_qry)
# 12/01/2024 : Supprimer les sequences
for sequence in MYSY_GV.dbname['session_formation_sequence'].find({'session_id':str(diction['session_id']),
'partner_owner_recid':str(my_partner['recid'])},
{'_id':1}):
local_status, local_retval = Session_Formation_Sequence.Delete_Given_Session_Sequence({'token':str(diction['token']), '_id':str(sequence['_id']) })
if( local_status is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " WARNING : Impossible de supprimer la sequence_id "+str(sequence['_id']))
# Suppression de la session
deleted_session_qry = {'_id':ObjectId(str(session_id)), 'partner_owner_recid':str(partner_recid)}
session_data = MYSY_GV.dbname['session_formation'].find_one(deleted_session_qry)
"""
## Add to log history
"""
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
# Pour la collection inscription
history_event_dict = {}
history_event_dict['token'] = mytoken
history_event_dict['related_collection'] = "session_formation"
history_event_dict['related_collection_recid'] = str(session_data['_id'])
history_event_dict['action_date'] = str(now)
local_session_info = ""
if ("code_session" in session_data.keys()):
local_session_info = local_session_info + ", " + session_data["code_session"]
else:
local_session_info = "Id Session : " + str(session_data['_id'])
history_event_dict['action_description'] = "Suppression de " + str(local_session_info)
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
deleted_data = MYSY_GV.dbname['session_formation'].delete_many(deleted_session_qry)
mycommon.myprint(
str(inspect.stack()[0][3]) + str(deleted_data.deleted_count) + " Document supprimé. La session_id " + str(
session_id) + " a été correctement supprimée ")
return True, "La session a été correctement supprimée"
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de supprimer la session de formation"
"""
Cette fonction prends une liste '_id' de session et effectue la Suppression
si les conditions sont remplie.
list_session_id = ['id1', 'id2', 'id3,]
"""
def Delete_List_SessionFormation(diction):
try:
field_list = ['token', 'list_session_id', ]
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée")
return False, "de récupérer la liste des stagiaires . Toutes les informations fournies ne sont pas valables"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', 'list_session_id', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, "Impossible de récupérer la liste des stagiaires, Toutes les informations necessaires n'ont pas été fournies"
# Recuperation du recid du partner
mydata = {}
mytoken = ""
if ("token" in diction.keys()):
if diction['token']:
mytoken = diction['token']
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
if (local_status is not True):
return local_status, my_partner
partner_recid = my_partner['recid']
list_session_id = []
if ("list_session_id" in diction.keys()):
if diction['list_session_id']:
list_session_id = str(diction['list_session_id']).replace(",", ";").split(";")
# Verifier qu'il n'y a pas d'incription valide
for session_id in list_session_id :
inscription_count_qry = {'session_id':str(session_id), 'status':{'$in':['0', '1', '2']} , 'partner_owner_recid':str(partner_recid)}
#print(" #### inscription_count_qry aa =", inscription_count_qry)
inscription_count = MYSY_GV.dbname['inscription'].count_documents(inscription_count_qry)
if( inscription_count > 0 ):
session_formation_data = MYSY_GV.dbname['session_formation'].find_one({'_id':ObjectId(str(session_id)), 'partner_owner_recid':str(partner_recid)})
mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible de supprimer la session "+str(session_formation_data['code_session'])+". Vous avez "+str(inscription_count)+" inscriptions associées.Suppression en masse annulée ")
return False, "Impossible de supprimer la session "+str(session_formation_data['code_session'])+". Vous avez "+str(inscription_count)+" inscriptions associées. Suppression en masse annulée"
"""
Verifier que l'inscription n'est pas utilisée dans un devis : 'partner_order_line'
"""
is_session_in_partner_order_line_count = MYSY_GV.dbname['partner_order_line'].count_documents(
{'order_line_session_id': str(session_id),
'partner_owner_recid': str(partner_recid)})
if (is_session_in_partner_order_line_count > 0):
session_formation_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(session_id)), 'partner_owner_recid': str(partner_recid)})
mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible de supprimer la session "+str(session_formation_data['code_session'])+". Vous avez " + str(
is_session_in_partner_order_line_count) + " devis ou commandes (s) associé(s) ")
return False, "Impossible de supprimer la session "+str(session_formation_data['code_session'])+". Vous avez " + str(
is_session_in_partner_order_line_count) + " devis ou commandes (s) associé(s) "
# Suppression des insciption eventuellement annulées
MYSY_GV.dbname['inscription'].delete_many({'session_id':{'$in':list_session_id}})
# Suppression des affectation de ressources associées
delete_affectation_qry = {'related_target_collection':'session_formation', 'related_target_collection_id':{'$in':list_session_id},
'partner_owner_recid': str(partner_recid)
}
# Pour les Ressource Humaine
MYSY_GV.dbname['ressource_humaine_affectation'].delete_many(delete_affectation_qry)
# Pour le materiel
MYSY_GV.dbname['ressource_materielle_affectation'].delete_many(delete_affectation_qry)
# Suppression des sessions
cpt = 0
for session_id in list_session_id:
deleted_session_qry = {'_id':ObjectId(str(session_id)), 'partner_owner_recid':str(partner_recid)}
deleted_data = MYSY_GV.dbname['session_formation'].delete_many(deleted_session_qry)
mycommon.myprint(str(inspect.stack()[0][3]) + str(deleted_data.deleted_count)+" Document supprimé. La session_id " + str(
session_id) + " a été correctement supprimée ")
cpt = cpt + 1
if( cpt > 1 ):
return True, "("+str(cpt)+") sessions ont été correctement supprimées"
else:
return True, "La session a été correctement supprimée"
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de supprimer la liste des sessions de formation"
"""
Cette fonction verifier des données correspondent à une session :
- internal_url
- date_debut
- date_fin
- si presentiel : la ville
- si distance, juste le a distance
"""
def Is_Corresponding_SessionFormation(diction):
try:
field_list = ['token', 'class_url', 'date_debut','date_fin', 'distantiel', 'mode_animation', 'ville' ]
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée")
return False, " Toutes les informations fournies ne sont pas valables"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', 'class_url', 'date_debut','date_fin', 'distantiel', 'mode_animation', 'ville' ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, " Toutes les informations necessaires n'ont pas été fournies"
# Recuperation du recid du partner
mydata = {}
mytoken = ""
if ("token" in diction.keys()):
if diction['token']:
mytoken = diction['token']
# Verifier la validité du token
retval = mycommon.check_partner_token_validity("", mytoken)
if retval is False:
return "Err_Connexion", " La session de connexion n'est pas valide"
partner_recid = mycommon.get_parnter_recid_from_token(mytoken)
if (partner_recid is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer la liste des stagiaires, ")
return False, " Les informations d'identification sont incorrectes "
class_url = ""
if ("class_url" in diction.keys()):
if diction['class_url']:
class_url = diction['class_url']
"""
Recuperation de l'internal url depuis l'url de la formation
"""
myclass_data = MYSY_GV.dbname['myclass'].find_one({'valide':"1", 'locked':'0',
'url':str(class_url)})
if( myclass_data is None or "internal_url" not in myclass_data.keys()):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer les données de la formation, ")
return False, " Impossible de récupérer les données de la formation, "
class_internal_url = str(myclass_data['internal_url'])
coll_session = MYSY_GV.dbname['session_formation']
myquery = [{'$match':{ 'class_internal_url':class_internal_url, 'partner_owner_recid':str(partner_recid)}},
{'$lookup':
{
'from': 'myclass',
'localField': 'class_internal_url',
'foreignField': 'internal_url',
'pipeline': [{'$project': {'title': 1, 'lms_class_code':1, 'recyclage_delai':1, 'recyclage_periodicite':1,
'lms_class_code':'1'}}],
'as': 'myclass'
}
}
]
print(" ##### myquery GetSessionFormation = "+str(myquery))
RetObject = []
nb_val = 0
for retval in coll_session.aggregate(myquery):
#print(" ##### Is_Corresponding_SessionFormation retval a controle = " + str(retval))
if (retval['mode_animation'] == diction['mode_animation'] and str(retval['date_debut'][0:10]) == diction[
'date_debut']
and str(retval['date_fin'][0:10]) == diction['date_fin'] and retval['ville'] == diction['ville']):
user = {}
user = retval
user['id'] = str(nb_val)
nb_val = nb_val + 1
title = ""
lms_class_code = ""
if ('myclass' in retval.keys() and len(retval['myclass']) > 0):
if( "title" in retval['myclass'][0].keys()):
title = retval['myclass'][0]['title']
if ("lms_class_code" in retval['myclass'][0].keys()):
lms_class_code = retval['myclass'][0]['lms_class_code']
user['title'] = title
user['lms_class_code'] = lms_class_code
RetObject.append(mycommon.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) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de verifier si la session correspond à une session existante"
"""
Cette fonction permet de dupliquer une session de formation.
par defaut lorqu'on duplique
- code_session = old_code_session+"_dup"
/!\ : Important : on prend une tab de session_id
"""
def Duplicate_List_Session_Formation(diction):
try:
field_list = ['token', 'tab_session_id', 'date_debut', 'date_fin', 'session_etape',
'formateur_id']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé.")
return False, " Toutes les informations fournies ne sont pas valables"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', 'tab_session_id', 'date_debut', 'date_fin']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, " Toutes les informations necessaires n'ont pas été fournies"
# Recuperation du recid du partner
mydata = {}
mytoken = ""
if ("token" in diction.keys()):
if diction['token']:
mytoken = diction['token']
# Verifier la validité du token
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data({'token':mytoken})
if (local_status is not True):
return local_status, my_partner
# Verification de la validité de toutes les session dans tab_session_id
tab_session_id = str(diction['tab_session_id']).split(',')
for session_id in tab_session_id :
if( MYSY_GV.dbname['session_formation'].count_documents({'_id':ObjectId(str(session_id)),
'valide':'1',
'partner_owner_recid':str(my_partner['recid'])}) != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " La session_id :"+str(session_id)+" n'est pas valide ")
return False, " La session_id :"+str(session_id)+" n'est pas valide "
# Verifier la validité du formateur si fourni
formateur_id = ""
if( "formateur_id" in diction.keys() and diction['formateur_id']):
formateur_id = diction['formateur_id']
is_valide_formateur_count = MYSY_GV.dbname['ressource_humaine'].count_documents({'partner_recid':my_partner['recid'],
'valide':'1',
'locked':'0',
'_id':ObjectId(str(formateur_id))})
if( is_valide_formateur_count != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant du formateur est invalide ")
return False, " L'identifiant du formateur est invalide "
# Verifier la validité de l'etape
session_etape = ""
if ("session_etape" in diction.keys()):
session_etape = str(diction['session_etape'])
is_valide_etape = MYSY_GV.dbname['base_partner_session_step'].count_documents({'partner_owner_recid':my_partner['recid'],
'valide':'1',
'locked':'0',
'session_step_name':str(session_etape)})
if( is_valide_etape != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'étape de la session est invalide ")
return False, " L'étape de la session est invalide "
# Verification des date et des cohérences de date
local_session_date_debut = ""
if ("date_debut" in diction.keys()):
local_session_date_debut = str(diction['date_debut'])[0:10]
local_session_date_fin = ""
if ("date_fin" in diction.keys()):
local_session_date_fin = str(diction['date_fin'])[0:10]
# Controle de cohérence sur les dates
local_status = mycommon.CheckisDate(str(diction['date_debut'])[0:10])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La date de debut n'est pas au format jj/mm/aaaa ")
return False, " La date de debut n'est pas au format jj/mm/aaaa "
local_status = mycommon.CheckisDate(str(diction['date_fin'])[0:10])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La date de fin n'est pas au format jj/mm/aaaa ")
return False, " La date de fin n'est pas au format jj/mm/aaaa "
if (datetime.strptime(str(diction['date_debut'])[0:10], '%d/%m/%Y') >= datetime.strptime(
str(diction['date_fin'])[0:10], '%d/%m/%Y')):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Session de Formation : La date debut " + str(
diction['date_debut'])[0:10] +
" doit être antérieure à la date de fin " + str(diction['date_fin'])[0:10])
return False, " Session de Formation : La date debut de formation " + str(diction['date_debut'])[0:10] + \
" doit être antérieure à la date de fin de formation " + str(diction['date_fin'])[0:10] + " "
# Duplicata
cpt = 0
now = str(datetime.now())
for session_id in tab_session_id:
session_data = MYSY_GV.dbname['session_formation'].find_one({'_id':ObjectId(str(session_id)),
'valide':'1',
'partner_owner_recid':str(my_partner['recid'])})
if( session_data is None):
mycommon.myprint(
str(inspect.stack()[0][3]) + " La session n'est pas valide ")
return False, " La session n'est pas valide "
duplicated_session = session_data
del duplicated_session['_id']
if( "invoiced_statut" in duplicated_session ):
del duplicated_session['invoiced_statut']
duplicated_session['code_session'] = str(session_data['code_session'])+"_dup"
duplicated_session['date_update'] = now
duplicated_session['update_by'] = str(my_partner['_id'])
duplicated_session['date_debut'] = str(diction['date_debut'])[0:10]
duplicated_session['date_fin'] = str(diction['date_fin'])[0:10]
duplicated_session['session_etape'] = str(diction['session_etape'])
duplicated_session['formateur_id'] = str(formateur_id)
local_retval = MYSY_GV.dbname['session_formation'].insert_one(duplicated_session)
"""
# Ajout de l'evenement dans l'historique
"""
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = diction['token']
history_event_dict['related_collection'] = "session_formation"
history_event_dict['related_collection_recid'] = str(local_retval.inserted_id)
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Creation (Dupliqué depuis "+str(duplicated_session['code_session'])+" "
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
cpt = cpt + 1
if(cpt > 1 ):
return True, "("+str(cpt)+" sessions ont été correctement dupliquées "
else:
return True, "La session a été correctement dupliquée "
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 dupliquer la session de formation"
"""
Cette fonction les conventions par email de formation en partant de la session.
Algo :
On recuperer les stagiaires qu'on groupe par client_rattachement_id
Pour tous ceux qui on le meme, on envoie une convention groupée
pour les autres, on envoi des conventions individuelle
"""
def Prepare_and_Send_Convention_From_Session_By_Email(tab_files, Folder, diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'email_test', 'email_production']
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"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
# Verifier qu'il ya bien des inscriptions valides dans la session pour le client
liste_client_rattachement_id = MYSY_GV.dbname['inscription'].distinct("client_rattachement_id",
{'session_id':str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(
my_partner['recid']),
"client_rattachement_id": { '$ne': ''}
}
)
print(" ### la liste des liste_client_rattachement_id = ", liste_client_rattachement_id)
# Sauvegarde des fichiers joints depuis le front
tab_saved_file_full_path = []
for file in tab_files:
status, saved_file_full_path = mycommon.Upload_Save_PDF_IMG_File(file, Folder)
if (status is False):
mycommon.myprint("Impossible de récupérer correctement le fichier à importer")
return False, "Impossible de récupérer correctement le fichier à importer"
tab_saved_file_full_path.append(saved_file_full_path)
print(" #### tab_saved_file_full_path = ", tab_saved_file_full_path)
# Recupération des données du modèle de document
is_convention_by_client = "0"
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
if( courrier_template_data and "edit_by_client" in courrier_template_data.keys() and courrier_template_data['edit_by_client'] == "1"):
is_convention_by_client = "1"
if( str(is_convention_by_client) == "1" ):
# Envoie des conventions pour les inscrits AVEC client_id (conventions d'entreprise)
for single_client in liste_client_rattachement_id :
print(" Traintement du client_id = ", single_client)
# Recuperation des contacts de communication du client
local_diction = {}
local_diction['token'] = diction['token']
local_diction['_id'] = str(single_client)
#print(" ##### local_diction = ", local_diction)
local_status, partner_client_contact_communication = partner_client.Get_Partner_Client_Communication_Contact(local_diction)
if (local_status is False):
mycommon.myprint(" Impossible de récupérer les contacts de communication du client ")
return False, " Impossible de récupérer les contacts de communication du client "
#print(" ### partner_client_contact_communication = ", partner_client_contact_communication)
tab_local_email_production = []
for tmp in partner_client_contact_communication:
tmp_JSON = ast.literal_eval(tmp)
if ("email" in tmp_JSON.keys()):
tab_local_email_production.append(str(tmp_JSON["email"]))
list_local_email_production = ",".join(tab_local_email_production)
new_diction_client = {}
new_diction_client['partner_client_id'] = single_client
new_diction_client['token'] = diction['token']
new_diction_client['courrier_template_id'] = diction['courrier_template_id']
new_diction_client['email_test'] = diction['email_test']
new_diction_client['email_production'] = str(list_local_email_production)
new_diction_client['session_id'] = diction['session_id']
new_diction_client['request_digital_signature'] = ""
if( "request_digital_signature" in diction.keys() ):
new_diction_client['request_digital_signature'] = diction['request_digital_signature']
#print(" ##### new_diction_client 0102 = ", new_diction_client)
local_status, local_retval = Inscription_mgt.Sent_Convention_Stagiaire_By_Email_By_Partner_client(tab_saved_file_full_path, Folder, new_diction_client)
if( local_status is False):
mycommon.myprint(" WARNING : impossible d'envoyer la convention au client : "+str( single_client))
elif (str(is_convention_by_client) == "0"):
liste_inscription_no_client = MYSY_GV.dbname['inscription'].find(
{"$or": [{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
"client_rattachement_id": ''
},
{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'client_rattachement_id': {'$exists': False}
}]
}
)
# Envoie des conventions pour les inscrits SANS client_id (conventions individuelles)
print(" ### is_convention_by_client ==== 0 : ")
print(" ### LIST traitement de l'inscrit : ", liste_inscription_no_client)
for single_inscrit_no_client in liste_inscription_no_client :
print(" ### traitement de l'inscrit : ",single_inscrit_no_client )
#field_list_obligatoire = [ 'token', 'inscription_id', 'courrier_template_id', 'email_test', 'email_production' ]
new_diction_no_client = {}
new_diction_no_client['token'] = str(diction['token'])
new_diction_no_client['inscription_id'] = str(single_inscrit_no_client['_id'])
new_diction_no_client['courrier_template_id'] = diction['courrier_template_id']
new_diction_no_client['session_id'] = diction['session_id']
new_diction_no_client['email_test'] = diction['email_test']
new_diction_no_client['email_production'] = diction['email_production']
new_diction_no_client['request_digital_signature'] = ""
if ("request_digital_signature" in diction.keys()):
new_diction_no_client['request_digital_signature'] = diction['request_digital_signature']
print(" ##### new_diction_no_client = ", new_diction_no_client)
local_status, local_retval = Inscription_mgt.Sent_Convention_Stagiaire_By_Email(tab_saved_file_full_path, Folder, new_diction_no_client)
if (local_status is False):
mycommon.myprint(" WARNING impossible d'envoyer la convention a l'apprenant : " + str(single_inscrit_no_client['_id']) )
else:
return False, " Vous devez definir si la convention est individuelle ou par client"
# Traitement de l'eventuel fichier joint
tab_files_to_attache_to_mail = []
return True, " Les conventions ont été correctement envoyées par emails"
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 d'envoyer les conventions par email "
"""
La meme que la précedente mais pour un groupe d'inscrit
/!\ : Les convention entreprise se font par CLIENT.
On utilise l'_id des inscrit pour aller chercher la liste des clients concernée.
Donc cela veut dire que mm si je n'ai pas selectionné un inscrit, si il a meme client qu'un autre inscrit qui est
selectionné, alors la convention mentionnera la liste des 2 inscrits, car tous les 2 releve de la meme entreprise.
"""
def Prepare_and_Send_Convention_From_Session_For_Selected_Inscrit_By_Email(tab_files, Folder, diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'email_test',
'email_production', 'tab_ids']
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"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
my_inscription_ids = ""
if ("tab_ids" in diction.keys()):
if diction['tab_ids']:
my_inscription_ids = diction['tab_ids']
tab_my_inscription_Object_ids = []
tab_my_inscription_ids = str(my_inscription_ids).split(",")
for my_inscription_id in tab_my_inscription_ids:
tab_my_inscription_Object_ids.append(ObjectId(str(my_inscription_id)))
# Verifier qu'il ya bien des inscriptions valides dans la session pour le client
liste_client_rattachement_id = MYSY_GV.dbname['inscription'].distinct("client_rattachement_id",
{'session_id':str(diction['session_id']),
'status': '1',
'_id': {'$in': tab_my_inscription_Object_ids},
'partner_owner_recid': str(
my_partner['recid']),
"client_rattachement_id": { '$ne': ''}
}
)
print(" ### la liste des liste_client_rattachement_id = ", liste_client_rattachement_id)
# Sauvegarde des fichiers joints depuis le front
tab_saved_file_full_path = []
for file in tab_files:
status, saved_file_full_path = mycommon.Upload_Save_PDF_IMG_File(file, Folder)
if (status is False):
mycommon.myprint("Impossible de récupérer correctement le fichier à importer")
return False, "Impossible de récupérer correctement le fichier à importer"
tab_saved_file_full_path.append(saved_file_full_path)
print(" #### tab_saved_file_full_path = ", tab_saved_file_full_path)
# Recupération des données du modèle de document
is_convention_by_client = "0"
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
if( courrier_template_data and "edit_by_client" in courrier_template_data.keys() and courrier_template_data['edit_by_client'] == "1"):
is_convention_by_client = "1"
if( str(is_convention_by_client) == "1" ):
# Envoie des conventions pour les inscrits AVEC client_id (conventions d'entreprise)
for single_client in liste_client_rattachement_id :
print(" Traintement du client_id = ", single_client)
# Recuperation des contacts de communication du client
local_diction = {}
local_diction['token'] = diction['token']
local_diction['_id'] = str(single_client)
#print(" ##### local_diction = ", local_diction)
local_status, partner_client_contact_communication = partner_client.Get_Partner_Client_Communication_Contact(local_diction)
if (local_status is False):
mycommon.myprint(" Impossible de récupérer les contacts de communication du client ")
return False, " Impossible de récupérer les contacts de communication du client "
#print(" ### partner_client_contact_communication = ", partner_client_contact_communication)
tab_local_email_production = []
for tmp in partner_client_contact_communication:
tmp_JSON = ast.literal_eval(tmp)
if ("email" in tmp_JSON.keys()):
tab_local_email_production.append(str(tmp_JSON["email"]))
list_local_email_production = ",".join(tab_local_email_production)
new_diction_client = {}
new_diction_client['partner_client_id'] = single_client
new_diction_client['token'] = diction['token']
new_diction_client['courrier_template_id'] = diction['courrier_template_id']
new_diction_client['email_test'] = diction['email_test']
new_diction_client['email_production'] = str(list_local_email_production)
new_diction_client['session_id'] = diction['session_id']
new_diction_client['request_digital_signature'] = ""
if( "request_digital_signature" in diction.keys() ):
new_diction_client['request_digital_signature'] = diction['request_digital_signature']
#print(" ##### new_diction_client 0102 = ", new_diction_client)
local_status, local_retval = Inscription_mgt.Sent_Convention_Stagiaire_By_Email_By_Partner_client(tab_saved_file_full_path, Folder, new_diction_client)
if( local_status is False):
mycommon.myprint(" WARNING : impossible d'envoyer la convention au client : "+str( single_client))
elif (str(is_convention_by_client) == "0"):
liste_inscription_no_client = MYSY_GV.dbname['inscription'].find(
{"$or": [{'session_id': str(diction['session_id']),
'status': '1',
'_id': {'$in': tab_my_inscription_Object_ids},
'partner_owner_recid': str(my_partner['recid']),
"client_rattachement_id": ''
},
{'session_id': str(diction['session_id']),
'status': '1',
'_id': {'$in': tab_my_inscription_Object_ids},
'partner_owner_recid': str(my_partner['recid']),
'client_rattachement_id': {'$exists': False}
}]
}
)
# Envoie des conventions pour les inscrits SANS client_id (conventions individuelles)
print(" ### is_convention_by_client ==== 0 : ")
print(" ### LIST traitement de l'inscrit : ", liste_inscription_no_client)
for single_inscrit_no_client in liste_inscription_no_client :
print(" ### traitement de l'inscrit : ",single_inscrit_no_client )
#field_list_obligatoire = [ 'token', 'inscription_id', 'courrier_template_id', 'email_test', 'email_production' ]
new_diction_no_client = {}
new_diction_no_client['token'] = str(diction['token'])
new_diction_no_client['inscription_id'] = str(single_inscrit_no_client['_id'])
new_diction_no_client['courrier_template_id'] = diction['courrier_template_id']
new_diction_no_client['session_id'] = diction['session_id']
new_diction_no_client['email_test'] = diction['email_test']
new_diction_no_client['email_production'] = diction['email_production']
new_diction_no_client['request_digital_signature'] = ""
if ("request_digital_signature" in diction.keys()):
new_diction_no_client['request_digital_signature'] = diction['request_digital_signature']
print(" ##### new_diction_no_client = ", new_diction_no_client)
local_status, local_retval = Inscription_mgt.Sent_Convention_Stagiaire_By_Email(tab_saved_file_full_path, Folder, new_diction_no_client)
if (local_status is False):
mycommon.myprint(" WARNING impossible d'envoyer la convention a l'apprenant : " + str(single_inscrit_no_client['_id']) )
else:
return False, " Vous devez definir si la convention est individuelle ou par client"
# Traitement de l'eventuel fichier joint
tab_files_to_attache_to_mail = []
return True, " Les conventions ont été correctement envoyées par emails"
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 d'envoyer les conventions par email "
"""
Cette fonction envoie les convention cochées par 'default'.
La fonction va envoyer les convention par defaut pour les inscrit rattachés à une societé et ceux rattaché à une societe.
Regle de gestion des adresse email :
Si le champ 'email_test' est rempli, alors il prend le pas sur la recherche des emails par defaut. Cela signifie que le
client veux faire un test.
"""
def Prepare_and_Send_Default_Convention_From_Session_By_Email(tab_files, Folder, diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'email_test', 'email_production']
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"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
is_test_mode = "0"
email_test = ""
if( "email_test" in diction.keys() and diction['email_test']):
email_test = diction['email_test']
if( mycommon.isEmailValide(email_test) is False ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'adresse email du test est invalide ")
return False, " L'adresse email du test est invalide "
is_test_mode = "1"
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
# Verifier qu'il ya bien des inscriptions valides dans la session pour le client
liste_client_rattachement_id = MYSY_GV.dbname['inscription'].distinct("client_rattachement_id",
{'session_id':str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(
my_partner['recid']),
"client_rattachement_id": { '$ne': ''}
}
)
# Sauvegarde des fichiers joints depuis le front
tab_saved_file_full_path = []
for file in tab_files:
status, saved_file_full_path = mycommon.Upload_Save_PDF_IMG_File(file, Folder)
if (status is False):
mycommon.myprint("Impossible de récupérer correctement le fichier à importer")
return False, "Impossible de récupérer correctement le fichier à importer"
tab_saved_file_full_path.append(saved_file_full_path)
"""
On verifie s'il y a des convention d'entreprise à faire, si oui on verifie si il y a un document
qui a été configuré
"""
if (len(liste_client_rattachement_id) > 0):
"""
# Recupération de la convention d'entreprise par defaut de à envoyer par email :
- ref_interne = "CONVENTION_STAGIAIRE"
- default_version = "1"
- edit_by_client = "1"
- type_doc = "email"
"""
default_courrier_template_client_count = MYSY_GV.dbname['courrier_template'].count_documents(
{'valide': '1',
'locked': '0',
'ref_interne': 'CONVENTION_STAGIAIRE',
'default_version': '1',
'edit_by_client': '1',
'type_doc': 'email',
'partner_owner_recid': str(my_partner['recid'])}
)
if( default_courrier_template_client_count <= 0 ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune convention d'entreprise n'est configurée - 1 ")
return False, " Aucune convention d'entreprise n'est configurée "
if (default_courrier_template_client_count > 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Il y a " + str(
default_courrier_template_client_count) + " conventions d'entreprise configurées. Il ne doit y avoir qu'une seule ")
return False, " Il y a " + str(
default_courrier_template_client_count) + " conventions d'entreprise configurées. Il ne doit y avoir qu'une seule "
nb_liste_inscription_no_client = MYSY_GV.dbname['inscription'].count_documents(
{"$or": [{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
"client_rattachement_id": ''
},
{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'client_rattachement_id': {'$exists': False}
}]
}
)
"""
On verifie s'il y a des conventions individuelles à faire, si oui on verifie si il y a un document
qui a été configuré
"""
if (nb_liste_inscription_no_client > 0):
"""
# Recupération de la convention individuelle par defaut de à envoyer par email :
- ref_interne = "CONVENTION_STAGIAIRE"
- default_version = "1"
- edit_by_client = "0"
- type_doc = "email"
"""
default_courrier_template_individuel_count = MYSY_GV.dbname['courrier_template'].count_documents(
{"$or": [{'valide': '1',
'locked': '0',
'ref_interne': 'CONVENTION_STAGIAIRE',
'default_version': '1',
'edit_by_client': '0',
'type_doc': 'email',
'partner_owner_recid': str(my_partner['recid'])}
,
{'valide': '1',
'locked': '0',
'ref_interne': 'CONVENTION_STAGIAIRE',
'default_version': '1',
'edit_by_client': {'$exists': False},
'type_doc': 'email',
'partner_owner_recid': str(my_partner['recid'])}
]
}
)
if (default_courrier_template_individuel_count <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune convention individuelle n'est configurée ")
return False, " Aucune convention d'individuelle n'est configurée "
if (default_courrier_template_individuel_count > 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Il y a "+str(default_courrier_template_individuel_count)+" conventions individuelles par défaut configurées. Il ne doit y avoir qu'une seule ")
return False, " Il y a "+str(default_courrier_template_individuel_count)+" conventions individuelles par défaut configurées. Il ne doit y avoir qu'une seule "
# Envoi des conventions d'entreprise par default
if( len(liste_client_rattachement_id) > 0 ):
# Il y a bien de inscris rattachés à des client. on cherche et envoie les conventions d'entreprises)
# Recuperer les datas de la convention par defautl
default_courrier_template_client_data = MYSY_GV.dbname['courrier_template'].find_one(
{'valide': '1',
'locked': '0',
'ref_interne': 'CONVENTION_STAGIAIRE',
'default_version': '1',
'edit_by_client': '1',
'type_doc': 'email',
'partner_owner_recid': str(my_partner['recid'])}
)
for single_client in liste_client_rattachement_id :
# Recuperation des contacts de communication du client
local_diction = {}
local_diction['token'] = diction['token']
local_diction['_id'] = str(single_client)
print(" ## Traitement du client id: ", str(single_client))
local_status, partner_client_contact_communication = partner_client.Get_Partner_Client_Communication_Contact(local_diction)
if (local_status is False):
mycommon.myprint(" Impossible de récupérer les contacts de communication du client ")
return False, " Impossible de récupérer les contacts de communication du client "
tab_local_email_production = []
for tmp in partner_client_contact_communication:
tmp_JSON = ast.literal_eval(tmp)
if ("email" in tmp_JSON.keys()):
tab_local_email_production.append(str(tmp_JSON["email"]))
list_local_email_production = ",".join(tab_local_email_production)
new_diction_client = {}
new_diction_client['partner_client_id'] = single_client
new_diction_client['token'] = diction['token']
new_diction_client['courrier_template_id'] = default_courrier_template_client_data['_id']
if( is_test_mode == "1"):
new_diction_client['email_test'] = email_test
new_diction_client['email_production'] = ""
else:
new_diction_client['email_test'] = ""
new_diction_client['email_production'] = str(list_local_email_production)
new_diction_client['session_id'] = diction['session_id']
new_diction_client['request_digital_signature'] = ""
if ("request_digital_signature" in diction.keys()):
new_diction_client['request_digital_signature'] = diction['request_digital_signature']
local_status, local_retval = Inscription_mgt.Sent_Convention_Stagiaire_By_Email_By_Partner_client(tab_saved_file_full_path, Folder, new_diction_client)
if( local_status is False):
mycommon.myprint(" WARNING : impossible d'envoyer la convention au client : "+str( single_client))
# Envoi des conventions individuelles par defaut
if (nb_liste_inscription_no_client > 0):
liste_inscription_no_client = MYSY_GV.dbname['inscription'].find(
{"$or": [{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
"client_rattachement_id": ''
},
{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'client_rattachement_id': {'$exists': False}
}]
}
)
# Recuperer les datas de la convention par defautl
default_courrier_template_individuel_data = MYSY_GV.dbname['courrier_template'].find_one(
{"$or": [{'valide': '1',
'locked': '0',
'ref_interne': 'CONVENTION_STAGIAIRE',
'default_version': '1',
'edit_by_client': '0',
'type_doc': 'email',
'partner_owner_recid': str(my_partner['recid'])}
,
{'valide': '1',
'locked': '0',
'ref_interne': 'CONVENTION_STAGIAIRE',
'default_version': '1',
'edit_by_client': {'$exists': False},
'type_doc': 'email',
'partner_owner_recid': str(my_partner['recid'])}
]
}
)
# Envoie des conventions pour les inscrits SANS client_id (conventions individuelles)
print(" ### is_convention_by_client ==== 0 : ")
print(" ### LIST traitement de l'inscrit : ", liste_inscription_no_client)
for single_inscrit_no_client in liste_inscription_no_client :
print(" ### traitement de l'inscrit : ",single_inscrit_no_client )
#field_list_obligatoire = [ 'token', 'inscription_id', 'courrier_template_id', 'email_test', 'email_production' ]
new_diction_no_client = {}
new_diction_no_client['token'] = str(diction['token'])
new_diction_no_client['inscription_id'] = str(single_inscrit_no_client['_id'])
new_diction_no_client['courrier_template_id'] = default_courrier_template_individuel_data['_id']
new_diction_no_client['session_id'] = diction['session_id']
if (is_test_mode == "1"):
new_diction_no_client['email_test'] = email_test
new_diction_no_client['email_production'] = ""
else:
new_diction_no_client['email_test'] = ""
new_diction_no_client['email_production'] = ""
print(" ##### new_diction_no_client = ", new_diction_no_client)
local_status, local_retval = Inscription_mgt.Sent_Convention_Stagiaire_By_Email(tab_saved_file_full_path, Folder, new_diction_no_client)
if (local_status is False):
mycommon.myprint(" WARNING impossible d'envoyer la convention a l'apprenant : " + str(single_inscrit_no_client['_id']) )
else:
return False, " Vous devez definir si la convention est individuelle ou par client"
# Traitement de l'eventuel fichier joint
tab_files_to_attache_to_mail = []
return True, " Les conventions ont été correctement envoyées par emails"
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 d'envoyer les conventions par email "
"""
Cette fonction permet de telecharger PDF toutes les conventions d'une session.
Depuis la session, l'utilisateur choisi le modele PDF et
telecharge les conventions d'entreprise et les conventions individuelles.
On créé un fichier zip qui sera téléchargé avec toutes les pièces jointes
"""
def Prepare_and_Send_Convention_From_Session_By_PDF(diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La valeur '" + val + "' n'est pas presente dans liste ")
return False, " La valeur '" + val + "' n'est pas presente dans liste"
elif str(diction[val]).strip() == "":
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Le champ obligatoire '" + val + "' est vide ")
return False, " Le champ obligatoire '" + val + "' est vide "
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
# Stokage des nom de fichier à zipper
list_file_name_to_zip = []
# Verifier qu'il ya bien des inscriptions valides dans la session pour le client
liste_client_rattachement_id = MYSY_GV.dbname['inscription'].distinct("client_rattachement_id",
{'session_id':str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(
my_partner['recid']),
"client_rattachement_id": { '$ne': ''}
}
)
print(" ### la liste des liste_client_rattachement_id = ", liste_client_rattachement_id)
# Recuperer inscriptions indépenantes, donc pas liée à un client
liste_inscription_no_client = MYSY_GV.dbname['inscription'].find({"$or": [{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
"client_rattachement_id": ''
},
{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'client_rattachement_id': {'$exists': False}
}]
}
)
"""
for val in liste_inscription_no_client:
print(" ### la liste des liste_inscription_no_client = ", str(val))
"""
# Recupération des données du modèle de document
is_convention_by_client = "0"
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
if (courrier_template_data and "edit_by_client" in courrier_template_data.keys() and courrier_template_data[
'edit_by_client'] == "1"):
is_convention_by_client = "1"
if (str(is_convention_by_client) == "1"):
# Envoie des conventions pour les inscrits AVEC client_id
for val in liste_client_rattachement_id:
local_diction = {}
# field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'client_id']
local_diction['token'] = diction['token']
local_diction['session_id'] = diction['session_id']
local_diction['courrier_template_id'] = diction['courrier_template_id']
local_diction['client_id'] = str(val)
print(" ### UUU Client_id = ", str(val))
local_status, local_full_file_name = Create_Convention_By_Client_PDF(local_diction)
if( local_status is False):
return local_status, local_full_file_name
else:
list_file_name_to_zip.append(str(local_full_file_name))
elif (str(is_convention_by_client) == "0"):
liste_inscription_no_client = MYSY_GV.dbname['inscription'].find(
{"$or": [{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
"client_rattachement_id": ''
},
{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'client_rattachement_id': {'$exists': False}
}]
}
)
for val in liste_inscription_no_client:
local_diction = {}
# field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'client_id']
local_diction['token'] = diction['token']
local_diction['session_id'] = diction['session_id']
local_diction['courrier_template_id'] = diction['courrier_template_id']
local_diction['inscription_id'] = str(val['_id'])
#print(" #### Traitemnt de local_diction bb = ", local_diction)
local_status, local_full_file_name = Create_Convention_By_Stagiaire_PDF(local_diction)
if( local_status is False):
return local_status, local_full_file_name
else:
list_file_name_to_zip.append(str(local_full_file_name))
# Create a ZipFile Object
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-3:]
zip_file_name = str(MYSY_GV.TEMPORARY_DIRECTORY_V2)+"List_Convention_session_"+str(diction['session_id'])+"_"+str(ts)+".zip"
with ZipFile(zip_file_name, 'w') as zip_object:
for pdf_files in list_file_name_to_zip :
#print(" ### fichier a zipper = ", pdf_files)
zip_object.write(str(pdf_files))
if os.path.exists(zip_file_name):
# print(" ### ok os.path.exists(outputFilename) "+str(outputFilename))
return True, send_file(zip_file_name, as_attachment=True)
return False, " Impossible de générer les conventions par pdf PDF (1) "
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 générer les conventions par pdf PDF "
"""
La meme que la précedente sauf qu'on fourni une liste d'inscrit en argument
/!\ : Les convention entreprise se font par CLIENT.
On utilise l'_id des inscrit pour aller chercher la liste des clients concernée.
Donc cela veut dire que mm si je n'ai pas selectionné un inscrit, si il a meme client qu'un autre inscrit qui est
selectionné, alors la convention mentionnera la liste des 2 inscrits, car tous les 2 releve de la meme entreprise.
"""
def Prepare_and_Send_Convention_From_Session_For_Selected_Inscrit_By_PDF(diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'tab_ids']
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"
elif str(diction[val]).strip() == "":
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Le champ obligatoire '" + val + "' est vide ")
return False, " Le champ obligatoire '" + val + "' est vide "
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
my_inscription_ids = ""
if ("tab_ids" in diction.keys()):
if diction['tab_ids']:
my_inscription_ids = diction['tab_ids']
tab_my_inscription_Object_ids = []
tab_my_inscription_ids = str(my_inscription_ids).split(",")
for my_inscription_id in tab_my_inscription_ids:
tab_my_inscription_Object_ids.append(ObjectId(str(my_inscription_id)))
# Stokage des nom de fichier à zipper
list_file_name_to_zip = []
# Verifier qu'il ya bien des inscriptions valides dans la session pour le client
liste_client_rattachement_id = MYSY_GV.dbname['inscription'].distinct("client_rattachement_id",
{'session_id':str(diction['session_id']),
'status': '1',
'_id': {
'$in': tab_my_inscription_Object_ids},
'partner_owner_recid': str(
my_partner['recid']),
"client_rattachement_id": { '$ne': ''}
}
)
print(" ### la liste des liste_client_rattachement_id = ", liste_client_rattachement_id)
# Recuperer inscriptions indépenantes, donc pas liée à un client
liste_inscription_no_client = MYSY_GV.dbname['inscription'].find({"$or": [{'session_id': str(diction['session_id']),
'status': '1',
'_id': {
'$in': tab_my_inscription_Object_ids},
'partner_owner_recid': str(my_partner['recid']),
"client_rattachement_id": ''
},
{'session_id': str(diction['session_id']),
'status': '1',
'_id': {
'$in': tab_my_inscription_Object_ids},
'partner_owner_recid': str(my_partner['recid']),
'client_rattachement_id': {'$exists': False}
}]
}
)
"""
for val in liste_inscription_no_client:
print(" ### la liste des liste_inscription_no_client = ", str(val))
"""
# Recupération des données du modèle de document
is_convention_by_client = "0"
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
if (courrier_template_data and "edit_by_client" in courrier_template_data.keys() and courrier_template_data[
'edit_by_client'] == "1"):
is_convention_by_client = "1"
if (str(is_convention_by_client) == "1"):
# Envoie des conventions pour les inscrits AVEC client_id
for val in liste_client_rattachement_id:
local_diction = {}
# field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'client_id']
local_diction['token'] = diction['token']
local_diction['session_id'] = diction['session_id']
local_diction['courrier_template_id'] = diction['courrier_template_id']
local_diction['client_id'] = str(val)
print(" ## ZZZ1 client_id PRRRR = ", str(val))
local_status, local_full_file_name = Create_Convention_By_Client_PDF(local_diction)
if( local_status is False):
return local_status, local_full_file_name
else:
list_file_name_to_zip.append(str(local_full_file_name))
elif (str(is_convention_by_client) == "0"):
liste_inscription_no_client = MYSY_GV.dbname['inscription'].find(
{"$or": [{'session_id': str(diction['session_id']),
'status': '1',
'_id': {'$in': tab_my_inscription_Object_ids},
'partner_owner_recid': str(my_partner['recid']),
"client_rattachement_id": ''
},
{'session_id': str(diction['session_id']),
'status': '1',
'_id': {'$in': tab_my_inscription_Object_ids},
'partner_owner_recid': str(my_partner['recid']),
'client_rattachement_id': {'$exists': False}
}]
}
)
for val in liste_inscription_no_client:
local_diction = {}
# field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'client_id']
local_diction['token'] = diction['token']
local_diction['session_id'] = diction['session_id']
local_diction['courrier_template_id'] = diction['courrier_template_id']
local_diction['inscription_id'] = str(val['_id'])
#print(" #### Traitemnt de local_diction bb = ", local_diction)
local_status, local_full_file_name = Create_Convention_By_Stagiaire_PDF(local_diction)
if( local_status is False):
return local_status, local_full_file_name
else:
list_file_name_to_zip.append(str(local_full_file_name))
# Create a ZipFile Object
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-3:]
zip_file_name = str(MYSY_GV.TEMPORARY_DIRECTORY_V2)+"List_Convention_session_"+str(diction['session_id'])+"_"+str(ts)+".zip"
with ZipFile(zip_file_name, 'w') as zip_object:
for pdf_files in list_file_name_to_zip :
#print(" ### fichier a zipper = ", pdf_files)
zip_object.write(str(pdf_files))
if os.path.exists(zip_file_name):
# print(" ### ok os.path.exists(outputFilename) "+str(outputFilename))
return True, send_file(zip_file_name, as_attachment=True)
return False, " Impossible de générer les conventions par pdf PDF (1) "
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 générer les conventions par pdf PDF "
"""
Cette fonction permet de telecharge les conventions par defaut pour les entreprises et les individuels
"""
def Prepare_and_Send_Default_Convention_From_Session_By_PDF(diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La valeur '" + val + "' n'est pas presente dans liste ")
return False, " La valeur '" + val + "' n'est pas presente dans liste"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
# Verifier qu'il ya bien des inscriptions valides dans la session pour le client
liste_client_rattachement_id = MYSY_GV.dbname['inscription'].distinct("client_rattachement_id",
{'session_id': str(
diction['session_id']),
'status': '1',
'partner_owner_recid': str(
my_partner['recid']),
"client_rattachement_id": {'$ne': ''}
}
)
# --------
"""
On verifie s'il y a des convention d'entreprise à faire, si oui on verifie si il y a un document
qui a été configuré
"""
if (len(liste_client_rattachement_id) > 0):
"""
# Recupération de la convention d'entreprise par defaut de à envoyer par email :
- ref_interne = "CONVENTION_STAGIAIRE"
- default_version = "1"
- edit_by_client = "1"
- type_doc = "pdf"
"""
default_courrier_template_client_count = MYSY_GV.dbname['courrier_template'].count_documents(
{'valide': '1',
'locked': '0',
'ref_interne': 'CONVENTION_STAGIAIRE',
'default_version': '1',
'edit_by_client': '1',
'type_doc': 'pdf',
'partner_owner_recid': str(my_partner['recid'])}
)
if (default_courrier_template_client_count <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune convention d'entreprise n'est configurée - 2")
return False, " Aucune convention d'entreprise n'est configurée "
if (default_courrier_template_client_count > 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Il y a " + str(
default_courrier_template_client_count) + " conventions d'entreprise par défaut configurées. Il ne doit y avoir qu'une seule ")
return False, " Il y a " + str(
default_courrier_template_client_count) + " conventions d'entreprise par défaut configurées. Il ne doit y avoir qu'une seule "
nb_liste_inscription_no_client = MYSY_GV.dbname['inscription'].count_documents(
{"$or": [{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
"client_rattachement_id": ''
},
{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'client_rattachement_id': {'$exists': False}
}]
}
)
"""
On verifie s'il y a des conventions individuelles à faire, si oui on verifie si il y a un document
qui a été configuré
"""
if (nb_liste_inscription_no_client > 0):
"""
# Recupération de la convention individuelle par defaut de à envoyer par email :
- ref_interne = "CONVENTION_STAGIAIRE"
- default_version = "1"
- edit_by_client = "0"
- type_doc = "pdf"
"""
qry_indi = {"$or": [{'valide': '1',
'locked': '0',
'ref_interne': 'CONVENTION_STAGIAIRE',
'default_version': '1',
'edit_by_client': '0',
'type_doc': 'pdf',
'partner_owner_recid': str(my_partner['recid'])}
,
{'valide': '1',
'locked': '0',
'ref_interne': 'CONVENTION_STAGIAIRE',
'default_version': '1',
'edit_by_client': {'$exists': False},
'type_doc': 'pdf',
'partner_owner_recid': str(my_partner['recid'])}
]
}
default_courrier_template_individuel_count = MYSY_GV.dbname['courrier_template'].count_documents(
{"$or": [{'valide': '1',
'locked': '0',
'ref_interne': 'CONVENTION_STAGIAIRE',
'default_version': '1',
'edit_by_client': '0',
'type_doc': 'pdf',
'partner_owner_recid': str(my_partner['recid'])}
,
{'valide': '1',
'locked': '0',
'ref_interne': 'CONVENTION_STAGIAIRE',
'default_version': '1',
'edit_by_client': {'$exists': False},
'type_doc': 'pdf',
'partner_owner_recid': str(my_partner['recid'])}
]
}
)
if (default_courrier_template_individuel_count <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune convention individuelle n'est configurée ")
return False, " Aucune convention d'individuelle n'est configurée "
if (default_courrier_template_individuel_count > 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Il y a " + str(
default_courrier_template_individuel_count) + " conventions individuelles configurées. Il ne doit y avoir qu'une seule ")
return False, " Il y a " + str(
default_courrier_template_individuel_count) + " conventions individuelles configurées. Il ne doit y avoir qu'une seule "
# -------------
# Stokage des nom de fichier à zipper
list_file_name_to_zip = []
# Recuperer inscriptions indépenantes, donc pas liée à un client
liste_inscription_no_client = MYSY_GV.dbname['inscription'].find(
{"$or": [{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
"client_rattachement_id": ''
},
{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'client_rattachement_id': {'$exists': False}
}]
}
)
# Envoi des conventions d'entreprise par default
if (len(liste_client_rattachement_id) > 0):
# Recuperer les datas de la convention par defautl
default_courrier_template_client_data = MYSY_GV.dbname['courrier_template'].find_one(
{'valide': '1',
'locked': '0',
'ref_interne': 'CONVENTION_STAGIAIRE',
'default_version': '1',
'edit_by_client': '1',
'type_doc': 'pdf',
'partner_owner_recid': str(my_partner['recid'])}
)
for val in liste_client_rattachement_id:
local_diction = {}
# field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'client_id']
local_diction['token'] = diction['token']
local_diction['session_id'] = diction['session_id']
local_diction['courrier_template_id'] = default_courrier_template_client_data['_id']
local_diction['client_id'] = str(val)
#print(" #### Traitemnt de local_diction aaa = ", local_diction)
local_status, local_full_file_name = Create_Convention_By_Client_PDF(local_diction)
if( local_status is False):
return local_status, local_full_file_name
else:
print(" ### pdf_file_name = ", local_full_file_name)
list_file_name_to_zip.append(str(local_full_file_name))
# Envoi des conventions individuelles par defaut
# Envoi des conventions individuelles par defaut
if (nb_liste_inscription_no_client > 0):
liste_inscription_no_client = MYSY_GV.dbname['inscription'].find(
{"$or": [{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
"client_rattachement_id": ''
},
{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'client_rattachement_id': {'$exists': False}
}]
}
)
# Recuperer les datas de la convention par defautl
default_courrier_template_individuel_data = MYSY_GV.dbname['courrier_template'].find_one(
{"$or": [{'valide': '1',
'locked': '0',
'ref_interne': 'CONVENTION_STAGIAIRE',
'default_version': '1',
'edit_by_client': '0',
'type_doc': 'pdf',
'partner_owner_recid': str(my_partner['recid'])}
,
{'valide': '1',
'locked': '0',
'ref_interne': 'CONVENTION_STAGIAIRE',
'default_version': '1',
'edit_by_client': {'$exists': False},
'type_doc': 'pdf',
'partner_owner_recid': str(my_partner['recid'])}
]
}
)
for val in liste_inscription_no_client:
local_diction = {}
# field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'client_id']
local_diction['token'] = diction['token']
local_diction['session_id'] = diction['session_id']
local_diction['courrier_template_id'] = default_courrier_template_individuel_data['_id']
local_diction['inscription_id'] = str(val['_id'])
#print(" #### Traitemnt de local_diction bb = ", local_diction)
local_status, local_full_file_name = Create_Convention_By_Stagiaire_PDF(local_diction)
if( local_status is False):
return local_status, local_full_file_name
else:
list_file_name_to_zip.append(str(local_full_file_name))
# Create a ZipFile Object
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-3:]
zip_file_name = str(MYSY_GV.TEMPORARY_DIRECTORY_V2)+"List_Convention_session_"+str(diction['session_id'])+"_"+str(ts)+".zip"
with ZipFile(zip_file_name, 'w') as zip_object:
for pdf_files in list_file_name_to_zip :
#print(" ### fichier a zipper = ", pdf_files)
zip_object.write(str(pdf_files))
if os.path.exists(zip_file_name):
# print(" ### ok os.path.exists(outputFilename) "+str(outputFilename))
return True, send_file(zip_file_name, as_attachment=True)
return False, " Impossible de générer les conventions par PDF (1) "
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 générer les conventions par pdf PDF "
"""
Cette fonction créer un PDF par client et retounr l'url complet du fichier pdf
pour les client (convention de type client)
"""
def Create_Convention_By_Client_PDF(diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'client_id']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La valeur '" + val + "' n'est pas presente dans liste ")
return False, " La valeur '" + val + "' n'est pas presente dans liste"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# 1 - Verifier que le modele de courrier est bien editable par client
template_courrier_data = MYSY_GV.dbname['courrier_template'].find_one({'_id':ObjectId(str(diction['courrier_template_id'])),
'valide':'1',
'locked':'0',
'partner_owner_recid':str(my_partner['recid'])})
if( template_courrier_data is None or "edit_by_client" not in template_courrier_data.keys() or str(template_courrier_data['edit_by_client']) != "1" ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Le modèle de courrier n'est pas éditable par client ")
return False, " Le modèle de courrier n'est pas éditable par client "
# Verifier que le client est valide
client_data = MYSY_GV.dbname['partner_client'].find_one({'_id':ObjectId(str(diction['client_id'])), 'valide':'1',
'locked':'0',
'partner_recid':str(my_partner['recid'])})
if (client_data is None ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant du client est invalide ")
return False, " L'identifiant du client est invalide "
tab_client = []
tab_client.append(client_data['_id'])
# Verifier que la session est valide
session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(diction['session_id'])), 'valide': '1', 'partner_owner_recid': str(my_partner['recid'])})
if (session_data is None):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
tab_session = []
tab_session.append(session_data['_id'])
# Recuperation du titre de la formation
class_data = MYSY_GV.dbname['myclass'].find_one(
{'internal_url': str(session_data['class_internal_url']), 'valide': '1',
'partner_owner_recid': str(my_partner['recid']), 'locked': '0'})
tab_class = []
tab_class.append(class_data['_id'])
# Recuperation des données du stagiaire
inscription_data = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'client_rattachement_id': str(
diction['client_id'])})
tab_participant = []
for val in inscription_data:
tab_participant.append(val['_id'])
#print(" ### tab_participant 1 = ", tab_participant)
# Creation du dictionnaire d'information à utiliser pour la creation du doc
convention_dictionnary_data = {}
new_diction = {}
new_diction['token'] = diction['token']
new_diction['list_stagiaire_id'] = tab_participant
new_diction['list_session_id'] = tab_session
new_diction['list_class_id'] = tab_class
new_diction['list_client_id'] = tab_client
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
body = {
"params": convention_dictionnary_data,
}
"""
Creation du ficier PDF
"""
#print(" ### body = ", body)
contenu_doc_Template = jinja2.Template(str(template_courrier_data['contenu_doc']))
sourceHtml = contenu_doc_Template.render(params=body["params"])
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-5:]
orig_file_name = "Convention_" + str(my_partner['recid'])[0:5] + "_" + str(ts) + ".pdf"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)
# open output file for writing (truncated binary)
resultFile = open(outputFilename, "w+b")
# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
src=sourceHtml, # the HTML to convert
dest=resultFile) # file handle to receive result
# close output file
resultFile.close()
"""
25/01/2024 : pour loger une action dans la collection ==> courrier_template_tracking_history
"""
# Recuperation des données du stagiaire
inscription_data = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'client_rattachement_id': str(
diction['client_id'])})
qry = {'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'client_rattachement_id': str(
diction['client_id'])}
for inscription in inscription_data:
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(my_partner, "CONVENTION_STAGIAIRE_ENTREPRISE", str(diction['session_id']), 'inscription', str(inscription['_id']),
str(template_courrier_data['_id']))
if( local_status is False ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " WARNING : impossible d'exécuter la fonction Editic_Log_History_Action_From_courrier_template_type_document_ref_interne local_retval = ", local_retval)
return True, outputFilename
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de créer le fichier pdf de convention client "
"""
Cette fonction créer un PDF par client et retounr l'url complet du fichier pdf pour les
personnes sans rattachement client (convention indivisuelle)
"""
def Create_Convention_By_Stagiaire_PDF(diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'inscription_id']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La valeur '" + val + "' n'est pas presente dans liste ")
return False, " La valeur '" + val + "' n'est pas presente dans liste"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# 1 - Verifier que le modele de courrier est bien editable par individu
template_courrier_data = MYSY_GV.dbname['courrier_template'].find_one({'_id':ObjectId(str(diction['courrier_template_id'])),
'valide':'1',
'locked':'0',
'ref_interne': 'CONVENTION_STAGIAIRE',
'partner_owner_recid':str(my_partner['recid'])})
if (template_courrier_data is None ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + "L'identifiant du modèle de document "+str(diction['courrier_template_id'])+" est invalide")
return False, "L'identifiant du modèle de document "+str(diction['courrier_template_id'])+" est invalide "
if( "edit_by_client" in template_courrier_data.keys() and str(template_courrier_data['edit_by_client']) == "1" ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Le modèle de courrier n'est pas éditable par stagiaire. ")
return False, " Le modèle de courrier n'est pas éditable par stagiaire "
# Verifier que le statgiaire est valide
local_qry = {'_id':ObjectId(str(diction['inscription_id'])), 'status':'1',
'partner_owner_recid':str(my_partner['recid'])}
statgiaire_data = MYSY_GV.dbname['inscription'].find_one({'_id':ObjectId(str(diction['inscription_id'])), 'status':'1',
'partner_owner_recid':str(my_partner['recid'])})
if (statgiaire_data is None ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant du stagiaire est invalide ")
return False, " L'identifiant du stagiaire est invalide "
tab_stagiaire = []
tab_stagiaire.append(statgiaire_data['_id'])
"""
update du 30/01/2024
si le participant à un apprenant_id, alors on recupere la valeur de l'apprenant id. On doit travailler sur cette dernier.
En general, avant d'envoyer une convocation ou convention, l'inscription est validée et donc le dossier apprenant existe.
Du coup si tout se passe bien, dans cette fonction, on travaillera tjrs avec l'apprenant_id
"""
tab_apprenant = []
if ("apprenant_id" in statgiaire_data.keys() and statgiaire_data['apprenant_id']):
tab_apprenant.append(ObjectId(str(statgiaire_data['apprenant_id'])))
# Verifier que la session est valide
session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(diction['session_id'])), 'valide': '1', 'partner_owner_recid': str(my_partner['recid'])})
if (session_data is None):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
tab_session = []
tab_session.append(session_data['_id'])
# Recuperation du titre de la formation
class_data = MYSY_GV.dbname['myclass'].find_one(
{'internal_url': str(session_data['class_internal_url']), 'valide': '1',
'partner_owner_recid': str(my_partner['recid']), 'locked': '0'})
tab_class = []
tab_class.append(class_data['_id'])
# Creation du dictionnaire d'information à utiliser pour la creation du doc
convention_dictionnary_data = {}
new_diction = {}
new_diction['token'] = diction['token']
new_diction['list_stagiaire_id'] = tab_stagiaire
new_diction['list_session_id'] = tab_session
new_diction['list_class_id'] = tab_class
new_diction['list_client_id'] = []
new_diction['list_apprenant_id'] = tab_apprenant
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
body = {
"params": convention_dictionnary_data,
}
"""
Creation du ficier PDF
"""
contenu_doc_Template = jinja2.Template(str(template_courrier_data['contenu_doc']))
sourceHtml = contenu_doc_Template.render(params=body["params"])
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-5:]
orig_file_name = "Convention_" + str(my_partner['recid'])[0:5] + "_" + str(ts) + ".pdf"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)
# open output file for writing (truncated binary)
resultFile = open(outputFilename, "w+b")
# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
src=sourceHtml, # the HTML to convert
dest=resultFile) # file handle to receive result
# close output file
resultFile.close()
"""
25/01/2024 : pour loger une action dans la collection ==> courrier_template_tracking_history
"""
"""local_status, local_retval = module_editique.Editic_Log_History_Action(my_partner, template_courrier_data, str(diction['session_id']),
'inscription', str(diction['inscription_id']) )"""
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(
my_partner, "CONVENTION_STAGIAIRE_INDIVIDUELLE", str(diction['session_id']), 'inscription',
str(diction['inscription_id']),
str(str(template_courrier_data['_id'])))
return True, outputFilename
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de créer le fichier pdf de convention par stagiaire "
"""
Cette fonction permet de telecharger PDF toutes les conVOCAtion d'une session.
Depuis la session, l'utilisateur choisi le modele PDF et
telecharge les conventions d'entreprise et les conventions individuelles.
On créé un fichier zip qui sera téléchargé avec toutes les pièces jointes
"""
def Prepare_and_Send_Convocation_From_Session_By_PDF(diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La valeur '" + val + "' n'est pas presente dans liste ")
return False, " La valeur '" + val + "' n'est pas presente dans liste"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
# Stokage des nom de fichier à zipper
list_file_name_to_zip = []
liste_inscription = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
}
)
"""
for val in liste_inscription_no_client:
print(" ### la liste des liste_inscription_no_client = ", str(val))
"""
# Recupération des données du modèle de document
is_convention_by_client = "0"
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
if (courrier_template_data and "edit_by_client" in courrier_template_data.keys() and courrier_template_data[
'edit_by_client'] == "1"):
is_convention_by_client = "1"
if (str(is_convention_by_client) == "0"):
liste_participants = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
}
)
for val in liste_participants:
local_diction = {}
# field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'client_id']
local_diction['token'] = diction['token']
local_diction['session_id'] = diction['session_id']
local_diction['courrier_template_id'] = diction['courrier_template_id']
local_diction['inscription_id'] = str(val['_id'])
#print(" #### Traitemnt de local_diction bb = ", local_diction)
local_status, local_full_file_name = Create_Convocation_By_Stagiaire_PDF(local_diction)
if( local_status is False):
return local_status, local_full_file_name
else:
list_file_name_to_zip.append(str(local_full_file_name))
# Create a ZipFile Object
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-3:]
zip_file_name = str(MYSY_GV.TEMPORARY_DIRECTORY_V2)+"List_Convocation_session_"+str(diction['session_id'])+"_"+str(ts)+".zip"
with ZipFile(zip_file_name, 'w') as zip_object:
for pdf_files in list_file_name_to_zip :
#print(" ### fichier a zipper = ", pdf_files)
zip_object.write(str(pdf_files))
if os.path.exists(zip_file_name):
# print(" ### ok os.path.exists(outputFilename) "+str(outputFilename))
return True, send_file(zip_file_name, as_attachment=True)
return False, " Impossible de générer les conventions par pdf PDF (1) "
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 générer les conventions par pdf PDF "
"""
La meme que la précedente mais juste pour une liste d'inscrit"""
def Prepare_and_Send_Convocation_From_Session_For_Selected_Inscrit_By_PDF(diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'tab_ids']
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"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
# Stokage des nom de fichier à zipper
list_file_name_to_zip = []
my_inscription_ids = ""
if ("tab_ids" in diction.keys()):
if diction['tab_ids']:
my_inscription_ids = diction['tab_ids']
tab_my_inscription_Object_ids = []
tab_my_inscription_ids = str(my_inscription_ids).split(",")
for my_inscription_id in tab_my_inscription_ids:
tab_my_inscription_Object_ids.append(ObjectId(str(my_inscription_id)))
"""
for val in liste_inscription_no_client:
print(" ### la liste des liste_inscription_no_client = ", str(val))
"""
# Recupération des données du modèle de document
is_convention_by_client = "0"
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
if (courrier_template_data and "edit_by_client" in courrier_template_data.keys() and courrier_template_data[
'edit_by_client'] == "1"):
is_convention_by_client = "1"
if (str(is_convention_by_client) == "0"):
liste_participants = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'_id': {'$in': tab_my_inscription_Object_ids},
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
}
)
for val in liste_participants:
local_diction = {}
# field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'client_id']
local_diction['token'] = diction['token']
local_diction['session_id'] = diction['session_id']
local_diction['courrier_template_id'] = diction['courrier_template_id']
local_diction['inscription_id'] = str(val['_id'])
#print(" #### Traitemnt de local_diction bb = ", local_diction)
local_status, local_full_file_name = Create_Convocation_By_Stagiaire_PDF(local_diction)
if( local_status is False):
return local_status, local_full_file_name
else:
list_file_name_to_zip.append(str(local_full_file_name))
# Create a ZipFile Object
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-3:]
zip_file_name = str(MYSY_GV.TEMPORARY_DIRECTORY_V2)+"List_Convocation_session_"+str(diction['session_id'])+"_"+str(ts)+".zip"
with ZipFile(zip_file_name, 'w') as zip_object:
for pdf_files in list_file_name_to_zip :
#print(" ### fichier a zipper = ", pdf_files)
zip_object.write(str(pdf_files))
if os.path.exists(zip_file_name):
# print(" ### ok os.path.exists(outputFilename) "+str(outputFilename))
return True, send_file(zip_file_name, as_attachment=True)
return False, " Impossible de générer les conventions par pdf PDF (1) "
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 générer les conventions par pdf PDF "
"""
Cette fonction créer une convocation PDF par participant à une session de formation
Peu importe le rattachement client ou pas.
"""
def Create_Convocation_By_Stagiaire_PDF(diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'inscription_id']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La valeur '" + val + "' n'est pas presente dans liste ")
return False, " La valeur '" + val + "' n'est pas presente dans liste"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
qry = {'_id':ObjectId(str(diction['courrier_template_id'])),
'valide':'1',
'locked':'0',
'ref_interne': 'CONVOCATION_STAGIAIRE',
'partner_owner_recid':str(my_partner['recid'])}
#print(" ##### qry = ", qry)
# 1 - Verifier que le modele de courrier est bien editable par individu
template_courrier_data = MYSY_GV.dbname['courrier_template'].find_one({'_id':ObjectId(str(diction['courrier_template_id'])),
'valide':'1',
'locked':'0',
'ref_interne': 'CONVOCATION_STAGIAIRE',
'partner_owner_recid':str(my_partner['recid'])})
if( template_courrier_data is None ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant du modèle de courrier est invalide ")
return False, " L'identifiant du modèle de courrier est invalide "
if ("edit_by_client" in template_courrier_data.keys() and str(template_courrier_data['edit_by_client']) == "1"):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Le modèle de courrier n'est pas éditable par stagiaire. ")
return False, " Le modèle de courrier n'est pas éditable par stagiaire "
# Verifier que le statgiaire est valide
local_qry = {'_id':ObjectId(str(diction['inscription_id'])), 'status':'1',
'partner_owner_recid':str(my_partner['recid'])}
statgiaire_data = MYSY_GV.dbname['inscription'].find_one({'_id':ObjectId(str(diction['inscription_id'])), 'status':'1',
'partner_owner_recid':str(my_partner['recid'])})
if (statgiaire_data is None ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant du stagiaire est invalide ")
return False, " L'identifiant du stagiaire est invalide "
tab_stagiaire = []
tab_stagiaire.append(statgiaire_data['_id'])
"""
update du 30/01/2024
si le participant à un apprenant_id, alors on recupere la valeur de l'apprenant id. On doit travailler sur cette dernier.
En general, avant d'envoyer une convocation ou convention, l'inscription est validée et donc le dossier apprenant existe.
Du coup si tout se passe bien, dans cette fonction, on travaillera tjrs avec l'apprenant_id
"""
tab_apprenant = []
if ("apprenant_id" in statgiaire_data.keys() and statgiaire_data['apprenant_id']):
tab_apprenant.append(ObjectId(str(statgiaire_data['apprenant_id'])))
# Verifier que la session est valide
session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(diction['session_id'])), 'valide': '1', 'partner_owner_recid': str(my_partner['recid'])})
if (session_data is None):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
tab_session = []
tab_session.append(session_data['_id'])
# Recuperation du titre de la formation
class_data = MYSY_GV.dbname['myclass'].find_one(
{'internal_url': str(session_data['class_internal_url']), 'valide': '1',
'partner_owner_recid': str(my_partner['recid']), 'locked': '0'})
tab_class = []
tab_class.append(class_data['_id'])
# Recuperation des sequences d'une session de formation
tab_sequence_session = []
for local_retval in MYSY_GV.dbname['session_formation_sequence'].find({'partner_owner_recid':str(my_partner['recid']),
'session_id':str(session_data['_id']),
'valide':'1',
'locked':'0'}):
tab_sequence_session.append(local_retval['_id'])
# Creation du dictionnaire d'information à utiliser pour la creation du doc
convention_dictionnary_data = {}
new_diction = {}
new_diction['token'] = diction['token']
new_diction['list_stagiaire_id'] = tab_stagiaire
new_diction['list_session_id'] = tab_session
new_diction['list_class_id'] = tab_class
new_diction['list_client_id'] = []
new_diction['list_apprenant_id'] = tab_apprenant
new_diction['list_sequence_session_id'] = tab_sequence_session
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
body = {
"params": convention_dictionnary_data,
}
"""
Creation du ficier PDF
"""
contenu_doc_Template = jinja2.Template(str(template_courrier_data['contenu_doc']))
sourceHtml = contenu_doc_Template.render(params=body["params"])
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-5:]
orig_file_name = "Convocation_" + str(my_partner['recid'])[0:5] + "_" + str(ts) + ".pdf"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)
# open output file for writing (truncated binary)
resultFile = open(outputFilename, "w+b")
# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
src=sourceHtml, # the HTML to convert
dest=resultFile) # file handle to receive result
# close output file
resultFile.close()
"""
25/01/2024 : pour loger une action dans la collection ==> courrier_template_tracking_history
"""
#print(" str(diction['inscription_id']) == ", str(diction['inscription_id']))
""" local_status, local_retval = module_editique.Editic_Log_History_Action(my_partner, template_courrier_data,
str(diction['session_id']), 'inscription', str(diction['inscription_id']))
"""
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(
my_partner, "CONVOCATION_STAGIAIRE", str(diction['session_id']), 'inscription',
str(diction['inscription_id']),
str(str(template_courrier_data['_id'])))
return True, outputFilename
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de créer le fichier pdf de convocation par stagiaire "
"""
Cette fonction prepare et envoi les conVocation a chaque
participant à la session de formation
"""
def Prepare_and_Send_Convocation_From_Session_By_Email(tab_files, Folder, diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'email_test', 'email_production']
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"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
# Verifier qu'il ya bien des inscriptions valides dans la session pour le client
liste_participants = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
}
)
#print(" ### la liste des liste_participants = ", liste_participants)
# Sauvegarde des fichiers joints depuis le front
tab_saved_file_full_path = []
for file in tab_files:
status, saved_file_full_path = mycommon.Upload_Save_PDF_IMG_File(file, Folder)
if (status is False):
mycommon.myprint("Impossible de récupérer correctement le fichier à importer")
return False, "Impossible de récupérer correctement le fichier à importer"
tab_saved_file_full_path.append(saved_file_full_path)
#print(" #### tab_saved_file_full_path = ", tab_saved_file_full_path)
# Recupération des données du modèle de document
is_convention_by_client = "0"
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
if( courrier_template_data and "edit_by_client" in courrier_template_data.keys() and courrier_template_data['edit_by_client'] == "1"):
is_convention_by_client = "1"
if (str(is_convention_by_client) == "0"):
liste_inscription = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
}
)
#print(" ### LIST liste_inscription: ", liste_inscription)
for single_inscrit in liste_inscription :
#print(" ### convocation traitement de l'inscrit : ",single_inscrit )
#field_list_obligatoire = [ 'token', 'inscription_id', 'courrier_template_id', 'email_test', 'email_production' ]
new_diction_no_client = {}
new_diction_no_client['token'] = str(diction['token'])
new_diction_no_client['inscription_id'] = str(single_inscrit['_id'])
new_diction_no_client['courrier_template_id'] = diction['courrier_template_id']
new_diction_no_client['session_id'] = diction['session_id']
new_diction_no_client['email_test'] = diction['email_test']
new_diction_no_client['email_production'] = diction['email_production']
#print(" ##### new_diction_no_client = ", new_diction_no_client)
local_status, local_retval = Sent_Convocation_Stagiaire_By_Email(tab_saved_file_full_path, Folder, new_diction_no_client)
if (local_status is False):
mycommon.myprint(" WARNING impossible d'envoyer la convocation a l'apprenant : " + str(single_inscrit['_id']) )
# Traitement de l'eventuel fichier joint
tab_files_to_attache_to_mail = []
"""
25/01/2024 : pour loger une action dans la collection ==> courrier_template_tracking_history
"""
"""local_status, local_retval = module_editique.Editic_Log_History_Action(my_partner, courrier_template_data,
str(diction['session_id']), "inscription", str(single_inscrit['_id']))"""
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(
my_partner, "CONVOCATION_STAGIAIRE", str(diction['session_id']), 'inscription',
str(single_inscrit['_id']),
str(str(courrier_template_data['_id'])))
return True, " Les convocations ont été correctement envoyées par emails"
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 d'envoyer les conventions par email "
"""
La meme que la précedentes, a la difference qu'on envoie les convocation
pour une liste d'inscrits bien précise.
"""
def Prepare_and_Send_Convocation_From_Session_For_Selected_Inscrit_By_Email(tab_files, Folder, diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'email_test', 'email_production',
'tab_ids']
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"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
my_inscription_ids = ""
if ("tab_ids" in diction.keys()):
if diction['tab_ids']:
my_inscription_ids = diction['tab_ids']
tab_my_inscription_Object_ids = []
tab_my_inscription_ids = str(my_inscription_ids).split(",")
for my_inscription_id in tab_my_inscription_ids:
tab_my_inscription_Object_ids.append(ObjectId(str(my_inscription_id)))
# Verifier qu'il ya bien des inscriptions valides dans la session pour le client
liste_participants = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'_id': {'$in': tab_my_inscription_Object_ids},
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
}
)
#print(" ### la liste des liste_participants = ", liste_participants)
# Sauvegarde des fichiers joints depuis le front
tab_saved_file_full_path = []
for file in tab_files:
status, saved_file_full_path = mycommon.Upload_Save_PDF_IMG_File(file, Folder)
if (status is False):
mycommon.myprint("Impossible de récupérer correctement le fichier à importer")
return False, "Impossible de récupérer correctement le fichier à importer"
tab_saved_file_full_path.append(saved_file_full_path)
#print(" #### tab_saved_file_full_path = ", tab_saved_file_full_path)
# Recupération des données du modèle de document
is_convention_by_client = "0"
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
if( courrier_template_data and "edit_by_client" in courrier_template_data.keys() and courrier_template_data['edit_by_client'] == "1"):
is_convention_by_client = "1"
if (str(is_convention_by_client) == "0"):
liste_inscription = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'_id': {'$in': tab_my_inscription_Object_ids},
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
}
)
#print(" ### LIST liste_inscription: ", liste_inscription)
for single_inscrit in liste_inscription :
#print(" ### convocation traitement de l'inscrit : ",single_inscrit )
#field_list_obligatoire = [ 'token', 'inscription_id', 'courrier_template_id', 'email_test', 'email_production' ]
new_diction_no_client = {}
new_diction_no_client['token'] = str(diction['token'])
new_diction_no_client['inscription_id'] = str(single_inscrit['_id'])
new_diction_no_client['courrier_template_id'] = diction['courrier_template_id']
new_diction_no_client['session_id'] = diction['session_id']
new_diction_no_client['email_test'] = diction['email_test']
new_diction_no_client['email_production'] = diction['email_production']
#print(" ##### new_diction_no_client = ", new_diction_no_client)
local_status, local_retval = Sent_Convocation_Stagiaire_By_Email(tab_saved_file_full_path, Folder, new_diction_no_client)
if (local_status is False):
mycommon.myprint(" WARNING impossible d'envoyer la convocation a l'apprenant : " + str(single_inscrit['_id']) )
# Traitement de l'eventuel fichier joint
tab_files_to_attache_to_mail = []
"""
25/01/2024 : pour loger une action dans la collection ==> courrier_template_tracking_history
"""
"""local_status, local_retval = module_editique.Editic_Log_History_Action(my_partner, courrier_template_data,
str(diction['session_id']), "inscription", str(single_inscrit['_id']))"""
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(
my_partner, "CONVOCATION_STAGIAIRE", str(diction['session_id']), 'inscription',
str(single_inscrit['_id']),
str(str(courrier_template_data['_id'])))
return True, " Les convocations ont été correctement envoyées par emails"
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 d'envoyer les conventions par email "
"""
Envoi d'une convocation pour un participant donné par email
Si le participants est rattaché à un client , alors on va mettre en copie de
l'email les contacts de communication du client de rattachement
"""
def Sent_Convocation_Stagiaire_By_Email(tab_files, Folder, diction):
try:
field_list_obligatoire = ['token', 'inscription_id', 'courrier_template_id', 'email_test', 'email_production']
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"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# Verifier que le stagiaire est bien inscrit. Le statut de l'inscription doit etre "1"
is_inscription_valide = MYSY_GV.dbname['inscription'].count_documents(
{'_id': ObjectId(str(diction['inscription_id'])),
'status': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_inscription_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de l'inscription est invalide ")
return False, " L'identifiant de l'inscription est invalide "
# Traitement de l'eventuel fichier joint
tab_files_to_attache_to_mail = []
for saved_file in tab_files:
"""
status, saved_file = mycommon.Upload_Save_PDF_IMG_File(file, Folder)
if (status is False):
mycommon.myprint("Impossible de récupérer correctement le fichier à importer")
return False, "Impossible de récupérer correctement le fichier à importer"
"""
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(saved_file, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(os.path.basename(saved_file)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
# Verification de la validité des adresses email_recu
"""
/!\ : Si l'email de test est repli, alors on considere que c'est un test, on ne prend pas en compte l'email de email_production.
Ceci pour forcer les utilisateur à ne remplir que l'email de prod s'il veulent l'envoyer en prod.
Si l'adresse email_prodution = "defaul", cela veut dire qu'on envoie la convention à :
- l'adresse email du stagiaire et ses tuteurs (si les tuteurs on cochés la case 'inclu com'
"""
send_in_production = 0
tab_emails_destinataire = []
if ("email_test" in diction.keys() and diction['email_test']):
send_in_production = 0
tab_email_test = str(diction['email_test']).replace(";", ",").split(",")
for email in tab_email_test:
email = email.strip()
if (mycommon.isEmailValide(email) is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'adresse email " + str(email) + " est invalide ")
return False, " L'adresse email " + str(email) + " est invalide "
tab_emails_destinataire = tab_email_test
elif ("email_production" in diction.keys() and diction['email_production']):
send_in_production = 1
if (str(diction['email_production']) != "default"):
tab_email_prod = str(diction['email_production']).replace(";", ",").split(",")
for email in tab_email_prod:
email = email.strip()
if (mycommon.isEmailValide(str(email)) is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'adresse email '" + str(email) + "' est invalide ")
return False, " L'adresse email " + str(email) + " est invalide "
tab_emails_destinataire = tab_email_prod
else:
send_in_production = 1
# On va chercher les adresse email de communication du
local_dict = {'token': str(diction['token']), '_id': str(diction['inscription_id'])}
local_status, tab_apprenant_contact = Inscription_mgt.Get_Statgiaire_Communication_Contact(local_dict)
if (local_status is False):
return local_status, tab_apprenant_contact
tmp_tab = []
# print(" ### tab_apprenant_contact = ", tab_apprenant_contact)
for tmp in tab_apprenant_contact:
if ("email" in tmp.keys()):
tab_emails_destinataire.append((tmp['email']))
if (len(tab_emails_destinataire) <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune adresse email n'a été fourni. ")
return False, " Aucune adresse email n'a été fourni. "
# print(" ### tab_emails_destinataire = ", tab_emails_destinataire)
# Verifier que le 'courrier_template_id' est valide
# Ici le template doit etre un email
is_courrier_template_id_valide = MYSY_GV.dbname['courrier_template'].count_documents(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'type_doc': 'email',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
if (is_courrier_template_id_valide != 1):
mycommon.myprint(str(inspect.stack()[0][3]) + " L'identifiant du modèle de courrier est invalide ")
return False, " L'identifiant du modèle de courrier est invalide "
# Recupération des données du modèle de document
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
# Recuperation des eventuelles pièces jointes du modèle que courrier
local_dic = {}
local_dic['token'] = str(diction['token'])
local_dic['object_owner_collection'] = "courrier_template"
local_dic['object_owner_id'] = str(courrier_template_data['_id'])
local_status, local_retval = attached_file_mgt.Get_List_object_owner_collection_Stored_Files(local_dic)
if (local_status is False):
return local_status, local_retval
# print(" ### file stocké = ", local_retval)
# Recuperation des fichiers attachés au modele de courrier, s'il y en a
for file in local_retval:
local_JSON = ast.literal_eval(file)
saved_file = local_JSON['full_path']
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(saved_file, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(os.path.basename(saved_file)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
# Recuperation des données du stagaire
inscription_data = MYSY_GV.dbname['inscription'].find_one({'_id': ObjectId(str(diction['inscription_id'])),
'status': '1',
'partner_owner_recid': str(my_partner['recid'])})
tab_apprenant_client_rattachement_contact = ""
# Verifier si le modele de courrier n'est par 'edit_by_client', au quel cas on verifie que l'appressant est bien lié à un client
if ("edit_by_client" in courrier_template_data.keys() and str(courrier_template_data['edit_by_client']) == "0"):
stagiaire_client_id = ""
if ("client_rattachement_id" in inscription_data.keys() and inscription_data['client_rattachement_id']):
stagiaire_client_id = str(inscription_data['client_rattachement_id'])
local_diction = {"token":str(diction['token']), "_id":stagiaire_client_id }
#print(" ##### local_diction pr Get_Partner_Client_Communication_Contact= ", local_diction)
local_status, partner_client_contact_communication = partner_client.Get_Partner_Client_Communication_Contact(local_diction)
if (local_status is True):
#print(" ### partner_client_contact_communication = ", partner_client_contact_communication)
tab_local_email_production = []
for tmp in partner_client_contact_communication:
tmp_JSON = ast.literal_eval(tmp)
if ("email" in tmp_JSON.keys()):
tab_local_email_production.append(str(tmp_JSON["email"]))
tab_apprenant_client_rattachement_contact = ",".join(tab_local_email_production)
tab_participant = []
tab_participant.append(inscription_data['_id'])
"""
update du 30/01/2024
si le participant à un apprenant_id, alors on recupere la valeur de l'apprenant id. On doit travailler sur cette dernier.
En general, avant d'envoyer une convocation ou convention, l'inscription est validée et donc le dossier apprenant existe.
Du coup si tout se passe bien, dans cette fonction, on travaillera tjrs avec l'apprenant_id
"""
tab_apprenant = []
if( "apprenant_id" in inscription_data.keys() and inscription_data['apprenant_id']) :
tab_apprenant.append(ObjectId(str(inscription_data['apprenant_id'])))
# Recuperations des info de la session de formation
session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(inscription_data['session_id'])), 'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
tab_session = []
tab_session.append(session_data['_id'])
# Recuperation du titre de la formation
class_data = MYSY_GV.dbname['myclass'].find_one(
{'internal_url': str(session_data['class_internal_url']), 'valide': '1',
'partner_owner_recid': str(my_partner['recid']), 'locked': '0'})
tab_class = []
tab_class.append(class_data['_id'])
# Creation du dictionnaire d'information à utiliser pour la creation du doc
convention_dictionnary_data = {}
new_diction = {}
new_diction['token'] = diction['token']
new_diction['list_stagiaire_id'] = tab_participant
new_diction['list_session_id'] = tab_session
new_diction['list_class_id'] = tab_class
new_diction['list_client_id'] = []
new_diction['list_apprenant_id'] = tab_apprenant
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
body = {
"params": convention_dictionnary_data,
}
orig_file_name = None
outputFilename = None
# Verifier s'il s'agit d'un document à envoyer avec une version de pièce jointe.
if ("joint_pdf" in courrier_template_data.keys() and str(courrier_template_data['joint_pdf']) == "1"):
# Il s'agit bien d'un envoie avec 'contenu_doc' en pièce jointe PDF
"""
1 - Creation du PDF
"""
contenu_doc_Template = jinja2.Template(str(courrier_template_data['contenu_doc']))
sourceHtml = contenu_doc_Template.render(params=body["params"])
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-5:]
orig_file_name = "Convocation_" + str(my_partner['recid'])[0:5] + "_" + str(ts) + ".pdf"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)
# open output file for writing (truncated binary)
resultFile = open(outputFilename, "w+b")
# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
src=sourceHtml, # the HTML to convert
dest=resultFile) # file handle to receive result
# close output file
resultFile.close()
# Attachement du fichier joint
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(outputFilename, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(os.path.basename(outputFilename)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
## Creation du mail au format email
corps_mail_Template = jinja2.Template(str(courrier_template_data['corps_mail']))
sourceHtml = corps_mail_Template.render(params=body["params"])
html_mime = MIMEText(sourceHtml, 'html')
# Creation de l'email à enoyer
msg = MIMEMultipart("alternative")
else:
# Il s'agit d'une simple email
## Creation du mail au format email
contenu_doc_Template = jinja2.Template(str(courrier_template_data['contenu_doc']))
sourceHtml = contenu_doc_Template.render(params=body["params"])
html_mime = MIMEText(sourceHtml, 'html')
# Creation de l'email à enoyer
msg = MIMEMultipart("alternative")
"""
Recuperation des parametre SMTP du partner si le client a decidé d'utiliser son propre smpt
"""
partner_own_smtp_value = "0"
partner_own_smtp = MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'partner_smtp',
'valide': '1',
'locked': '0'})
if (partner_own_smtp and "config_value" in partner_own_smtp.keys()):
partner_own_smtp_value = partner_own_smtp['config_value']
if (str(partner_own_smtp_value) == "1"):
partner_SMTP_COUNT_password = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_user_pwd',
'valide': '1',
'locked': '0'}, {'config_value': 1})['config_value'])
partner_SMTP_COUNT_smtpsrv = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_server',
'valide': '1',
'locked': '0'}, {'config_value': 1})['config_value'])
partner_SMTP_COUNT_user = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_user',
'valide': '1',
'locked': '0'}, {'config_value': 1})['config_value'])
partner_SMTP_COUNT_From_User = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_count_from_name',
'valide': '1',
'locked': '0'}, {'config_value': 1})['config_value'])
partner_SMTP_COUNT_port = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_count_port',
'valide': '1',
'locked': '0'}, {'config_value': 1})['config_value'])
if (str(partner_own_smtp_value) == "1"):
smtpserver = smtplib.SMTP(partner_SMTP_COUNT_smtpsrv, partner_SMTP_COUNT_port)
else:
smtpserver = smtplib.SMTP(MYSY_GV.O365_SMTP_COUNT_smtpsrv, MYSY_GV.O365_SMTP_COUNT_port)
if (str(partner_own_smtp_value) == "1"):
msg.attach(html_mime)
msg['From'] = partner_SMTP_COUNT_From_User
msg['Cc'] = tab_apprenant_client_rattachement_contact
msg['Bcc'] = 'contact@mysy-training.com'
msg['Subject'] = courrier_template_data['sujet']
# msg['to'] = "billardman01@hotmail.com"
toaddrs = ",".join(tab_emails_destinataire)
msg['to'] = str(toaddrs)
# Attacher l'eventuelle pièces jointes
for myfile in tab_files_to_attache_to_mail:
msg.attach(myfile['attached_file'])
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.login(partner_SMTP_COUNT_user, partner_SMTP_COUNT_password)
else:
msg.attach(html_mime)
msg['From'] = MYSY_GV.O365_SMTP_COUNT_From_User
msg['Cc'] = tab_apprenant_client_rattachement_contact
msg['Bcc'] = 'contact@mysy-training.com'
msg['Subject'] = courrier_template_data['sujet']
# msg['to'] = "billardman01@hotmail.com"
toaddrs = ",".join(tab_emails_destinataire)
msg['to'] = str(toaddrs)
for myfile in tab_files_to_attache_to_mail:
msg.attach(myfile['attached_file'])
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.login(MYSY_GV.O365_SMTP_COUNT_user, MYSY_GV.O365_SMTP_COUNT_password)
val = smtpserver.send_message(msg)
smtpserver.close()
print(" Email envoyé 66" + str(val))
"""
# Ajout de l'evenement dans l'historique
"""
# L'action n'est loggué pour les envois reels (en prod)
if (send_in_production == 1):
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = diction['token']
history_event_dict['related_collection'] = "inscription"
history_event_dict['related_collection_recid'] = str(diction['inscription_id'])
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Convocation envoyée par email à la liste : " + str(
tab_emails_destinataire)
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
"""
Après avoir loggé l'envoie reelle en production, on va aller stocker le document dans la collection : download_files
si et seulement si on bien un fichier PDF (voir variables : orig_file_name et outputFilename)
"""
if( orig_file_name and outputFilename ):
new_file = {}
new_file['token'] = diction['token']
type_document = "Convocation"
new_file['file_business_object'] = str(orig_file_name)
new_file['file_name'] = str(orig_file_name)
new_file['status'] = "1"
new_file['type_document'] = str(type_document)
new_file['object_owner_collection'] = "partner_client"
new_file['object_owner_id'] = str(inscription_data['client_rattachement_id'])
new_file['file_name_to_store'] = outputFilename
# print(" ### new_file new_file = ", new_file)
local_status, local_retval = attached_file_mgt.Internal_Usage_Store_User_Downloaded_File(
MYSY_GV.upload_folder, new_file)
if (local_status is False):
print(" ## WARINNGGG Impossible de stocker le fichier de Convocation ")
return True, "L'email a été correctement envoyé "
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 d'envoyer la convention par email "
"""
Cette fonction prepare et envoi les attestation de formation a chaque
participant à la session de formation
"""
def Prepare_and_Send_Attestation_From_Session_By_Email(tab_files, Folder, diction):
try:
field_list_obligatoire = ['token', 'session_id', 'email_test', 'email_production', 'tab_inscriptions_ids']
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"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
tab_inscriptions_ids = ""
if ("tab_inscriptions_ids" in diction.keys()):
if diction['tab_inscriptions_ids']:
tab_inscriptions_ids = diction['tab_inscriptions_ids']
tab_inscriptions_ids_splited = str(tab_inscriptions_ids).split(",")
tab_inscriptions_ids_splited_obj = []
for tmp in tab_inscriptions_ids_splited :
tab_inscriptions_ids_splited_obj.append(ObjectId(str(tmp)))
is_warning_message = "0"
warning_message = "Les attestation ont été correctement envoyées par emails avec l'attention suivante : "
for attestation_formation_data in MYSY_GV.dbname['attestation_formation'].find({"session_id":str(diction['session_id']),
'partner_owner_recid':str(my_partner['recid']),
'valide':"1",
"locked":'0',
'_id': { '$in': tab_inscriptions_ids_splited_obj} }):
inscrit_email = ""
if( attestation_formation_data and "inscription_id" in attestation_formation_data.keys() and attestation_formation_data['inscription_id']):
inscrit_data = MYSY_GV.dbname['inscription'].find_one({'partner_owner_recid':str(my_partner['recid']),
'_id':ObjectId(str(attestation_formation_data['inscription_id']))})
if( inscrit_data and 'email' in inscrit_data.keys() ):
inscrit_email = inscrit_data['email']
# Recupération des données du modèle de document
is_convention_by_client = "0"
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'_id': ObjectId(str(attestation_formation_data['courrier_template_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
if( courrier_template_data and "edit_by_client" in courrier_template_data.keys() and courrier_template_data['edit_by_client'] == "1"):
is_convention_by_client = "1"
#field_list_obligatoire = [ 'token', 'inscription_id', 'courrier_template_id', 'email_test', 'email_production' ]
new_diction_no_client = {}
new_diction_no_client['token'] = str(diction['token'])
new_diction_no_client['inscription_id'] = str(attestation_formation_data['inscription_id'])
new_diction_no_client['courrier_template_id'] = attestation_formation_data['courrier_template_id']
new_diction_no_client['session_id'] = diction['session_id']
new_diction_no_client['email_test'] = diction['email_test']
new_diction_no_client['email_production'] = diction['email_production']
#print(" ##### new_diction_no_client = ", new_diction_no_client)
tab_saved_file_full_path = []
local_status, local_retval = Sent_Attestation_Stagiaire_By_Email(tab_saved_file_full_path, Folder, new_diction_no_client)
if (local_status is False):
mycommon.myprint(" WARNING impossible d'envoyer l'attestation de formation a l'apprenant : " + str(attestation_formation_data['inscription_id']) )
is_warning_message = "1"
warning_message = str(warning_message)+" -- "+str(" WARNING impossible d'envoyer l'attestation de formation a l'apprenant : " + str(inscrit_email) )
else:
# Traitement de l'eventuel fichier joint
tab_files_to_attache_to_mail = []
"""
25/01/2024 : pour loger une action dans la collection ==> courrier_template_tracking_history
"""
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(
my_partner, "ATTESTATION_FORMATION", str(diction['session_id']), 'inscription',
str(attestation_formation_data['inscription_id']),
str(attestation_formation_data['courrier_template_id']))
# Mettre à jour avec la date d'envoi de l'attestation
updata_data = {}
updata_data['date_update'] = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
updata_data['update_by'] = str(my_partner['recid'])
updata_data['statut'] = "1"
updata_data['date_envoie'] = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
MYSY_GV.dbname['attestation_formation'].find_one_and_update({'_id':ObjectId(str(attestation_formation_data['_id'])),
'partner_owner_recid':str(my_partner['recid'])},
{'$set':updata_data})
if( is_warning_message == "1"):
return True, str(warning_message)
return True, " Les attestations ont été correctement envoyées par emails"
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 d'envoyer les conventions par email "
"""
Envoi d'une attestation pour un participant donné par email
Si le participants est rattaché à un client , alors on va mettre en copie de
l'email les contacts de communication du client de rattachement
"""
def Sent_Attestation_Stagiaire_By_Email(tab_files, Folder, diction):
try:
field_list_obligatoire = ['token', 'inscription_id', 'courrier_template_id', 'email_test', 'email_production']
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"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# Verifier que le stagiaire est bien inscrit. Le statut de l'inscription doit etre "1"
is_inscription_valide = MYSY_GV.dbname['inscription'].count_documents(
{'_id': ObjectId(str(diction['inscription_id'])),
'status': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_inscription_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de l'inscription est invalide ")
return False, " L'identifiant de l'inscription est invalide "
# Traitement de l'eventuel fichier joint
tab_files_to_attache_to_mail = []
for saved_file in tab_files:
"""
status, saved_file = mycommon.Upload_Save_PDF_IMG_File(file, Folder)
if (status is False):
mycommon.myprint("Impossible de récupérer correctement le fichier à importer")
return False, "Impossible de récupérer correctement le fichier à importer"
"""
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(saved_file, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(os.path.basename(saved_file)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
# Verification de la validité des adresses email_recu
"""
/!\ : Si l'email de test est repli, alors on considere que c'est un test, on ne prend pas en compte l'email de email_production.
Ceci pour forcer les utilisateur à ne remplir que l'email de prod s'il veulent l'envoyer en prod.
Si l'adresse email_prodution = "defaul", cela veut dire qu'on envoie la convention à :
- l'adresse email du stagiaire et ses tuteurs (si les tuteurs on cochés la case 'inclu com'
"""
send_in_production = 0
tab_emails_destinataire = []
if ("email_test" in diction.keys() and diction['email_test']):
send_in_production = 0
tab_email_test = str(diction['email_test']).replace(";", ",").split(",")
for email in tab_email_test:
email = email.strip()
if (mycommon.isEmailValide(email) is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'adresse email " + str(email) + " est invalide ")
return False, " L'adresse email " + str(email) + " est invalide "
tab_emails_destinataire = tab_email_test
elif ("email_production" in diction.keys() and diction['email_production']):
send_in_production = 1
if (str(diction['email_production']) != "default"):
tab_email_prod = str(diction['email_production']).replace(";", ",").split(",")
for email in tab_email_prod:
email = email.strip()
if (mycommon.isEmailValide(str(email)) is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'adresse email '" + str(email) + "' est invalide ")
return False, " L'adresse email " + str(email) + " est invalide "
tab_emails_destinataire = tab_email_prod
else:
send_in_production = 1
# On va chercher les adresse email de communication du
local_dict = {'token': str(diction['token']), '_id': str(diction['inscription_id'])}
local_status, tab_apprenant_contact = Inscription_mgt.Get_Statgiaire_Communication_Contact(local_dict)
if (local_status is False):
return local_status, tab_apprenant_contact
tmp_tab = []
# print(" ### tab_apprenant_contact = ", tab_apprenant_contact)
for tmp in tab_apprenant_contact:
if ("email" in tmp.keys()):
tab_emails_destinataire.append((tmp['email']))
if (len(tab_emails_destinataire) <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune adresse email n'a été fourni. ")
return False, " Aucune adresse email n'a été fourni. "
# print(" ### tab_emails_destinataire = ", tab_emails_destinataire)
# Verifier que le 'courrier_template_id' est valide
# Ici le template doit etre un email
is_courrier_template_id_valide = MYSY_GV.dbname['courrier_template'].count_documents(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'type_doc': 'email',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
if (is_courrier_template_id_valide != 1):
mycommon.myprint(str(inspect.stack()[0][3]) + " L'identifiant du modèle de courrier est invalide ")
return False, " L'identifiant du modèle de courrier est invalide "
# Recupération des données du modèle de document
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
# Recuperation des eventuelles pièces jointes du modèle que courrier
local_dic = {}
local_dic['token'] = str(diction['token'])
local_dic['object_owner_collection'] = "courrier_template"
local_dic['object_owner_id'] = str(courrier_template_data['_id'])
local_status, local_retval = attached_file_mgt.Get_List_object_owner_collection_Stored_Files(local_dic)
if (local_status is False):
return local_status, local_retval
# print(" ### file stocké = ", local_retval)
# Recuperation des fichiers attachés au modele de courrier, s'il y en a
for file in local_retval:
local_JSON = ast.literal_eval(file)
saved_file = local_JSON['full_path']
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(saved_file, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(os.path.basename(saved_file)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
# Recuperation des données du stagaire
inscription_data = MYSY_GV.dbname['inscription'].find_one({'_id': ObjectId(str(diction['inscription_id'])),
'status': '1',
'partner_owner_recid': str(my_partner['recid'])})
tab_apprenant_client_rattachement_contact = ""
# Verifier si le modele de courrier n'est par 'edit_by_client', au quel cas on verifie que l'appressant est bien lié à un client
if ("edit_by_client" in courrier_template_data.keys() and str(courrier_template_data['edit_by_client']) == "0"):
stagiaire_client_id = ""
if ("client_rattachement_id" in inscription_data.keys() and inscription_data['client_rattachement_id']):
stagiaire_client_id = str(inscription_data['client_rattachement_id'])
local_diction = {"token":str(diction['token']), "_id":stagiaire_client_id }
print(" ##### local_diction pr Get_Partner_Client_Communication_Contact= ", local_diction)
local_status, partner_client_contact_communication = partner_client.Get_Partner_Client_Communication_Contact(local_diction)
if (local_status is True):
print(" ### partner_client_contact_communication = ", partner_client_contact_communication)
tab_local_email_production = []
for tmp in partner_client_contact_communication:
tmp_JSON = ast.literal_eval(tmp)
if ("email" in tmp_JSON.keys()):
tab_local_email_production.append(str(tmp_JSON["email"]))
tab_apprenant_client_rattachement_contact = ",".join(tab_local_email_production)
tab_participant = []
tab_participant.append(inscription_data['_id'])
"""
update du 30/01/2024
si le participant à un apprenant_id, alors on recupere la valeur de l'apprenant id. On doit travailler sur cette dernier.
En general, avant d'envoyer une convocation ou convention, l'inscription est validée et donc le dossier apprenant existe.
Du coup si tout se passe bien, dans cette fonction, on travaillera tjrs avec l'apprenant_id
"""
tab_apprenant = []
if( "apprenant_id" in inscription_data.keys() and inscription_data['apprenant_id']) :
tab_apprenant.append(ObjectId(str(inscription_data['apprenant_id'])))
# Recuperations des info de la session de formation
session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(inscription_data['session_id'])), 'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
tab_session = []
tab_session.append(session_data['_id'])
# Recuperation du titre de la formation
class_data = MYSY_GV.dbname['myclass'].find_one(
{'internal_url': str(session_data['class_internal_url']), 'valide': '1',
'partner_owner_recid': str(my_partner['recid']), 'locked': '0'})
tab_class = []
tab_class.append(class_data['_id'])
# Creation du dictionnaire d'information à utiliser pour la creation du doc
convention_dictionnary_data = {}
new_diction = {}
new_diction['token'] = diction['token']
new_diction['list_stagiaire_id'] = tab_participant
new_diction['list_session_id'] = tab_session
new_diction['list_class_id'] = tab_class
new_diction['list_client_id'] = []
new_diction['list_apprenant_id'] = tab_apprenant
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
body = {
"params": convention_dictionnary_data,
}
orig_file_name = None
outputFilename = None
# Verifier s'il s'agit d'un document à envoyer avec une version de pièce jointe.
if ("joint_pdf" in courrier_template_data.keys() and str(courrier_template_data['joint_pdf']) == "1"):
# Il s'agit bien d'un envoie avec 'contenu_doc' en pièce jointe PDF
"""
1 - Creation du PDF
"""
contenu_doc_Template = jinja2.Template(str(courrier_template_data['contenu_doc']))
sourceHtml = contenu_doc_Template.render(params=body["params"])
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-5:]
orig_file_name = "Attestation_" + str(my_partner['recid'])[0:5] + "_" + str(ts) + ".pdf"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)
# open output file for writing (truncated binary)
resultFile = open(outputFilename, "w+b")
# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
src=sourceHtml, # the HTML to convert
dest=resultFile) # file handle to receive result
# close output file
resultFile.close()
# Attachement du fichier joint
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(outputFilename, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(os.path.basename(outputFilename)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
## Creation du mail au format email
corps_mail_Template = jinja2.Template(str(courrier_template_data['corps_mail']))
sourceHtml = corps_mail_Template.render(params=body["params"])
html_mime = MIMEText(sourceHtml, 'html')
# Creation de l'email à enoyer
msg = MIMEMultipart("alternative")
else:
# Il s'agit d'une simple email
## Creation du mail au format email
contenu_doc_Template = jinja2.Template(str(courrier_template_data['contenu_doc']))
sourceHtml = contenu_doc_Template.render(params=body["params"])
html_mime = MIMEText(sourceHtml, 'html')
# Creation de l'email à enoyer
msg = MIMEMultipart("alternative")
"""
Recuperation des parametre SMTP du partner si le client a decidé d'utiliser son propre smpt
"""
partner_own_smtp_value = "0"
partner_own_smtp = MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'partner_smtp',
'valide': '1',
'locked': '0'})
if (partner_own_smtp and "config_value" in partner_own_smtp.keys()):
partner_own_smtp_value = partner_own_smtp['config_value']
if (str(partner_own_smtp_value) == "1"):
partner_SMTP_COUNT_password = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_user_pwd',
'valide': '1',
'locked': '0'}, {'config_value': 1})['config_value'])
partner_SMTP_COUNT_smtpsrv = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_server',
'valide': '1',
'locked': '0'}, {'config_value': 1})['config_value'])
partner_SMTP_COUNT_user = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_user',
'valide': '1',
'locked': '0'}, {'config_value': 1})['config_value'])
partner_SMTP_COUNT_From_User = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_count_from_name',
'valide': '1',
'locked': '0'}, {'config_value': 1})['config_value'])
partner_SMTP_COUNT_port = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_count_port',
'valide': '1',
'locked': '0'}, {'config_value': 1})['config_value'])
if (str(partner_own_smtp_value) == "1"):
smtpserver = smtplib.SMTP(partner_SMTP_COUNT_smtpsrv, partner_SMTP_COUNT_port)
else:
smtpserver = smtplib.SMTP(MYSY_GV.O365_SMTP_COUNT_smtpsrv, MYSY_GV.O365_SMTP_COUNT_port)
if (str(partner_own_smtp_value) == "1"):
msg.attach(html_mime)
msg['From'] = partner_SMTP_COUNT_From_User
msg['Cc'] = tab_apprenant_client_rattachement_contact
msg['Bcc'] = 'contact@mysy-training.com'
msg['Subject'] = courrier_template_data['sujet']
# msg['to'] = "billardman01@hotmail.com"
toaddrs = ",".join(tab_emails_destinataire)
msg['to'] = str(toaddrs)
# Attacher l'eventuelle pièces jointes
for myfile in tab_files_to_attache_to_mail:
msg.attach(myfile['attached_file'])
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.login(partner_SMTP_COUNT_user, partner_SMTP_COUNT_password)
else:
msg.attach(html_mime)
msg['From'] = MYSY_GV.O365_SMTP_COUNT_From_User
msg['Cc'] = tab_apprenant_client_rattachement_contact
msg['Bcc'] = 'contact@mysy-training.com'
msg['Subject'] = courrier_template_data['sujet']
# msg['to'] = "billardman01@hotmail.com"
toaddrs = ",".join(tab_emails_destinataire)
msg['to'] = str(toaddrs)
for myfile in tab_files_to_attache_to_mail:
msg.attach(myfile['attached_file'])
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.login(MYSY_GV.O365_SMTP_COUNT_user, MYSY_GV.O365_SMTP_COUNT_password)
val = smtpserver.send_message(msg)
smtpserver.close()
print(" Email envoyé " + str(val))
"""
# Ajout de l'evenement dans l'historique
"""
# L'action n'est loggué pour les envois reels (en prod)
if (send_in_production == 1):
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = diction['token']
history_event_dict['related_collection'] = "inscription"
history_event_dict['related_collection_recid'] = str(diction['inscription_id'])
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Attestation de formation envoyée par email à la liste : " + str(
tab_emails_destinataire)
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
"""
Après avoir loggé l'envoie reelle en production, on va aller stocker le document dans la collection : download_files
si et seulement si on bien un fichier PDF (voir variables : orig_file_name et outputFilename)
"""
print(" ### orig_file_name = ", orig_file_name)
print(" ### outputFilename = ", outputFilename)
if (orig_file_name and outputFilename):
new_file = {}
new_file['token'] = diction['token']
type_document = "Attestation"
new_file['file_business_object'] = str(orig_file_name)
new_file['file_name'] = str(orig_file_name)
new_file['status'] = "1"
new_file['type_document'] = str(type_document)
new_file['object_owner_collection'] = "partner_client"
new_file['object_owner_id'] = str(inscription_data['client_rattachement_id'])
new_file['file_name_to_store'] = outputFilename
# print(" ### new_file new_file = ", new_file)
local_status, local_retval = attached_file_mgt.Internal_Usage_Store_User_Downloaded_File(
MYSY_GV.upload_folder, new_file)
if (local_status is False):
print(" ## WARNINGGG Impossible de stocker le fichier d'attestation")
return True, "L'email a été correctement envoyé "
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 d'envoyer l'attestation de formation par email "
"""
Cette fonction permet de facturer une session de formation selon les regles suivants :
Sur une session :
- les participants groupés par client_rattachement_id
- facturation du client si j'ai un client rattachement id
- Cas particulier :
- un participant qui est en autonome (donc pas de client )
- pour le facturer il faudra obligatoirement créer une client.
/!\ : On ajoute un champ 'invoiced' à chaque ligne.
ainsi si une lignes est déjà invoiced, alors on ne la refacture pas.
/!\ : Pour les inscrit sans client_rattachement_id, voici comment on procede :
1 - on verifier s'il y a un client avec la meme adresse email, si oui on recupere l'id du client
qu'on vient mettre sur l'inscription.
2 - si aucun client avec cette adresse email, on va créer un client de type 'particulier' et
on vient mettre à jour inscription.
Infiné, apres la facturation, toutes les lignes d'inscription on bel et bien un 'client_rattachement_id'
17/05/2024 : /!\
Maintenant on facture à partir du champs "facture_client_rattachement_id" et non
"client_rattachement_id" qui lui est concerné par les convention et autre documents
administratifs
"""
def Prepare_and_Send_Facture_From_Session_By_Email(tab_files, Folder, diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'email_test', 'email_production']
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", False
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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, False
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide ", False
"""
Gestion des inscriptions n'ayant pas de client ID
"""
liste_inscription_no_client = MYSY_GV.dbname['inscription'].find(
{"$or": [{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
"facture_client_rattachement_id": '',
"invoiced": {'$ne': '1'}
},
{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'facture_client_rattachement_id': {'$exists': False},
"invoiced": {'$ne': '1'}
}]
}
)
# CONTROLE : Verification des data client (si tous les clients 'particuliers' sont ok
for local_inscription_no_client in liste_inscription_no_client:
print(" ### List des inscrit n'ayant pas de 'client_id': ", local_inscription_no_client)
"""
- Verifier s'il y a un client avec la même adresse email,
si non, créer le client
"""
is_inscription_no_client_exist = MYSY_GV.dbname['partner_client'].count_documents(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email'])})
# S'il ya plusieurs clients avec la meme adresse email, alors il y a un bin's
if (is_inscription_no_client_exist > 1):
mycommon.myprint(" Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à plusieurs clients")
return False, " Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à plusieurs clients ", False
# Si le client existe, verifier qu'il est valide et pas locké
if (is_inscription_no_client_exist == 1):
is_inscription_no_client_valide_no_locked = MYSY_GV.dbname['partner_client'].count_documents(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email']),
'valide': "1",
'locked': '0'})
if (is_inscription_no_client_valide_no_locked == 0):
mycommon.myprint(" Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à un client non valide")
return False, " Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à un client non valide ", False
# Mise à jour de l'inscription avec l'_id du client
inscription_no_client_valide_no_locked_data = MYSY_GV.dbname['partner_client'].find_one(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email']),
'valide': "1",
'locked': '0'})
MYSY_GV.dbname['inscription'].update_one({'partner_owner_recid': str(my_partner['recid']),
'_id': ObjectId(local_inscription_no_client['_id'])},
{'$set': {'facture_client_rattachement_id': str(
inscription_no_client_valide_no_locked_data['_id'])}})
# Si il n'y a pas de client associé à cette adresse email, alors on crée le client
if (is_inscription_no_client_exist == 0):
new_client_contact_data = {}
new_client_data = {}
new_partner_all_list = ['token', "raison_sociale", "nom", "siret", "tva", "email",
"telephone", "website", "comment", "address",
'adr_adresse', 'adr_code_postal', 'adr_ville', 'adr_pays',
'invoice_email', 'invoice_nom', 'invoice_siret',
'invoice_tva', 'invoice_condition_paiement_id', 'invoice_adresse', 'invoice_ville',
'invoice_code_postal', 'invoice_pays', "client_type_id",
'is_fournisseur', 'is_client', 'is_financeur', 'is_client']
# Pre Remplir les champs à vide
for tmp in new_partner_all_list:
new_client_data[str(tmp)] = ""
new_client_data['token'] = diction['token']
new_client_contact_data['token'] = diction['token']
if ("nom" in local_inscription_no_client.keys()):
new_client_data['raison_sociale'] = local_inscription_no_client['nom']
new_client_data['nom'] = local_inscription_no_client['nom']
# Pour le contact
new_client_contact_data['nom'] = local_inscription_no_client['nom']
if ("prenom" in local_inscription_no_client.keys()):
# Pour le contact
new_client_contact_data['prenom'] = local_inscription_no_client['prenom']
if ("civilite" in local_inscription_no_client.keys()):
# Pour le contact
new_client_contact_data['civilite'] = str(local_inscription_no_client['civilite']).lower()
if( "email" in local_inscription_no_client.keys() ):
new_client_data['email'] = local_inscription_no_client['email']
new_client_data['invoice_email'] = local_inscription_no_client['email']
# Pour le contact
new_client_contact_data['email'] = local_inscription_no_client['email']
if ("telephone" in local_inscription_no_client.keys()):
new_client_data['telephone'] = local_inscription_no_client['telephone']
# Pour le contact
new_client_contact_data['telephone'] = local_inscription_no_client['telephone']
if ("adresse" in local_inscription_no_client.keys()):
new_client_data['adr_adresse'] = local_inscription_no_client['adresse']
new_client_data['invoice_adresse'] = local_inscription_no_client['adresse']
# Pour le contact
new_client_contact_data['adr_adresse'] = local_inscription_no_client['adresse']
if("code_postal" in local_inscription_no_client.keys()):
new_client_data['adr_code_postal'] = local_inscription_no_client['code_postal']
new_client_data['invoice_code_postal'] = local_inscription_no_client['code_postal']
# Pour le contact
new_client_contact_data['adr_code_postal'] = local_inscription_no_client['code_postal']
if ("ville" in local_inscription_no_client.keys()):
new_client_data['adr_ville'] = local_inscription_no_client['ville']
new_client_data['invoice_ville'] = local_inscription_no_client['ville']
# Pour le contact
new_client_contact_data['adr_ville'] = local_inscription_no_client['ville']
if ("pays" in local_inscription_no_client.keys()):
new_client_data['adr_pays'] = local_inscription_no_client['pays']
new_client_data['invoice_pays'] = local_inscription_no_client['pays']
# Pour le contact
new_client_contact_data['adr_pays'] = local_inscription_no_client['pays']
new_client_data['is_client'] = "1"
new_client_data['is_company'] = "0"
new_client_status, new_client_retval = partner_client.Add_Partner_Client(new_client_data)
if (new_client_status is False):
mycommon.myprint(" Facturation : Impossible de créer un client associé à l'adresse email : " + str(
local_inscription_no_client['email']) + " ")
return False, " Facturation : Impossible de créer un client associé à l'adresse email : " + str(
local_inscription_no_client['email']) + " ", False
inscription_no_client_valide_no_locked_data = MYSY_GV.dbname['partner_client'].find_one(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email']),
'valide': "1",
'locked': '0'})
# Créer le contact de communication du client
new_client_contact_data['include_com'] = "1"
new_client_contact_data['related_collection'] = "partner_client"
new_client_contact_data['related_collection_owner_id'] = str(inscription_no_client_valide_no_locked_data['_id'])
local_add_contact_status, local_add_contact_retval = Contact.Add_Contact(new_client_contact_data)
if( local_add_contact_status is False ):
mycommon.myprint(str(inspect.stack()[0][3]) + " WARNING : Impossible de créer le contact "+str(local_add_contact_retval))
# Mise à jour de l'inscription avec l'_id du client
MYSY_GV.dbname['inscription'].update_one({'partner_owner_recid': str(my_partner['recid']),
'_id': ObjectId(local_inscription_no_client['_id'])},
{'$set': {'facture_client_rattachement_id': str(
inscription_no_client_valide_no_locked_data['_id'])}})
# Verifier qu'il ya bien des inscriptions valides dans la session pour le client
liste_client_rattachement_id = MYSY_GV.dbname['inscription'].distinct("facture_client_rattachement_id",
{'session_id':str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(
my_partner['recid']),
"facture_client_rattachement_id": { '$ne': ''},
"invoiced": {'$ne': '1'}
}
)
print(" ### la liste des liste_client_rattachement_id = ", liste_client_rattachement_id)
# Sauvegarde des fichiers joints depuis le front
tab_saved_file_full_path = []
for file in tab_files:
status, saved_file_full_path = mycommon.Upload_Save_PDF_IMG_File(file, Folder)
if (status is False):
mycommon.myprint("Impossible de récupérer correctement le fichier à importer")
return False, "Impossible de récupérer correctement le fichier à importer", False
tab_saved_file_full_path.append(saved_file_full_path)
print(" #### tab_saved_file_full_path = ", tab_saved_file_full_path)
# Recupération des données du modèle de document
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
tab_local_invoice_ref_interne = []
# Envoie des factures pour les inscrits AVEC client_id (conventions d'entreprise)
for single_client in liste_client_rattachement_id:
print(" Traitement du client_id = ", single_client)
# Recuperation des contacts de communication du client
local_diction = {}
local_diction['token'] = diction['token']
local_diction['_id'] = str(single_client)
print(" ##### local_diction = ", local_diction)
local_status, partner_client_contact_communication = partner_client.Get_Partner_Client_Communication_Contact(
local_diction)
if (local_status is False):
mycommon.myprint(" Impossible de récupérer les contacts de communication du client ")
return False, " Impossible de récupérer les contacts de communication du client ", False
print(" ### partner_client_contact_communication = ", partner_client_contact_communication)
tab_local_email_production = []
for tmp in partner_client_contact_communication:
tmp_JSON = ast.literal_eval(tmp)
if ("email" in tmp_JSON.keys()):
tab_local_email_production.append(str(tmp_JSON["email"]))
list_local_email_production = ",".join(tab_local_email_production)
new_diction_client = {}
new_diction_client['partner_client_id'] = single_client
new_diction_client['token'] = diction['token']
new_diction_client['courrier_template_id'] = diction['courrier_template_id']
new_diction_client['email_test'] = diction['email_test']
new_diction_client['email_production'] = str(list_local_email_production)
new_diction_client['session_id'] = diction['session_id']
print(" ##### new_diction_client 0102 = ", new_diction_client)
# Creation de la facture du client
diction_invoice = {}
diction_invoice['token'] = diction['token']
diction_invoice['partner_client_id'] = single_client
diction_invoice['session_id'] = diction['session_id']
#print(" ##### diction_invoice 0202 = ", diction_invoice)
local_create_invoice_status, local_create_invoice_retval, local_invoice_ref_interne = Invoice_Partner_From_Session(diction_invoice)
if( local_create_invoice_status is False ):
return local_create_invoice_status, local_create_invoice_retval, False
"""
Mettre à jour les lignes associées à ce client pour dire que la ligne est facturé
"""
now = str(datetime.now())
update_data = {}
update_data['invoiced'] = "1"
update_data['invoiced_ref'] = str(local_invoice_ref_interne)
update_data['invoiced_date'] = now
update_data['date_update'] = now
update_data['update_by'] = str(my_partner['_id'])
update = MYSY_GV.dbname['inscription'].update_many({'partner_owner_recid':str(my_partner['recid']),
'session_id':diction['session_id'],
'facture_client_rattachement_id':str(single_client)},
{'$set':update_data})
tab_local_invoice_ref_interne.append(str(local_invoice_ref_interne))
"""
07/03/20204 : mettre un statut de facturation sur la session afin de voir
tout de suite quel session est entièrement facturée ou partiellement.
regles :
Si toutes les inscription associées à une session sont facturée ==> invoiced_statut de la session = 2
Si au moins une inscription associée à une session est facturé ==> invoiced_statut de la session = 1
Si non invoiced_statut de la session =0
"""
nb_inscription_facture = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'session_id': diction['session_id'],
'invoiced': '1'})
nb_inscription_non_facture = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'session_id': diction['session_id'],
'invoiced': {'$ne': '1'}})
nb_inscription_valide = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'session_id': diction['session_id'],
'status': '1'})
invoiced_statut = "0"
if (nb_inscription_facture == nb_inscription_valide):
# toutes les inscription valides ont été facturée
invoiced_statut = "2"
elif (nb_inscription_facture > 0):
# Au moins une ligne a été facturée
invoiced_statut = "1"
# Mise à jour du statut de facturation de la session
MYSY_GV.dbname['session_formation'].update_one({'partner_owner_recid': my_partner['recid'],
'valide': '1',
'_id': ObjectId(str(diction['session_id']))
},
{'$set': {'invoiced_statut': invoiced_statut}})
# Creation de l'historique dans les action 'courrier_template_tracking_history'
local_qry = {'partner_owner_recid':str(my_partner['recid']), 'session_id':str(diction['session_id']),
'invoiced_ref': {'$in': tab_local_invoice_ref_interne} }
#print(" ### local_qry = ", local_qry)
for val in MYSY_GV.dbname['inscription'].find({'partner_owner_recid':str(my_partner['recid']),
'session_id':str(diction['session_id']),
'invoiced_ref': {'$in': tab_local_invoice_ref_interne} }):
ref_facture = ""
if( "invoiced_ref" in val.keys() ):
ref_facture = val['invoiced_ref']
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(
my_partner, "FACTURATION_SESSION", str(diction['session_id']), 'inscription',
str(val['_id']),
str(diction['courrier_template_id']),
"Facture : "+str(ref_facture)
)
if( local_status is False ):
mycommon.myprint(" WARNING : Impossible de logguer l'historique l'inscription_id : " + str(val['_id']))
return_message = " La session a été correctement facturée.\nListe des factures : "
for tmp in tab_local_invoice_ref_interne:
return_message += "\n - "+str(tmp)
return True, str(return_message), tab_local_invoice_ref_interne
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de créer et d'envoyer les factures par email ", False
def Prepare_and_Send_Facture_From_Session_By_Email_SAVE_ORIG(tab_files, Folder, diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'email_test', 'email_production']
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", False
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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, False
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide ", False
"""
Gestion des inscriptions n'ayant pas de client ID
"""
liste_inscription_no_client = MYSY_GV.dbname['inscription'].find(
{"$or": [{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
"client_rattachement_id": '',
"invoiced": {'$ne': '1'}
},
{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'client_rattachement_id': {'$exists': False},
"invoiced": {'$ne': '1'}
}]
}
)
# CONTROLE : Verification des data client (si tous les clients 'particuliers' sont ok
for local_inscription_no_client in liste_inscription_no_client:
print(" ### List des inscrit n'ayant pas de 'client_id': ", local_inscription_no_client)
"""
- Verifier s'il y a un client avec la même adresse email,
si non, créer le client
"""
is_inscription_no_client_exist = MYSY_GV.dbname['partner_client'].count_documents(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email'])})
# S'il ya plusieurs clients avec la meme adresse email, alors il y a un bin's
if (is_inscription_no_client_exist > 1):
mycommon.myprint(" Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à plusieurs clients")
return False, " Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à plusieurs clients ", False
# Si le client existe, verifier qu'il est valide et pas locké
if (is_inscription_no_client_exist == 1):
is_inscription_no_client_valide_no_locked = MYSY_GV.dbname['partner_client'].count_documents(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email']),
'valide': "1",
'locked': '0'})
if (is_inscription_no_client_valide_no_locked == 0):
mycommon.myprint(" Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à un client non valide")
return False, " Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à un client non valide ", False
# Mise à jour de l'inscription avec l'_id du client
inscription_no_client_valide_no_locked_data = MYSY_GV.dbname['partner_client'].find_one(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email']),
'valide': "1",
'locked': '0'})
MYSY_GV.dbname['inscription'].update_one({'partner_owner_recid': str(my_partner['recid']),
'_id': ObjectId(local_inscription_no_client['_id'])},
{'$set': {'client_rattachement_id': str(
inscription_no_client_valide_no_locked_data['_id'])}})
# Si il n'y a pas de client associé à cette adresse email, alors on crée le client
if (is_inscription_no_client_exist == 0):
new_client_contact_data = {}
new_client_data = {}
new_partner_all_list = ['token', "raison_sociale", "nom", "siret", "tva", "email",
"telephone", "website", "comment", "address",
'adr_adresse', 'adr_code_postal', 'adr_ville', 'adr_pays',
'invoice_email', 'invoice_nom', 'invoice_siret',
'invoice_tva', 'invoice_condition_paiement_id', 'invoice_adresse', 'invoice_ville',
'invoice_code_postal', 'invoice_pays', "client_type_id",
'is_fournisseur', 'is_client', 'is_financeur', 'is_client']
# Pre Remplir les champs à vide
for tmp in new_partner_all_list:
new_client_data[str(tmp)] = ""
new_client_data['token'] = diction['token']
new_client_contact_data['token'] = diction['token']
if ("nom" in local_inscription_no_client.keys()):
new_client_data['raison_sociale'] = local_inscription_no_client['nom']
new_client_data['nom'] = local_inscription_no_client['nom']
# Pour le contact
new_client_contact_data['nom'] = local_inscription_no_client['nom']
if ("prenom" in local_inscription_no_client.keys()):
# Pour le contact
new_client_contact_data['prenom'] = local_inscription_no_client['prenom']
if ("civilite" in local_inscription_no_client.keys()):
# Pour le contact
new_client_contact_data['civilite'] = str(local_inscription_no_client['civilite']).lower()
if( "email" in local_inscription_no_client.keys() ):
new_client_data['email'] = local_inscription_no_client['email']
new_client_data['invoice_email'] = local_inscription_no_client['email']
# Pour le contact
new_client_contact_data['email'] = local_inscription_no_client['email']
if ("telephone" in local_inscription_no_client.keys()):
new_client_data['telephone'] = local_inscription_no_client['telephone']
# Pour le contact
new_client_contact_data['telephone'] = local_inscription_no_client['telephone']
if ("adresse" in local_inscription_no_client.keys()):
new_client_data['adr_adresse'] = local_inscription_no_client['adresse']
new_client_data['invoice_adresse'] = local_inscription_no_client['adresse']
# Pour le contact
new_client_contact_data['adr_adresse'] = local_inscription_no_client['adresse']
if("code_postal" in local_inscription_no_client.keys()):
new_client_data['adr_code_postal'] = local_inscription_no_client['code_postal']
new_client_data['invoice_code_postal'] = local_inscription_no_client['code_postal']
# Pour le contact
new_client_contact_data['adr_code_postal'] = local_inscription_no_client['code_postal']
if ("ville" in local_inscription_no_client.keys()):
new_client_data['adr_ville'] = local_inscription_no_client['ville']
new_client_data['invoice_ville'] = local_inscription_no_client['ville']
# Pour le contact
new_client_contact_data['adr_ville'] = local_inscription_no_client['ville']
if ("pays" in local_inscription_no_client.keys()):
new_client_data['adr_pays'] = local_inscription_no_client['pays']
new_client_data['invoice_pays'] = local_inscription_no_client['pays']
# Pour le contact
new_client_contact_data['adr_pays'] = local_inscription_no_client['pays']
new_client_data['is_client'] = "1"
new_client_data['is_company'] = "0"
new_client_status, new_client_retval = partner_client.Add_Partner_Client(new_client_data)
if (new_client_status is False):
mycommon.myprint(" Facturation : Impossible de créer un client associé à l'adresse email : " + str(
local_inscription_no_client['email']) + " ")
return False, " Facturation : Impossible de créer un client associé à l'adresse email : " + str(
local_inscription_no_client['email']) + " ", False
inscription_no_client_valide_no_locked_data = MYSY_GV.dbname['partner_client'].find_one(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email']),
'valide': "1",
'locked': '0'})
# Créer le contact de communication du client
new_client_contact_data['include_com'] = "1"
new_client_contact_data['related_collection'] = "partner_client"
new_client_contact_data['related_collection_owner_id'] = str(inscription_no_client_valide_no_locked_data['_id'])
local_add_contact_status, local_add_contact_retval = Contact.Add_Contact(new_client_contact_data)
if( local_add_contact_status is False ):
mycommon.myprint(str(inspect.stack()[0][3]) + " WARNING : Impossible de créer le contact "+str(local_add_contact_retval))
# Mise à jour de l'inscription avec l'_id du client
MYSY_GV.dbname['inscription'].update_one({'partner_owner_recid': str(my_partner['recid']),
'_id': ObjectId(local_inscription_no_client['_id'])},
{'$set': {'client_rattachement_id': str(
inscription_no_client_valide_no_locked_data['_id'])}})
# Verifier qu'il ya bien des inscriptions valides dans la session pour le client
liste_client_rattachement_id = MYSY_GV.dbname['inscription'].distinct("client_rattachement_id",
{'session_id':str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(
my_partner['recid']),
"client_rattachement_id": { '$ne': ''},
"invoiced": {'$ne': '1'}
}
)
print(" ### la liste des liste_client_rattachement_id = ", liste_client_rattachement_id)
# Sauvegarde des fichiers joints depuis le front
tab_saved_file_full_path = []
for file in tab_files:
status, saved_file_full_path = mycommon.Upload_Save_PDF_IMG_File(file, Folder)
if (status is False):
mycommon.myprint("Impossible de récupérer correctement le fichier à importer")
return False, "Impossible de récupérer correctement le fichier à importer", False
tab_saved_file_full_path.append(saved_file_full_path)
print(" #### tab_saved_file_full_path = ", tab_saved_file_full_path)
# Recupération des données du modèle de document
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
tab_local_invoice_ref_interne = []
# Envoie des factures pour les inscrits AVEC client_id (conventions d'entreprise)
for single_client in liste_client_rattachement_id:
print(" Traitement du client_id = ", single_client)
# Recuperation des contacts de communication du client
local_diction = {}
local_diction['token'] = diction['token']
local_diction['_id'] = str(single_client)
print(" ##### local_diction = ", local_diction)
local_status, partner_client_contact_communication = partner_client.Get_Partner_Client_Communication_Contact(
local_diction)
if (local_status is False):
mycommon.myprint(" Impossible de récupérer les contacts de communication du client ")
return False, " Impossible de récupérer les contacts de communication du client ", False
print(" ### partner_client_contact_communication = ", partner_client_contact_communication)
tab_local_email_production = []
for tmp in partner_client_contact_communication:
tmp_JSON = ast.literal_eval(tmp)
if ("email" in tmp_JSON.keys()):
tab_local_email_production.append(str(tmp_JSON["email"]))
list_local_email_production = ",".join(tab_local_email_production)
new_diction_client = {}
new_diction_client['partner_client_id'] = single_client
new_diction_client['token'] = diction['token']
new_diction_client['courrier_template_id'] = diction['courrier_template_id']
new_diction_client['email_test'] = diction['email_test']
new_diction_client['email_production'] = str(list_local_email_production)
new_diction_client['session_id'] = diction['session_id']
print(" ##### new_diction_client 0102 = ", new_diction_client)
# Creation de la facture du client
diction_invoice = {}
diction_invoice['token'] = diction['token']
diction_invoice['partner_client_id'] = single_client
diction_invoice['session_id'] = diction['session_id']
#print(" ##### diction_invoice 0202 = ", diction_invoice)
local_create_invoice_status, local_create_invoice_retval, local_invoice_ref_interne = Invoice_Partner_From_Session(diction_invoice)
if( local_create_invoice_status is False ):
return local_create_invoice_status, local_create_invoice_retval, False
"""
Mettre à jour les lignes associées à ce client pour dire que la ligne est facturé
"""
now = str(datetime.now())
update_data = {}
update_data['invoiced'] = "1"
update_data['invoiced_ref'] = str(local_invoice_ref_interne)
update_data['invoiced_date'] = now
update_data['date_update'] = now
update_data['update_by'] = str(my_partner['_id'])
update = MYSY_GV.dbname['inscription'].update_many({'partner_owner_recid':str(my_partner['recid']),
'session_id':diction['session_id'],
'client_rattachement_id':str(single_client)},
{'$set':update_data})
tab_local_invoice_ref_interne.append(str(local_invoice_ref_interne))
"""
07/03/20204 : mettre un statut de facturation sur la session afin de voir
tout de suite quel session est entièrement facturée ou partiellement.
regles :
Si toutes les inscription associées à une session sont facturée ==> invoiced_statut de la session = 2
Si au moins une inscription associée à une session est facturé ==> invoiced_statut de la session = 1
Si non invoiced_statut de la session =0
"""
nb_inscription_facture = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'session_id': diction['session_id'],
'invoiced': '1'})
nb_inscription_non_facture = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'session_id': diction['session_id'],
'invoiced': {'$ne': '1'}})
nb_inscription_valide = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'session_id': diction['session_id'],
'status': '1'})
invoiced_statut = "0"
if (nb_inscription_facture == nb_inscription_valide):
# toutes les inscription valides ont été facturée
invoiced_statut = "2"
elif (nb_inscription_facture > 0):
# Au moins une ligne a été facturée
invoiced_statut = "1"
# Mise à jour du statut de facturation de la session
MYSY_GV.dbname['session_formation'].update_one({'partner_owner_recid': my_partner['recid'],
'valide': '1',
'_id': ObjectId(str(diction['session_id']))
},
{'$set': {'invoiced_statut': invoiced_statut}})
# Creation de l'historique dans les action 'courrier_template_tracking_history'
local_qry = {'partner_owner_recid':str(my_partner['recid']), 'session_id':str(diction['session_id']),
'invoiced_ref': {'$in': tab_local_invoice_ref_interne} }
#print(" ### local_qry = ", local_qry)
for val in MYSY_GV.dbname['inscription'].find({'partner_owner_recid':str(my_partner['recid']),
'session_id':str(diction['session_id']),
'invoiced_ref': {'$in': tab_local_invoice_ref_interne} }):
ref_facture = ""
if( "invoiced_ref" in val.keys() ):
ref_facture = val['invoiced_ref']
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(
my_partner, "FACTURATION_SESSION", str(diction['session_id']), 'inscription',
str(val['_id']),
str(diction['courrier_template_id']),
"Facture : "+str(ref_facture)
)
if( local_status is False ):
mycommon.myprint(" WARNING : Impossible de logguer l'historique l'inscription_id : " + str(val['_id']))
return_message = " La session a été correctement facturée.\nListe des factures : "
for tmp in tab_local_invoice_ref_interne:
return_message += "\n - "+str(tmp)
return True, str(return_message), tab_local_invoice_ref_interne
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de créer et d'envoyer les factures par email ", False
"""
Cette fonction va créer une facture pour un client
lié à des apprenants sur une session de formation
"""
def Invoice_Partner_From_Session( diction):
try:
field_list_obligatoire = ['token', 'partner_client_id', 'session_id']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La valeur '" + val + "' n'est pas presente dans liste ")
return False, " La valeur '" + val + "' n'est pas presente dans liste", False
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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, False
# Verifier que la session est valide
is_session_id_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_id_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide ", False
# Verifier que ce client a bien des inscriptions valide pour cette session
nb_valide_inscription_pr_client = MYSY_GV.dbname['inscription'].count_documents(
{'facture_client_rattachement_id': str(diction['partner_client_id']),
'session_id': str(diction['session_id']),
'partner_owner_recid': str(my_partner['recid']),
'status': '1'})
if (nb_valide_inscription_pr_client <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune inscription valide pour ce client pour cette session ")
return False, " Aucune inscription valide pour ce client pour cette session ", False
partner_client_id_data = MYSY_GV.dbname['partner_client'].find_one(
{'_id': ObjectId(str(diction['partner_client_id'])),
'valide': '1',
'locked': '0',
'partner_recid': str(my_partner['recid'])})
# Recuperation des données du stagiaire
inscription_data = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'facture_client_rattachement_id':str(diction['partner_client_id'])})
tab_apprenant = []
tab_participant = []
for val in inscription_data:
tab_participant.append(val['_id'])
"""
update du 30/01/2024
si le participant à un apprenant_id, alors on recupere la valeur de l'apprenant id. On doit travailler sur cette dernier.
En general, avant d'envoyer une convocation ou convention, l'inscription est validée et donc le dossier apprenant existe.
Du coup si tout se passe bien, dans cette fonction, on travaillera tjrs avec l'apprenant_id
"""
if ("apprenant_id" in val.keys() and val['apprenant_id']):
tab_apprenant.append(ObjectId(str(val['apprenant_id'])))
print(" ### tab_participant 2 = ", tab_participant)
# Recuperations des info de la session de formation
session_data = MYSY_GV.dbname['session_formation'].find_one({'_id': ObjectId(str(diction['session_id']))})
tab_session = []
tab_session.append(session_data['_id'])
# Recuperation du titre de la formation
class_data = MYSY_GV.dbname['myclass'].find({'internal_url': str(session_data['class_internal_url']),
'valide': '1',
'partner_owner_recid': str(my_partner['recid']),
'locked': '0'})
price_by = "perstagiaire"
if( "perstagiaire" in session_data.keys() ):
price_by = session_data['perstagiaire']
if( price_by not in MYSY_GV.TRAINING_PRICE) :
mycommon.myprint(str(inspect.stack()[0][3]) + " Le prix par " + str(price_by) + " n'est valide. Les valeurs autorisées sont " + str(MYSY_GV.TRAINING_PRICE))
return False, " Le prix par " + str(price_by) + " n'est valide. Les valeurs autorisées sont " + str(MYSY_GV.TRAINING_PRICE) + " ", False
partner_invoice_header_data = {}
list_partner_invoice_header_champ = ['order_header_client_id', 'order_header_ref_interne', 'order_header_email_client', 'order_header_origin', 'order_header_ref_client', 'order_header_vendeur_id',
'order_header_date_cmd', 'order_header_date_expiration', 'order_header_adr_fact_adresse', 'order_header_adr_fact_code_postal', 'order_header_adr_fact_ville', 'order_header_adr_fact_pays',
'order_header_adr_liv_adresse', 'order_header_adr_liv_code_postal', 'order_header_adr_liv_ville', 'order_header_adr_liv_pays', 'valide', 'locked', 'date_update',
'order_header_montant_reduction', 'order_header_tax', 'order_header_tax_amount', 'total_header_hors_taxe_after_header_reduction', 'total_header_hors_taxe_before_header_reduction',
'total_header_toutes_taxes', 'total_lines_hors_taxe_after_lines_reduction', 'total_lines_hors_taxe_before_lines_reduction', 'total_lines_montant_reduction', 'invoice_header_ref_interne',
'invoice_header_type', 'invoice_date', 'update_by']
# PreRemplir les champs
for val in list_partner_invoice_header_champ:
partner_invoice_header_data[str(val)] = ""
partner_invoice_header_data['order_header_client_id'] = str(partner_client_id_data['_id'])
"""
Recuperation des conditions de paiement depuis le client
"""
ction_paiement_code = ""
ction_paiement_desc = ""
ction_paiement_depart = "facture"
ction_paiement_nb_jour = "0"
if ("invoice_condition_paiement_id" in partner_client_id_data.keys() and partner_client_id_data[
'invoice_condition_paiement_id']):
ction_paiement_data = MYSY_GV.dbname['base_partner_paiement_condition'].find_one(
{'partner_owner_recid': my_partner['recid'],
'valide': '1',
'locked': '0',
'_id': ObjectId(str(partner_client_id_data['invoice_condition_paiement_id']))})
if (ction_paiement_data and "code" in ction_paiement_data.keys() and ction_paiement_data['code']):
ction_paiement_code = ction_paiement_data['code']
if (ction_paiement_data and "description" in ction_paiement_data.keys() and ction_paiement_data[
'description']):
ction_paiement_desc = ction_paiement_data['description']
if (ction_paiement_data and "nb_jour" in ction_paiement_data.keys() and ction_paiement_data['nb_jour'] and
"depart" in ction_paiement_data.keys() and ction_paiement_data['depart']):
ction_paiement_nb_jour = ction_paiement_data['nb_jour']
ction_paiement_depart = ction_paiement_data['depart']
nb_jour_int = mycommon.tryInt(str(ction_paiement_nb_jour))
today = datetime.today()
date_echance = datetime.today()
if (str(ction_paiement_depart) == "mois"):
days_in_month = lambda dt: monthrange(dt.year, dt.month)[1]
first_day_next_month = today.replace(day=1) + timedelta(days_in_month(today))
date_echance = first_day_next_month + timedelta(days=nb_jour_int)
else:
date_echance = today + timedelta(days=nb_jour_int)
date_echance = date_echance.strftime("%d/%m/%Y")
partner_invoice_header_data['invoice_date_echeance'] = str(date_echance)
partner_invoice_header_data['order_header_condition_paiement_code'] = str(ction_paiement_code)
partner_invoice_header_data['order_header_condition_paiement_description'] = str(ction_paiement_desc)
code_session = ""
if( "code_session" in session_data.keys() ):
code_session = session_data['code_session']
partner_invoice_header_data['order_header_ref_interne'] = "Code_Session_"+str(code_session)
order_header_email_client = ""
if ("email" in partner_client_id_data.keys()):
order_header_email_client = partner_client_id_data['email']
partner_invoice_header_data['order_header_email_client'] = order_header_email_client
order_header_origin = "session_id_"+str(session_data['_id'])
partner_invoice_header_data['order_header_origin'] = order_header_origin
order_header_adr_fact_adresse = ""
if( "invoice_adresse" in partner_client_id_data.keys() ):
order_header_adr_fact_adresse = partner_client_id_data['invoice_adresse']
partner_invoice_header_data['order_header_adr_fact_adresse'] = order_header_adr_fact_adresse
order_header_adr_fact_ville = ""
if ("invoice_ville" in partner_client_id_data.keys()):
order_header_adr_fact_ville = partner_client_id_data['invoice_adresse']
partner_invoice_header_data['order_header_adr_fact_ville'] = order_header_adr_fact_ville
order_header_adr_fact_code_postal = ""
if ("invoice_code_postal" in partner_client_id_data.keys()):
order_header_adr_fact_code_postal = partner_client_id_data['invoice_code_postal']
partner_invoice_header_data['order_header_adr_fact_code_postal'] = order_header_adr_fact_code_postal
order_header_adr_fact_pays = ""
if ("invoice_pays" in partner_client_id_data.keys()):
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_montant_reduction = "0"
partner_invoice_header_data['order_header_montant_reduction'] = order_header_montant_reduction
# Calcul du Totol HT sans reduction
total_ht = 0
prix_session = 0
session_price = 0
if( "prix_session" not in session_data.keys() ):
mycommon.myprint(str(inspect.stack()[0][3]) + " Facturation : La session n'a pas de prix valide")
return False, " Facturation : La session n'a pas de prix valide ", False
if( str(session_data['prix_session']).strip() == "" ):
mycommon.myprint(str(inspect.stack()[0][3]) + " Facturation : La session n'a pas de prix valide (2) ")
return False, " Facturation : La session n'a pas de prix valide (2) ", False
prix_session = mycommon.tryFloat(str(session_data['prix_session']))
if( str(price_by).strip() == "persession" ):
total_ht = round(prix_session, 2)
else:
total_ht = round(prix_session * nb_valide_inscription_pr_client, 2)
partner_invoice_header_data['total_header_hors_taxe_before_header_reduction'] = total_ht
# Recupération de la TVA de l'entité qui facture
taux_tva_statuts, taux_tva_retval = partner_base_setup.Get_Given_Partner_Basic_Setup({'token':str(diction['token']), 'config_name':'tva'})
if( taux_tva_statuts is False ):
mycommon.myprint(str(inspect.stack()[0][3]) + " Facturation : Impossible de récupérer le taux de TVA ")
return False, " Facturation : Impossible de récupérer le taux de TVA ", False
tmp = ast.literal_eval(taux_tva_retval[0])
taux_tva_retval = tmp['config_value']
print(" ### taux_tva_retval = ", taux_tva_retval)
tva_status, tva_value = mycommon.IsFloat(str(taux_tva_retval))
if (tva_status is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " Facturation : Le taux de TVA est invalide ")
return False, " Facturation : Le taux de TVA est invalide ", False
partner_invoice_header_data['order_header_tax'] = taux_tva_retval
partner_invoice_header_data['order_header_tax_amount'] = str(round(tva_value * total_ht/100, 2))
partner_invoice_header_data['total_header_toutes_taxes'] = str(round(total_ht + (tva_value * total_ht)/100, 2))
partner_invoice_header_data['invoice_header_type'] = "facture"
# Récuperation de la sequence de l'objet "partner_invoice_header" dans la collection : "mysy_sequence"
retval_sequence_invoice = MYSY_GV.dbname['mysy_sequence'].find_one(
{'partner_invoice_header': 'partner_order_header',
'valide': '1', 'partner_owner_recid': str(
my_partner['recid'])})
if (retval_sequence_invoice is None):
# Il n'y pas de sequence pour le partenaire, on va aller chercher la sequence par defaut
retval_sequence_invoice = MYSY_GV.dbname['mysy_sequence'].find_one(
{'related_mysy_object': 'partner_invoice_header',
'valide': '1', 'partner_owner_recid': 'default'})
if (retval_sequence_invoice is None or "current_val" not in retval_sequence_invoice.keys()):
# Il n'y aucune sequence meme par defaut.
mycommon.myprint(" Facture : Impossible de récupérer la sequence 'retval_sequence_invoice' ")
return False, "Facture : Impossible de récupérer la sequence 'retval_sequence_invoice' ", False
current_seq_value = str(retval_sequence_invoice['current_val'])
new_sequence_value = int(mycommon.tryInt(current_seq_value)) + 1
new_sequance_data_to_update = {'current_val': new_sequence_value}
ret_val2 = MYSY_GV.dbname['mysy_sequence'].find_one_and_update(
{'_id': ObjectId(str(retval_sequence_invoice['_id'])), 'valide': '1'},
{"$set": new_sequance_data_to_update},
return_document=ReturnDocument.AFTER,
upsert=False,
)
invoice_date_time = str(datetime.now().strftime("%d/%m/%Y"))
"""
Verifier qu'il n'y pas une facture du partenaire avec le meme ref interne
"""
is_already_invoice_ref_exist = MYSY_GV.dbname['partner_invoice_header'].count_documents({'partner_invoice_header':str(my_partner['recid']),
'valide':'1',
'invoice_header_ref_interne':str(retval_sequence_invoice['prefixe'] + str(current_seq_value))})
if( is_already_invoice_ref_exist > 0 ):
mycommon.myprint(" Facture : Il existe déjà une facture avec la même ref. interne : "+str(retval_sequence_invoice['prefixe'] + str(current_seq_value)))
return False, " Facture : Il existe déjà une facture avec la même ref. interne : "+str(retval_sequence_invoice['prefixe'] + str(current_seq_value)), False
partner_invoice_header_data['invoice_header_ref_interne'] = retval_sequence_invoice['prefixe'] + str(current_seq_value)
partner_invoice_header_data['invoice_header_type'] = "facture"
partner_invoice_header_data['invoice_date'] = invoice_date_time
partner_invoice_header_data['update_by'] = str(my_partner['_id'])
partner_invoice_header_data['valide'] = "1"
partner_invoice_header_data['locked'] = "0"
partner_invoice_header_data['partner_owner_recid'] = str(my_partner['recid'])
partner_invoice_header_data['date_update'] = str(datetime.now())
print(" #### partner_invoice_header_data = ", partner_invoice_header_data)
inserted_invoice_id = MYSY_GV.dbname['partner_invoice_header'].insert_one(partner_invoice_header_data).inserted_id
if (not inserted_invoice_id):
mycommon.myprint(" Facture : Impossible de créer l'entête de la facture ")
return False, " Facture : Impossible de créer l'entête de la facture ", False
"""
Création des lignes de facture.
Pour memo, dans la collection : partner_invoice_line
order_line_formation = titre formation
order_line_qty = nb participants
order_line_comment = la liste des personnes participans
"""
partner_invoice_line_data = {}
list_partner_invoice_line_champ = ['order_line_formation', 'order_line_qty', 'order_line_prix_unitaire', 'order_line_tax', 'order_line_tax_amount', 'order_line_montant_toutes_taxes',
'order_line_montant_hors_taxes', 'order_line_type_reduction', 'order_line_type_valeur', 'order_line_montant_reduction', 'order_header_ref_interne',
'order_line_comment', 'order_header_id', 'valide', 'locked', 'date_update', 'partner_owner_recid', 'invoice_header_ref_interne', 'invoice_line_type',
'invoice_date', 'invoice_header_id']
# PreRemplir les champs
for val in list_partner_invoice_line_champ:
partner_invoice_line_data[str(val)] = ""
nb_participant_du_client = len(tab_apprenant)
nom_prenom_email_participant = ""
for val in tab_apprenant:
local_apprenant = MYSY_GV.dbname['apprenant'].find_one({'_id':val, 'partner_owner_recid':str(my_partner['recid']),
'valide':'1', 'locked':'0'})
local_nom = ""
local_prenom = ""
local_email = ""
if( "nom" in local_apprenant.keys() ):
local_nom = local_apprenant['nom']
if ("prenom" in local_apprenant.keys()):
local_prenom = local_apprenant['prenom']
if ("email" in local_apprenant.keys()):
local_email = local_apprenant['email']
nom_prenom_email_participant += local_nom+" "+local_prenom+" "+local_email+"\n"
partner_invoice_line_data['order_line_formation'] = class_data[0]['internal_url']
partner_invoice_line_data['order_line_qty'] = str(nb_participant_du_client)
partner_invoice_line_data['order_line_prix_unitaire'] = str(prix_session)
partner_invoice_line_data['order_line_montant_hors_taxes'] = str(total_ht)
partner_invoice_line_data['order_line_comment'] = str(nom_prenom_email_participant)
partner_invoice_line_data['invoice_header_id'] = str(inserted_invoice_id)
partner_invoice_line_data['invoice_line_type'] = "facture"
partner_invoice_line_data['invoice_header_ref_interne'] = partner_invoice_header_data['invoice_header_ref_interne']
partner_invoice_line_data['update_by'] = str(my_partner['_id'])
partner_invoice_line_data['valide'] = "1"
partner_invoice_line_data['locked'] = "0"
partner_invoice_line_data['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'].insert_one(
partner_invoice_line_data).inserted_id
if (not inserted_invoice_id):
mycommon.myprint(" Facture : Impossible de créer les lignes de la facture "+str(partner_invoice_header_data['invoice_header_ref_interne']))
return False, " Facture : Impossible de créer les lignes de la facture "+str(partner_invoice_header_data['invoice_header_ref_interne']), False
return True, "L'email a été correctement envoyé ", str(partner_invoice_header_data['invoice_header_ref_interne'])
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 d'envoyer la convention par email ", False
"""
Envoie par email pour les stagiaires rattachés à un client
important :
si le champ 'email_test' est rempli, alors il s'agit d'un email de test.
donc on n'envoie pas l'email à l'adresss de prod ou contact du client
"""
def Sent_Facture_Stagiaire_By_Email_By_Partner_client(tab_files_name_full_path, Folder, diction):
try:
field_list_obligatoire = ['token', 'courrier_template_id', 'email_test', 'email_production', 'partner_client_id', 'session_id']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La valeur '" + val + "' n'est pas presente dans liste ")
return False, " La valeur '" + val + "' n'est pas presente dans liste"
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
# Verifier que la session est valide
is_session_id_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_id_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
# Verifier que ce client a bien des inscriptions valide pour cette session
is_valide_inscription_pr_client = MYSY_GV.dbname['inscription'].count_documents(
{'facture_client_rattachement_id': str(diction['partner_client_id']),
'session_id': str(diction['session_id']),
'partner_owner_recid': str(my_partner['recid']),
'status': '1'})
if (is_valide_inscription_pr_client <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune inscription valide pour ce client pour cette session ")
return False, " Aucune inscription valide pour ce client pour cette session "
partner_client_id_data = MYSY_GV.dbname['partner_client'].find_one(
{'_id': ObjectId(str(diction['partner_client_id'])),
'valide': '1',
'locked': '0',
'partner_recid': str(my_partner['recid'])})
# Traitement de l'eventuel fichier joint
tab_files_to_attache_to_mail = []
for file_name_full_path in tab_files_name_full_path:
"""status, saved_file = mycommon.Upload_Save_PDF_IMG_File(file, Folder)
if (status is False):
mycommon.myprint("Impossible de récupérer correctement le fichier à importer")
return False, "Impossible de récupérer correctement le fichier à importer"
"""
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(file_name_full_path, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(os.path.basename(file_name_full_path)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
# Verification de la validité des adresses email_recu
"""
/!\ : Si l'email de test est repli, alors on considere que c'est un test, on ne prend pas en compte l'email de email_production.
Ceci pour forcer les utilisateur à ne remplir que l'email de prod s'il veulent l'envoyer en prod.
Si l'adresse email_prodution = "defaul", cela veut dire qu'on envoie la convention à :
- l'adresse email du stagiaire et ses tuteurs (si les tuteurs on cochés la case 'inclu com'
"""
send_in_production = 0
tab_emails_destinataire = []
if ("email_test" in diction.keys() and diction['email_test']):
tab_email_test = str(diction['email_test']).replace(";", ",").split(",")
for email in tab_email_test:
email = email.strip()
if (mycommon.isEmailValide(email) is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'adresse email " + str(email) + " est invalide ")
return False, " L'adresse email " + str(email) + " est invalide "
tab_emails_destinataire = tab_email_test
elif ("email_production" in diction.keys() and diction['email_production']):
send_in_production = 1
if (str(diction['email_production']) != "default"):
tab_email_prod = str(diction['email_production']).replace(";", ",").split(",")
for email in tab_email_prod:
email = email.strip()
if (mycommon.isEmailValide(str(email)) is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'adresse email '" + str(email) + "' est invalide ")
return False, " L'adresse email " + str(email) + " est invalide "
tab_emails_destinataire = tab_email_prod
else:
tab_email_prod = "default"
else:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune adresse email n'a été fourni. ")
return False, " Aucune adresse email n'a été fourni. "
#print(" ## laaa : tab_emails_destinataire lalala = ", tab_emails_destinataire)
# Verifier que le 'courrier_template_id' est valide
# Ici le template doit etre un email
is_courrier_template_id_valide = MYSY_GV.dbname['courrier_template'].count_documents(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'type_doc': 'email',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
if (is_courrier_template_id_valide != 1):
mycommon.myprint(str(inspect.stack()[0][3]) + " L'identifiant du modèle de courrier est invalide ")
return False, " L'identifiant du modèle de courrier est invalide "
# Recupération des données du modèle de document
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
# Recuperation des eventuelles pièces jointes du modèle que courrier
local_dic = {}
local_dic['token'] = str(diction['token'])
local_dic['object_owner_collection'] = "courrier_template"
local_dic['object_owner_id'] = str(courrier_template_data['_id'])
local_status, local_retval = attached_file_mgt.Get_List_object_owner_collection_Stored_Files(local_dic)
if (local_status is False):
return local_status, local_retval
# print(" ### file stocké = ", local_retval)
# Recuperation des fichiers attachés au modele de courrier, s'il y en a
for file in local_retval:
local_JSON = ast.literal_eval(file)
saved_file = local_JSON['full_path']
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(saved_file, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(os.path.basename(saved_file)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
# Recuperation des données du stagiaire
inscription_data = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'facture_client_rattachement_id':str(diction['partner_client_id'])})
tab_apprenant = []
tab_participant = []
for val in inscription_data:
tab_participant.append(val['_id'])
"""
update du 30/01/2024
si le participant à un apprenant_id, alors on recupere la valeur de l'apprenant id. On doit travailler sur cette dernier.
En general, avant d'envoyer une convocation ou convention, l'inscription est validée et donc le dossier apprenant existe.
Du coup si tout se passe bien, dans cette fonction, on travaillera tjrs avec l'apprenant_id
"""
if ("apprenant_id" in val.keys() and val['apprenant_id']):
tab_apprenant.append(ObjectId(str(val['apprenant_id'])))
print(" ### tab_participant 3 = ", tab_participant)
# Recuperations des info de la session de formation
session_data = MYSY_GV.dbname['session_formation'].find_one({'_id': ObjectId(str(diction['session_id']))})
tab_session = []
tab_session.append(session_data['_id'])
# Recuperation du titre de la formation
class_data = MYSY_GV.dbname['myclass'].find({'internal_url': str(session_data['class_internal_url']),
'valide': '1',
'partner_owner_recid': str(my_partner['recid']),
'locked': '0'})
tab_class = []
for val in class_data:
tab_class.append(val['_id'])
# Recuperer les données du client
client_data = MYSY_GV.dbname['partner_client'].find_one({'_id':ObjectId(str(diction['partner_client_id'])),
'valide':'1',
'locked':'0',
'partner_recid': str(my_partner['recid']),
})
tab_client = []
tab_client.append(client_data['_id'])
# Creation du dictionnaire d'information à utiliser pour la creation du doc
convention_dictionnary_data = {}
new_diction = {}
new_diction['token'] = diction['token']
new_diction['list_stagiaire_id'] = tab_participant
new_diction['list_session_id'] = tab_session
new_diction['list_class_id'] = tab_class
new_diction['list_client_id'] = tab_client
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
## Creation du PDF
body = {
"params": convention_dictionnary_data,
}
# ---
# Verifier s'il s'agit d'un document à envoyer avec une version de pièce jointe.
if ("joint_pdf" in courrier_template_data.keys() and str(courrier_template_data['joint_pdf']) == "1"):
# Il s'agit bien d'un envoie avec 'contenu_doc' en pièce jointe PDF
"""
1 - Creation du PDF
"""
contenu_doc_Template = jinja2.Template(str(courrier_template_data['contenu_doc']))
sourceHtml = contenu_doc_Template.render(params=body["params"])
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-5:]
orig_file_name = "Convention_" + str(my_partner['recid'])[0:5] + "_" + str(ts) + ".pdf"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)
# open output file for writing (truncated binary)
resultFile = open(outputFilename, "w+b")
# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
src=sourceHtml, # the HTML to convert
dest=resultFile) # file handle to receive result
# close output file
resultFile.close()
# Attachement du fichier joint
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(outputFilename, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(os.path.basename(outputFilename)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
## Creation du mail au format email
corps_mail_Template = jinja2.Template(str(courrier_template_data['corps_mail']))
sourceHtml = corps_mail_Template.render(params=body["params"])
html_mime = MIMEText(sourceHtml, 'html')
# Creation de l'email à enoyer
msg = MIMEMultipart("alternative")
else:
# Il s'agit d'une simple email
## Creation du mail au format email
contenu_doc_Template = jinja2.Template(str(courrier_template_data['contenu_doc']))
sourceHtml = contenu_doc_Template.render(params=body["params"])
html_mime = MIMEText(sourceHtml, 'html')
# Creation de l'email à enoyer
msg = MIMEMultipart("alternative")
# ---
"""
## Creation du PDF
contenu_doc_Template = jinja2.Template(str(courrier_template_data['contenu_doc']))
sourceHtml = contenu_doc_Template.render(params=body["params"])
html_mime = MIMEText(sourceHtml, 'html')
# Creation de l'email à enoyer
msg = MIMEMultipart("alternative")
"""
"""
Recuperation des parametre SMTP du partner si le client a decidé d'utiliser son propre smpt
"""
partner_own_smtp_value = "0"
partner_own_smtp = MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'partner_smtp',
'valide': '1',
'locked': '0'})
if (partner_own_smtp and "config_value" in partner_own_smtp.keys()):
partner_own_smtp_value = partner_own_smtp['config_value']
if (str(partner_own_smtp_value) == "1"):
partner_SMTP_COUNT_password = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_user_pwd',
'valide': '1',
'locked': '0'}, {'config_value': 1})['config_value'])
partner_SMTP_COUNT_smtpsrv = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_server',
'valide': '1',
'locked': '0'}, {'config_value': 1})['config_value'])
partner_SMTP_COUNT_user = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_user',
'valide': '1',
'locked': '0'}, {'config_value': 1})['config_value'])
partner_SMTP_COUNT_From_User = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_count_from_name',
'valide': '1',
'locked': '0'}, {'config_value': 1})['config_value'])
partner_SMTP_COUNT_port = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_count_port',
'valide': '1',
'locked': '0'}, {'config_value': 1})['config_value'])
if (str(partner_own_smtp_value) == "1"):
smtpserver = smtplib.SMTP(partner_SMTP_COUNT_smtpsrv, partner_SMTP_COUNT_port)
else:
smtpserver = smtplib.SMTP(MYSY_GV.O365_SMTP_COUNT_smtpsrv, MYSY_GV.O365_SMTP_COUNT_port)
if (str(partner_own_smtp_value) == "1"):
msg.attach(html_mime)
msg['From'] = partner_SMTP_COUNT_From_User
msg['Bcc'] = 'contact@mysy-training.com'
msg['Subject'] = courrier_template_data['sujet']
# msg['to'] = "billardman01@hotmail.com"
toaddrs = ",".join(tab_emails_destinataire)
msg['to'] = str(toaddrs)
# Attacher l'eventuelle pièces jointes
for myfile in tab_files_to_attache_to_mail:
msg.attach(myfile['attached_file'])
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.login(partner_SMTP_COUNT_user, partner_SMTP_COUNT_password)
else:
msg.attach(html_mime)
msg['From'] = MYSY_GV.O365_SMTP_COUNT_From_User
msg['Bcc'] = 'contact@mysy-training.com'
msg['Subject'] = courrier_template_data['sujet']
# msg['to'] = "billardman01@hotmail.com"
toaddrs = ",".join(tab_emails_destinataire)
msg['to'] = str(toaddrs)
for myfile in tab_files_to_attache_to_mail:
msg.attach(myfile['attached_file'])
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.login(MYSY_GV.O365_SMTP_COUNT_user, MYSY_GV.O365_SMTP_COUNT_password)
val = smtpserver.send_message(msg)
smtpserver.close()
print(" 22 Email envoyé " + str(val))
"""
25/01/2024 : pour loger une action dans la collection ==> courrier_template_tracking_history
"""
# Recuperation des données du stagiaire
inscription_data = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'facture_client_rattachement_id': str(
diction['partner_client_id'])})
for inscription in inscription_data:
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(
my_partner, "CONVENTION_STAGIAIRE_ENTREPRISE", str(diction['session_id']), 'inscription',
str(inscription['_id']), str(courrier_template_data['_id']))
#print(" local_status = ", local_status)
"""
# Ajout de l'evenement dans l'historique
"""
# L'action n'est loggué pour les envois reels (en prod)
if (send_in_production == 1):
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = diction['token']
history_event_dict['related_collection'] = "partner_client"
history_event_dict['related_collection_recid'] = str(diction['partner_client_id'])
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Facture envoyée par email à la liste : " + str(
tab_emails_destinataire)
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
return True, "L'email a été correctement envoyé "
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 d'envoyer la convention par email "
"""
Cette fonction ne facture uniquement et exclusivement les lignes d'inscriptions sur lesquels
il ya une demande d'éclatement de la facture
C'est a dire que ligne d'inscription dispose d'un champ : "invoice_split" qui est valide.
Pour etre valide, ce champs est de type :
'invoice_split':{split_type : fixe/percent, tab_split : [{partner_client:cccc, invoice_part:40}, {partner_client:eeeeee, invoice_part:60} ....] }},
"""
def Invoice_Inscrption_With_Split_Session_By_Inscription_Id( tab_files, diction):
try:
field_list_obligatoire = ['token', 'session_id', 'tab_inscription_ids']
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", False
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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, False
# Verifier que la session est valide
is_session_id_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_id_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide ", False
my_inscription_ids = ""
if ("tab_inscription_ids" in diction.keys()):
if diction['tab_inscription_ids']:
my_inscription_ids = diction['tab_inscription_ids']
if( str(my_inscription_ids) == "all"):
# Recuperation des données du stagiaire
inscription_data = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
"invoiced": {'$ne': '1'}, })
else:
tab_my_inscription_ids = str(my_inscription_ids).split(",")
tab_my_inscription_ids_ObjectId = []
for tmp in tab_my_inscription_ids :
tab_my_inscription_ids_ObjectId.append(ObjectId(str(tmp)))
# Recuperation des données du stagiaire
inscription_data = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'_id':{'$in':tab_my_inscription_ids_ObjectId},
"invoiced": {'$ne': '1'},})
#print(" ### inscription_data = ", inscription_data)
tab_inscrit_for_splited_invoice = []
tab_inscrit_for_NOT_splited_invoice = []
tab_apprenant = []
tab_participant = []
for val in inscription_data:
if( "invoice_split" in val.keys() and val['invoice_split'] ):
tab_participant.append(val['_id'])
node = {}
node['inscription_id'] = str(val['_id'])
"""
update du 30/01/2024
si le participant à un apprenant_id, alors on recupere la valeur de l'apprenant id. On doit travailler sur cette dernier.
En general, avant d'envoyer une convocation ou convention, l'inscription est validée et donc le dossier apprenant existe.
Du coup si tout se passe bien, dans cette fonction, on travaillera tjrs avec l'apprenant_id
"""
if ("apprenant_id" in val.keys() and val['apprenant_id']):
tab_apprenant.append(ObjectId(str(val['apprenant_id'])))
node['apprenant_id'] = str(val['apprenant_id'])
else:
node['apprenant_id'] = ""
if( "invoice_split" in val.keys() ):
node['invoice_split'] = val['invoice_split']
else:
node['invoice_split'] = ""
# Verifier que le mode d'eclatement de la factue est soit : percent, soit fixe
if( "invoice_split" in val.keys() and val['invoice_split'] and
"split_type" in val['invoice_split'].keys() and val['invoice_split']['split_type']):
if( str(val['invoice_split']['split_type']).lower() not in ['percent', 'fixe'] ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Le mode de partage de la facture doit être 'percent' ou 'fixe' ")
return False, " Le mode de partage de la facture doit être 'percent' ou 'fixe' ", False
if ("invoice_split" in val.keys() and val['invoice_split'] and
"tab_split" in val['invoice_split'].keys() and val['invoice_split']['tab_split']):
for tmp in val['invoice_split']['tab_split'] :
if("invoice_part" in tmp.keys() ):
is_float_status, is_float_retaval = mycommon.IsFloat(str(tmp['invoice_part']))
if( is_float_status is False ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La valeur de partage de la facture n'est pas un nombre decimal ")
return False, " La valeur de partage de la facture n'est pas un nombre decimal ", False
elif ( is_float_retaval < 0 ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La valeur de partage de la facture est inférieure à 0 ")
return False, " La valeur de partage de la facture est inférieure à 0 ", False
tab_inscrit_for_splited_invoice.append(node)
else:
node = {}
node['inscription_id'] = str(val['_id'])
if ("apprenant_id" in val.keys() and val['apprenant_id']):
node['apprenant_id'] = str(val['apprenant_id'])
else:
node['apprenant_id'] = ""
tab_inscrit_for_NOT_splited_invoice.append(node)
print(" ### La liste des tab_inscrit_for_splited_invoice ", tab_inscrit_for_splited_invoice)
print(" ### La liste des tab_inscrit_for_NOT_splited_invoice ", tab_inscrit_for_NOT_splited_invoice)
print(" ### tab_apprenant = ", tab_apprenant)
"""
Creation du diction pour la facture SANS SPLIT de facture
"""
local_tmp_tab = []
list_non_splited_invoice = []
no_split_tab_inscription_ids = ""
for tmp in tab_inscrit_for_NOT_splited_invoice:
if( "inscription_id" in tmp.keys() ):
local_tmp_tab.append(tmp['inscription_id'])
no_split_tab_inscription_ids = ",".join(local_tmp_tab)
local_diction_for_NOT_INVOICE_SPLIT = {}
local_diction_for_NOT_INVOICE_SPLIT['tab_inscription_ids'] = no_split_tab_inscription_ids
local_diction_for_NOT_INVOICE_SPLIT['token'] = diction['token']
local_diction_for_NOT_INVOICE_SPLIT['session_id'] = diction['session_id']
local_diction_for_NOT_INVOICE_SPLIT['courrier_template_id'] = ""
local_diction_for_NOT_INVOICE_SPLIT['email_test'] = ""
local_diction_for_NOT_INVOICE_SPLIT['email_production'] = ""
print(" ### local_diction_for_NOT_INVOICE_SPLIT = ", local_diction_for_NOT_INVOICE_SPLIT)
status, retval, invoice_ref = Prepare_and_Send_Facture_From_Session_By_Inscription_Id_SAVE_ORIG(tab_files,
MYSY_GV.TEMPORARY_DIRECTORY_V2,
local_diction_for_NOT_INVOICE_SPLIT)
print(" ### status = ", status)
print(" ### retval = ", retval)
print(" ### local_diction_for_NOT_INVOICE_SPLIT invoice_ref = ", invoice_ref)
for tmp in invoice_ref:
list_non_splited_invoice.append(tmp)
list_non_splited_invoice_str = ', '.join(invoice_ref)
print(" ### BBBB list_non_splited_invoice_str = ", list_non_splited_invoice_str)
global_list_facture = list_non_splited_invoice_str
list_splited_invoice = []
"""
Creation du diction pour la facture AVEC SPLIT de facture
"""
for tmp in tab_inscrit_for_splited_invoice:
local_diction_for_WITH_INVOICE_SPLIT = {}
local_diction_for_WITH_INVOICE_SPLIT['token'] = diction['token']
local_diction_for_WITH_INVOICE_SPLIT['session_id'] = diction['session_id']
local_diction_for_WITH_INVOICE_SPLIT['inscription_id'] = tmp['inscription_id']
print(" ### local_diction_for_WITH_INVOICE_SPLIT = ", local_diction_for_WITH_INVOICE_SPLIT)
status, retval, invoice_ref = Invoice_Splited_Partner_From_Session_By_Inscription_Id( local_diction_for_WITH_INVOICE_SPLIT)
print(" ### status = ", status)
print(" ### retval = ", retval)
print(" ### local_diction_for_WITH_INVOICE_SPLIT invoice_ref = ", invoice_ref)
list_splited_invoice = str(invoice_ref).replace('[', '').replace(']', '').replace("'", "")
list_non_splited_invoice_str = list_non_splited_invoice_str+", "+str(list_splited_invoice)
global_list_facture = list_non_splited_invoice_str
tab_global_list_facture = str(global_list_facture).split(",")
print(" ### tab_global_list_facture = ", tab_global_list_facture)
"""
Recupeer le modele de courrier "courrier_template_type_document_ref_interne":"FACTURATION_SESSION"
depuis la collection courrier_template_tracking
"""
print(' QRY : ', {'courrier_template_type_document_ref_interne':'FACTURATION_SESSION',
'partner_owner_recid':my_partner['recid'],
'valide':'1',
'locked':'0',
}
)
courrier_template_count = MYSY_GV.dbname['courrier_template'].count_documents({'ref_interne':'FACTURATION_SESSION',
'partner_owner_recid':'default',
'valide':'1',
'locked':'0',
})
if( courrier_template_count != 1):
mycommon.myprint(" WARNING : Impossible d'identifier le courrier_template_count associé à la facturation : ")
else:
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one({'ref_interne':'FACTURATION_SESSION',
'partner_owner_recid':'default',
'valide':'1',
'locked':'0',
})
print(" ### courrier_template_data = ", courrier_template_data)
print(" QRYY = ", {'partner_owner_recid': str(my_partner['recid']),
'session_id': str(diction['session_id']),
'invoiced_ref': {'$in': tab_global_list_facture}})
if( courrier_template_data and '_id' in courrier_template_data.keys() ):
for local_data in tab_inscrit_for_splited_invoice :
for val in MYSY_GV.dbname['inscription'].find({'partner_owner_recid': str(my_partner['recid']),
'session_id': str(diction['session_id']),
'_id':ObjectId(str(local_data['inscription_id']))}):
ref_facture = ""
if ("invoiced_ref" in val.keys()):
ref_facture = val['invoiced_ref']
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(
my_partner, "FACTURATION_SESSION", str(diction['session_id']), 'inscription',
str(val['_id']),
str(courrier_template_data['_id']),
"Facture : " + str(ref_facture)
)
if (local_status is False):
mycommon.myprint(" WARNING : Impossible de logguer l'historique l'inscription_id : " + str(val['_id']))
for local_data in tab_inscrit_for_NOT_splited_invoice:
for val in MYSY_GV.dbname['inscription'].find({'partner_owner_recid': str(my_partner['recid']),
'session_id': str(diction['session_id']),
'_id': ObjectId(str(
local_data['inscription_id']))}):
ref_facture = ""
if ("invoiced_ref" in val.keys()):
ref_facture = val['invoiced_ref']
print(" ### traintement login de val = ", val)
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(
my_partner, "FACTURATION_SESSION", str(diction['session_id']), 'inscription',
str(val['_id']),
str(courrier_template_data['_id']),
"Facture : " + str(ref_facture)
)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique l'inscription_id : " + str(val['_id']))
global_list_facture = str(global_list_facture).replace(",", "\n")
"""
07/03/20204 : mettre un statut de facturation sur la session afin de voir
tout de suite quel session est entièrement facturée ou partiellement.
regles :
Si toutes les inscription associées à une session sont facturée ==> invoiced_statut de la session = 2
Si au moins une inscription associée à une session est facturé ==> invoiced_statut de la session = 1
Si non invoiced_statut de la session =0
"""
nb_inscription_facture_termine = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'invoiced': '1',
'session_id':str(diction['session_id'])
})
nb_inscription_non_facture_ou_encours = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'session_id': str(diction['session_id']),
'invoiced': {'$ne': '1'}})
nb_inscription_valide = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'session_id': str(diction['session_id']),
'status': '1'})
invoiced_statut = "0"
if (nb_inscription_facture_termine == nb_inscription_valide):
# toutes les inscription valides ont été facturée
invoiced_statut = "2"
elif (nb_inscription_non_facture_ou_encours > 0):
# Au moins une ligne a été facturée
invoiced_statut = "1"
# Mise à jour du statut de facturation de la session
MYSY_GV.dbname['session_formation'].update_one({'partner_owner_recid': my_partner['recid'],
'valide': '1',
'_id': ObjectId(str(diction['session_id']))
},
{'$set': {'invoiced_statut': invoiced_statut}})
return True, " Les factures suivantes été créées : \n "+str(global_list_facture), str(global_list_facture)
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 generer les factures ", False
"""
Facturation partielles d'une session.
C'est a dire le cas ou on souhaite facturer que les lignes selectionnées
/!\ :
Cette fonction est identique à la fonction : "Prepare_and_Send_Facture_From_Session_By_Email"
a l'exception qu'elle prend en compte les inscription_id à facturer
17/05/2024 : /!\
Maintenant on facture à partir du champs "facture_client_rattachement_id" et non
"client_rattachement_id" qui lui est concerné par les convention et autre documents
administratifs
"""
def Prepare_and_Send_Facture_From_Session_By_Inscription_Id(tab_files, Folder, diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'email_test', 'email_production',
'tab_inscription_ids']
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", False
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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, False
my_inscription_ids = ""
tab_my_inscription_ids = []
tab_my_inscription_ids_Object = []
if ("tab_inscription_ids" in diction.keys()):
if diction['tab_inscription_ids']:
my_inscription_ids = diction['tab_inscription_ids']
tab_my_inscription_ids = str(my_inscription_ids).split(",")
print(" ### tab_my_inscription_ids = ", tab_my_inscription_ids)
for my_inscription_id in tab_my_inscription_ids:
tmp_count = MYSY_GV.dbname['inscription'].count_documents({'session_id': str(diction['session_id']),
'_id': ObjectId(str(my_inscription_id)),
'partner_owner_recid': str(
my_partner['recid'])})
if (tmp_count != 1):
mycommon.myprint(str(inspect.stack()[0][3]) + " L'indentifiant de l'inscription " + str(
my_inscription_id) + " est invalide ")
return False, " L'indentifiant de l'inscription " + str(my_inscription_id) + " est invalide "
tab_my_inscription_ids_Object.append(ObjectId(str(my_inscription_id)))
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide ", False
# Verifier qu'il ya bien des inscriptions valides dans la session pour le client
liste_client_rattachement_id = []
liste_client_facturation_rattachement_id = MYSY_GV.dbname['inscription'].distinct(
"facture_client_rattachement_id",
{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(
my_partner['recid']),
"facture_client_rattachement_id": {'$ne': ''},
"invoiced": {'$ne': '1'},
"_id": {'$in': tab_my_inscription_ids_Object},
}
)
print(" ### la liste des liste_client_facturation_rattachement_id = ", liste_client_facturation_rattachement_id)
# Ajout des client de facturation
for tmp in liste_client_facturation_rattachement_id:
liste_client_rattachement_id.append(tmp)
print(" ### la liste des liste_client_rattachement_id = ", liste_client_rattachement_id)
"""
Gestion des inscriptions n'ayant pas de facture_client_rattachement_id
"""
liste_inscription_no_client = MYSY_GV.dbname['inscription'].find(
{"$or": [{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
"facture_client_rattachement_id": '',
"invoiced": {'$ne': '1'},
"_id": {'$in': tab_my_inscription_ids_Object},
},
{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'facture_client_rattachement_id': {'$exists': False},
"invoiced": {'$ne': '1'},
"_id": {'$in': tab_my_inscription_ids_Object},
}]
}
)
# CONTROLE : Verification des data client (si tous les clients 'particuliers' sont ok
for local_inscription_no_client in liste_inscription_no_client:
print(" ### List des inscrit n'ayant pas de 'facture_client_rattachement_id': ",
local_inscription_no_client)
"""
- Verifier s'il y a un client avec la même adresse email,
si non, créer le client
"""
is_inscription_no_client_exist = MYSY_GV.dbname['partner_client'].count_documents(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email'])})
# S'il ya plusieurs clients avec la meme adresse email, alors il y a un bin's
if (is_inscription_no_client_exist > 1):
mycommon.myprint(" Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à plusieurs clients")
return False, " Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à plusieurs clients ", False
# Si le client existe, verifier qu'il est valide et pas locké
if (is_inscription_no_client_exist == 1):
is_inscription_no_client_valide_no_locked = MYSY_GV.dbname['partner_client'].count_documents(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email']),
'valide': "1",
'locked': '0'})
if (is_inscription_no_client_valide_no_locked == 0):
mycommon.myprint(" Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à un client non valide")
return False, " Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à un client non valide ", False
# Mise à jour de l'inscription avec l'_id du client
inscription_no_client_valide_no_locked_data = MYSY_GV.dbname['partner_client'].find_one(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email']),
'valide': "1",
'locked': '0'})
MYSY_GV.dbname['inscription'].update_one({'partner_owner_recid': str(my_partner['recid']),
'_id': ObjectId(local_inscription_no_client['_id'])},
{'$set': {
'facture_client_rattachement_id': str(
inscription_no_client_valide_no_locked_data['_id']),
'client_rattachement_id': str(
inscription_no_client_valide_no_locked_data['_id']),
}
})
# Si il n'y a pas de client associé à cette adresse email, alors on crée le client
if (is_inscription_no_client_exist == 0):
new_client_contact_data = {}
new_client_data = {}
new_partner_all_list = ['token', "raison_sociale", "nom", "siret", "tva", "email",
"telephone", "website", "comment", "address",
'adr_adresse', 'adr_code_postal', 'adr_ville', 'adr_pays',
'invoice_email', 'invoice_nom', 'invoice_siret',
'invoice_tva', 'invoice_condition_paiement_id', 'invoice_adresse',
'invoice_ville',
'invoice_code_postal', 'invoice_pays', "client_type_id",
'is_fournisseur', 'is_client', 'is_financeur', 'is_client']
# Pre Remplir les champs à vide
for tmp in new_partner_all_list:
new_client_data[str(tmp)] = ""
new_client_data['token'] = diction['token']
new_client_contact_data['token'] = diction['token']
if ("nom" in local_inscription_no_client.keys()):
new_client_data['raison_sociale'] = local_inscription_no_client['nom']
new_client_data['nom'] = local_inscription_no_client['nom']
# Pour le contact
new_client_contact_data['nom'] = local_inscription_no_client['nom']
if ("prenom" in local_inscription_no_client.keys()):
# Pour le contact
new_client_contact_data['prenom'] = local_inscription_no_client['prenom']
if ("civilite" in local_inscription_no_client.keys()):
# Pour le contact
new_client_contact_data['civilite'] = str(local_inscription_no_client['civilite']).lower()
if ("email" in local_inscription_no_client.keys()):
new_client_data['email'] = local_inscription_no_client['email']
new_client_data['invoice_email'] = local_inscription_no_client['email']
# Pour le contact
new_client_contact_data['email'] = local_inscription_no_client['email']
if ("telephone" in local_inscription_no_client.keys()):
new_client_data['telephone'] = local_inscription_no_client['telephone']
# Pour le contact
new_client_contact_data['telephone'] = local_inscription_no_client['telephone']
if ("adresse" in local_inscription_no_client.keys()):
new_client_data['adr_adresse'] = local_inscription_no_client['adresse']
new_client_data['invoice_adresse'] = local_inscription_no_client['adresse']
# Pour le contact
new_client_contact_data['adr_adresse'] = local_inscription_no_client['adresse']
if ("code_postal" in local_inscription_no_client.keys()):
new_client_data['adr_code_postal'] = local_inscription_no_client['code_postal']
new_client_data['invoice_code_postal'] = local_inscription_no_client['code_postal']
# Pour le contact
new_client_contact_data['adr_code_postal'] = local_inscription_no_client['code_postal']
if ("ville" in local_inscription_no_client.keys()):
new_client_data['adr_ville'] = local_inscription_no_client['ville']
new_client_data['invoice_ville'] = local_inscription_no_client['ville']
# Pour le contact
new_client_contact_data['adr_ville'] = local_inscription_no_client['ville']
if ("pays" in local_inscription_no_client.keys()):
new_client_data['adr_pays'] = local_inscription_no_client['pays']
new_client_data['invoice_pays'] = local_inscription_no_client['pays']
# Pour le contact
new_client_contact_data['adr_pays'] = local_inscription_no_client['pays']
new_client_data['is_client'] = "1"
new_client_data['is_company'] = "0"
new_client_status, new_client_retval = partner_client.Add_Partner_Client(new_client_data)
if (new_client_status is False):
mycommon.myprint(" Facturation : Impossible de créer un client associé à l'adresse email : " + str(
local_inscription_no_client['email']) + " ")
return False, " Facturation : Impossible de créer un client associé à l'adresse email : " + str(
local_inscription_no_client['email']) + " ", False
inscription_no_client_valide_no_locked_data = MYSY_GV.dbname['partner_client'].find_one(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email']),
'valide': "1",
'locked': '0'})
# Créer le contact de communication du client
new_client_contact_data['include_com'] = "1"
new_client_contact_data['related_collection'] = "partner_client"
new_client_contact_data['related_collection_owner_id'] = str(
inscription_no_client_valide_no_locked_data['_id'])
local_add_contact_status, local_add_contact_retval = Contact.Add_Contact(new_client_contact_data)
if (local_add_contact_status is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " WARNING : Impossible de créer le contact " + str(
local_add_contact_retval))
# Mise à jour de l'inscription avec l'_id du client
MYSY_GV.dbname['inscription'].update_one({'partner_owner_recid': str(my_partner['recid']),
'_id': ObjectId(local_inscription_no_client['_id'])},
{'$set':
{
'facture_client_rattachement_id': str(
inscription_no_client_valide_no_locked_data[
'_id']),
'client_rattachement_id': str(
inscription_no_client_valide_no_locked_data['_id'])
}
})
# Sauvegarde des fichiers joints depuis le front
tab_saved_file_full_path = []
for file in tab_files:
status, saved_file_full_path = mycommon.Upload_Save_PDF_IMG_File(file, Folder)
if (status is False):
mycommon.myprint("Impossible de récupérer correctement le fichier à importer")
return False, "Impossible de récupérer correctement le fichier à importer", False
tab_saved_file_full_path.append(saved_file_full_path)
print(" #### tab_saved_file_full_path = ", tab_saved_file_full_path)
# Recupération des données du modèle de document
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'_id': ObjectId(str(diction['courrier_template_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
)
tab_local_invoice_ref_interne = []
# Traitement pour les facture : liste_client_facturation_rattachement_id
for single_client in liste_client_facturation_rattachement_id:
print(" Traitement du client_id = ", single_client)
# Recuperation des contacts de communication du client
local_diction = {}
local_diction['token'] = diction['token']
local_diction['_id'] = str(single_client)
print(" ##### local_diction = ", local_diction)
local_status, partner_client_contact_communication = partner_client.Get_Partner_Client_Communication_Contact(
local_diction)
if (local_status is False):
mycommon.myprint(" Impossible de récupérer les contacts de communication du client ")
return False, " Impossible de récupérer les contacts de communication du client ", False
print(" ### partner_client_contact_communication = ", partner_client_contact_communication)
tab_local_email_production = []
for tmp in partner_client_contact_communication:
tmp_JSON = ast.literal_eval(tmp)
if ("email" in tmp_JSON.keys()):
tab_local_email_production.append(str(tmp_JSON["email"]))
list_local_email_production = ",".join(tab_local_email_production)
new_diction_client = {}
new_diction_client['partner_client_id'] = single_client
new_diction_client['token'] = diction['token']
new_diction_client['courrier_template_id'] = diction['courrier_template_id']
new_diction_client['email_test'] = diction['email_test']
new_diction_client['email_production'] = str(list_local_email_production)
new_diction_client['session_id'] = diction['session_id']
print(" ##### new_diction_client 0102 = ", new_diction_client)
# Creation de la facture du client
diction_invoice = {}
diction_invoice['token'] = diction['token']
diction_invoice['partner_client_id'] = single_client
diction_invoice['session_id'] = diction['session_id']
diction_invoice['tab_inscription_ids'] = tab_my_inscription_ids_Object
print(" ##### liste_client_facturation_rattachement_id : diction_invoice 0202 icici = ", diction_invoice)
local_create_invoice_status, local_create_invoice_retval, local_invoice_ref_interne = Invoice_Partner_From_Session_By_Inscription_Id(
diction_invoice)
if (local_create_invoice_status is False):
return local_create_invoice_status, local_create_invoice_retval, False
"""
Mettre à jour les lignes associées à ce client pour dire que la ligne est facturé
"""
now = str(datetime.now())
update_data = {}
update_data['invoiced'] = "1"
update_data['invoiced_ref'] = str(local_invoice_ref_interne)
update_data['invoiced_date'] = now
update_data['date_update'] = now
update_data['update_by'] = str(my_partner['_id'])
update = MYSY_GV.dbname['inscription'].update_many({'partner_owner_recid': str(my_partner['recid']),
'session_id': diction['session_id'],
'facture_client_rattachement_id': str(single_client),
"_id": {'$in': tab_my_inscription_ids_Object},
},
{'$set': update_data})
tab_local_invoice_ref_interne.append(str(local_invoice_ref_interne))
# Traitement pour les facture : liste_client_client_rattachement_id
for single_client in liste_client_client_rattachement_id:
print(" Traitement du client_id = ", single_client)
# Recuperation des contacts de communication du client
local_diction = {}
local_diction['token'] = diction['token']
local_diction['_id'] = str(single_client)
print(" ##### local_diction = ", local_diction)
local_status, partner_client_contact_communication = partner_client.Get_Partner_Client_Communication_Contact(
local_diction)
if (local_status is False):
mycommon.myprint(" Impossible de récupérer les contacts de communication du client ")
return False, " Impossible de récupérer les contacts de communication du client ", False
print(" ### partner_client_contact_communication = ", partner_client_contact_communication)
tab_local_email_production = []
for tmp in partner_client_contact_communication:
tmp_JSON = ast.literal_eval(tmp)
if ("email" in tmp_JSON.keys()):
tab_local_email_production.append(str(tmp_JSON["email"]))
list_local_email_production = ",".join(tab_local_email_production)
new_diction_client = {}
new_diction_client['partner_client_id'] = single_client
new_diction_client['token'] = diction['token']
new_diction_client['courrier_template_id'] = diction['courrier_template_id']
new_diction_client['email_test'] = diction['email_test']
new_diction_client['email_production'] = str(list_local_email_production)
new_diction_client['session_id'] = diction['session_id']
print(" ##### new_diction_client 0102 = ", new_diction_client)
# Creation de la facture du client
diction_invoice = {}
diction_invoice['token'] = diction['token']
diction_invoice['partner_client_id'] = single_client
diction_invoice['session_id'] = diction['session_id']
diction_invoice['tab_inscription_ids'] = tab_my_inscription_ids_Object
print(" ##### liste_client_client_rattachement_id : diction_invoice 0202 icici = ", diction_invoice)
local_create_invoice_status, local_create_invoice_retval, local_invoice_ref_interne = Invoice_Partner_From_Session_By_Inscription_Id(
diction_invoice)
if (local_create_invoice_status is False):
return local_create_invoice_status, local_create_invoice_retval, False
"""
Mettre à jour les lignes associées à ce client pour dire que la ligne est facturé
"""
now = str(datetime.now())
update_data = {}
update_data['invoiced'] = "1"
update_data['invoiced_ref'] = str(local_invoice_ref_interne)
update_data['invoiced_date'] = now
update_data['date_update'] = now
update_data['update_by'] = str(my_partner['_id'])
update = MYSY_GV.dbname['inscription'].update_many({'partner_owner_recid': str(my_partner['recid']),
'session_id': diction['session_id'],
'facture_client_rattachement_id': str(
single_client),
"_id": {'$in': tab_my_inscription_ids_Object},
},
{'$set': update_data})
tab_local_invoice_ref_interne.append(str(local_invoice_ref_interne))
"""
07/03/20204 : mettre un statut de facturation sur la session afin de voir
tout de suite quel session est entièrement facturée ou partiellement.
regles :
Si toutes les inscription associées à une session sont facturée ==> invoiced_statut de la session = 2
Si au moins une inscription associée à une session est facturé ==> invoiced_statut de la session = 1
Si non invoiced_statut de la session =0
"""
nb_inscription_facture = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'invoiced': '1'})
nb_inscription_non_facture = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'invoiced': {'$ne': '1'}})
nb_inscription_valide = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'status': '1'})
invoiced_statut = "0"
if (nb_inscription_facture == nb_inscription_valide):
# toutes les inscription valides ont été facturée
invoiced_statut = "2"
elif (nb_inscription_facture > 0):
# Au moins une ligne a été facturée
invoiced_statut = "1"
# Mise à jour du statut de facturation de la session
MYSY_GV.dbname['session_formation'].update_one({'partner_owner_recid': my_partner['recid'],
'valide': '1',
'_id': ObjectId(str(diction['session_id']))
},
{'$set': {'invoiced_statut': invoiced_statut}})
# Creation de l'historique dans les action 'courrier_template_tracking_history'
local_qry = {'partner_owner_recid': str(my_partner['recid']), 'session_id': str(diction['session_id']),
'invoiced_ref': {'$in': tab_local_invoice_ref_interne}}
# print(" ### local_qry = ", local_qry)
for val in MYSY_GV.dbname['inscription'].find({'partner_owner_recid': str(my_partner['recid']),
'session_id': str(diction['session_id']),
'invoiced_ref': {'$in': tab_local_invoice_ref_interne}}):
ref_facture = ""
if ("invoiced_ref" in val.keys()):
ref_facture = val['invoiced_ref']
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(
my_partner, "FACTURATION_SESSION", str(diction['session_id']), 'inscription',
str(val['_id']),
str(diction['courrier_template_id']),
"Facture : " + str(ref_facture)
)
if (local_status is False):
mycommon.myprint(" WARNING : Impossible de logguer l'historique l'inscription_id : " + str(val['_id']))
return_message = " La session a été correctement facturée.\nListe des factures : "
for tmp in tab_local_invoice_ref_interne:
return_message += "\n - " + str(tmp)
return True, str(return_message), tab_local_invoice_ref_interne
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de créer et d'envoyer les factures par email ", False
"""
Sauvegarde fonction avant modif
"""
def Prepare_and_Send_Facture_From_Session_By_Inscription_Id_SAVE_ORIG(tab_files, Folder, diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'email_test', 'email_production',
'tab_inscription_ids']
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", False
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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, False
my_inscription_ids = ""
tab_my_inscription_ids = []
tab_my_inscription_ids_Object = []
if ("tab_inscription_ids" in diction.keys()):
if diction['tab_inscription_ids']:
my_inscription_ids = diction['tab_inscription_ids']
tab_my_inscription_ids = str(my_inscription_ids).split(",")
print(" ### tab_my_inscription_ids = ", tab_my_inscription_ids)
for my_inscription_id in tab_my_inscription_ids:
tmp_count = MYSY_GV.dbname['inscription'].count_documents({'session_id': str(diction['session_id']),
'_id': ObjectId(str(my_inscription_id)),
'partner_owner_recid': str(
my_partner['recid']),
"invoiced": {'$ne': '1'},})
if (tmp_count != 1):
mycommon.myprint(str(inspect.stack()[0][3]) + " L'indentifiant de l'inscription " + str(
my_inscription_id) + " est invalide ")
return False, " L'indentifiant de l'inscription " + str(my_inscription_id) + " est invalide "
tab_my_inscription_ids_Object.append(ObjectId(str(my_inscription_id)))
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide ", False
# Verifier qu'il ya bien des inscriptions valides dans la session pour le client
liste_client_rattachement_id = MYSY_GV.dbname['inscription'].distinct("facture_client_rattachement_id",
{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(
my_partner['recid']),
"facture_client_rattachement_id": {'$ne': ''},
"invoiced": {'$ne': '1'},
"_id": {
'$in': tab_my_inscription_ids_Object},
}
)
print(" ### la liste des liste_client_rattachement_id (client à facturer) : AVANT GESTION inscriptions SANS CLIENT = ", liste_client_rattachement_id)
"""
Gestion des inscriptions n'ayant pas de client à facturer ID
"""
liste_inscription_no_client = MYSY_GV.dbname['inscription'].find(
{"$or": [{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
"facture_client_rattachement_id": '',
"invoiced": {'$ne': '1'},
"_id": {'$in': tab_my_inscription_ids_Object},
},
{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'facture_client_rattachement_id': {'$exists': False},
"invoiced": {'$ne': '1'},
"_id": {'$in': tab_my_inscription_ids_Object},
}]
}
)
# CONTROLE : Verification des data client (si tous les clients 'particuliers' sont ok
for local_inscription_no_client in liste_inscription_no_client:
print(" ### List des inscrit n'ayant pas de 'client_id': ", local_inscription_no_client)
"""
- Verifier s'il y a un client avec la même adresse email,
si non, créer le client
"""
is_inscription_no_client_exist = MYSY_GV.dbname['partner_client'].count_documents(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email'])})
# S'il ya plusieurs clients avec la meme adresse email, alors il y a un bin's
if (is_inscription_no_client_exist > 1):
mycommon.myprint(" Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à plusieurs clients")
return False, " Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à plusieurs clients ", False
# Si le client existe, verifier qu'il est valide et pas locké
if (is_inscription_no_client_exist == 1):
is_inscription_no_client_valide_no_locked = MYSY_GV.dbname['partner_client'].count_documents(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email']),
'valide': "1",
'locked': '0'})
if (is_inscription_no_client_valide_no_locked == 0):
mycommon.myprint(" Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à un client non valide")
return False, " Facturation : L'adresse email : " + str(
local_inscription_no_client['email']) + " correspond à un client non valide ", False
# Mise à jour de l'inscription avec l'_id du nouveau client pour les champs : client_rattachement_id et facture_client_rattachement_id
inscription_no_client_valide_no_locked_data = MYSY_GV.dbname['partner_client'].find_one(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email']),
'valide': "1",
'locked': '0'})
MYSY_GV.dbname['inscription'].update_one({'partner_owner_recid': str(my_partner['recid']),
'_id': ObjectId(local_inscription_no_client['_id'])},
{'$set': {'client_rattachement_id': str(
inscription_no_client_valide_no_locked_data['_id']),
'facture_client_rattachement_id': str(
inscription_no_client_valide_no_locked_data['_id'])
},
})
"""
/!\ 23/07/2024 : Ajouter ce client dans la table : "liste_client_rattachement_id'.
En fait, vu que la ligne d'inscription a maintenant un client_rattachement_id et facture_client_rattachement_id
"""
liste_client_rattachement_id.append(str(inscription_no_client_valide_no_locked_data['_id']))
# Si il n'y a pas de client associé à cette adresse email, alors on crée le client
elif (is_inscription_no_client_exist == 0):
new_client_contact_data = {}
new_client_data = {}
new_partner_all_list = ['token', "raison_sociale", "nom", "siret", "tva", "email",
"telephone", "website", "comment", "address",
'adr_adresse', 'adr_code_postal', 'adr_ville', 'adr_pays',
'invoice_email', 'invoice_nom', 'invoice_siret',
'invoice_tva', 'invoice_condition_paiement_id', 'invoice_adresse',
'invoice_ville',
'invoice_code_postal', 'invoice_pays', "client_type_id",
'is_fournisseur', 'is_client', 'is_financeur', 'is_client']
# Pre Remplir les champs à vide
for tmp in new_partner_all_list:
new_client_data[str(tmp)] = ""
new_client_data['token'] = diction['token']
new_client_contact_data['token'] = diction['token']
if ("nom" in local_inscription_no_client.keys()):
new_client_data['raison_sociale'] = local_inscription_no_client['nom']
new_client_data['nom'] = local_inscription_no_client['nom']
# Pour le contact
new_client_contact_data['nom'] = local_inscription_no_client['nom']
if ("prenom" in local_inscription_no_client.keys()):
# Pour le contact
new_client_contact_data['prenom'] = local_inscription_no_client['prenom']
if ("civilite" in local_inscription_no_client.keys()):
# Pour le contact
new_client_contact_data['civilite'] = str(local_inscription_no_client['civilite']).lower()
if ("email" in local_inscription_no_client.keys()):
new_client_data['email'] = local_inscription_no_client['email']
new_client_data['invoice_email'] = local_inscription_no_client['email']
# Pour le contact
new_client_contact_data['email'] = local_inscription_no_client['email']
if ("telephone" in local_inscription_no_client.keys()):
new_client_data['telephone'] = local_inscription_no_client['telephone']
# Pour le contact
new_client_contact_data['telephone'] = local_inscription_no_client['telephone']
if ("adresse" in local_inscription_no_client.keys()):
new_client_data['adr_adresse'] = local_inscription_no_client['adresse']
new_client_data['invoice_adresse'] = local_inscription_no_client['adresse']
# Pour le contact
new_client_contact_data['adr_adresse'] = local_inscription_no_client['adresse']
if ("code_postal" in local_inscription_no_client.keys()):
new_client_data['adr_code_postal'] = local_inscription_no_client['code_postal']
new_client_data['invoice_code_postal'] = local_inscription_no_client['code_postal']
# Pour le contact
new_client_contact_data['adr_code_postal'] = local_inscription_no_client['code_postal']
if ("ville" in local_inscription_no_client.keys()):
new_client_data['adr_ville'] = local_inscription_no_client['ville']
new_client_data['invoice_ville'] = local_inscription_no_client['ville']
# Pour le contact
new_client_contact_data['adr_ville'] = local_inscription_no_client['ville']
if ("pays" in local_inscription_no_client.keys()):
new_client_data['adr_pays'] = local_inscription_no_client['pays']
new_client_data['invoice_pays'] = local_inscription_no_client['pays']
# Pour le contact
new_client_contact_data['adr_pays'] = local_inscription_no_client['pays']
new_client_data['is_client'] = "1"
new_client_data['is_company'] = "0"
new_client_status, new_client_retval = partner_client.Add_Partner_Client(new_client_data)
if (new_client_status is False):
mycommon.myprint(" Facturation : Impossible de créer un client associé à l'adresse email : " + str(
local_inscription_no_client['email']) + " ")
return False, " Facturation : Impossible de créer un client associé à l'adresse email : " + str(
local_inscription_no_client['email']) + " ", False
inscription_no_client_valide_no_locked_data = MYSY_GV.dbname['partner_client'].find_one(
{'partner_recid': str(my_partner['recid']),
'email': str(local_inscription_no_client['email']),
'valide': "1",
'locked': '0'})
# Créer le contact de communication du client
new_client_contact_data['include_com'] = "1"
new_client_contact_data['related_collection'] = "partner_client"
new_client_contact_data['related_collection_owner_id'] = str(
inscription_no_client_valide_no_locked_data['_id'])
local_add_contact_status, local_add_contact_retval = Contact.Add_Contact(new_client_contact_data)
if (local_add_contact_status is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " WARNING : Impossible de créer le contact " + str(
local_add_contact_retval))
# Mise à jour de l'inscription avec l'_id du nouveau client pour les champs : client_rattachement_id et facture_client_rattachement_id
MYSY_GV.dbname['inscription'].update_one({'partner_owner_recid': str(my_partner['recid']),
'_id': ObjectId(local_inscription_no_client['_id'])},
{'$set': {'client_rattachement_id': str(
inscription_no_client_valide_no_locked_data['_id']),
'facture_client_rattachement_id': str(
inscription_no_client_valide_no_locked_data['_id']),
}})
"""
/!\ 23/07/2024 : Ajouter ce client dans la table : "liste_client_rattachement_id'.
En fait, vu que la ligne d'inscription a maintenant un client_rattachement_id et facture_client_rattachement_id
"""
liste_client_rattachement_id.append(str(inscription_no_client_valide_no_locked_data['_id']))
# Sauvegarde des fichiers joints depuis le front
tab_saved_file_full_path = []
for file in tab_files:
status, saved_file_full_path = mycommon.Upload_Save_PDF_IMG_File(file, Folder)
if (status is False):
mycommon.myprint("Impossible de récupérer correctement le fichier à importer")
return False, "Impossible de récupérer correctement le fichier à importer", False
tab_saved_file_full_path.append(saved_file_full_path)
print(" #### tab_saved_file_full_path = ", tab_saved_file_full_path)
tab_local_invoice_ref_interne = []
"""
/!\ : 23/07/2024 : A présent, toutes les lignes ont un client_rattachement_id et facture_client_rattachement_id
car pour ceux qui n'en avaient pas, la creation a ete faite ci-dessus.
"""
print( " ### la liste des liste_client_rattachement_id (client à facturer) : APRES GESTION inscriptions SANS CLIENT = ",
liste_client_rattachement_id)
# Envoie des factures pour les inscrits AVEC client_id
for single_client in liste_client_rattachement_id:
print(" Traitement du client_id (client à facturer) = ", single_client)
# Recuperation des contacts de communication du client
local_diction = {}
local_diction['token'] = diction['token']
local_diction['_id'] = str(single_client)
print(" ##### local_diction = ", local_diction)
local_status, partner_client_contact_communication = partner_client.Get_Partner_Client_Communication_Contact(
local_diction)
if (local_status is False):
mycommon.myprint(" Impossible de récupérer les contacts de communication du client ")
return False, " Impossible de récupérer les contacts de communication du client ", False
print(" ### partner_client_contact_communication = ", partner_client_contact_communication)
tab_local_email_production = []
for tmp in partner_client_contact_communication:
tmp_JSON = ast.literal_eval(tmp)
if ("email" in tmp_JSON.keys()):
tab_local_email_production.append(str(tmp_JSON["email"]))
list_local_email_production = ",".join(tab_local_email_production)
new_diction_client = {}
new_diction_client['partner_client_id'] = single_client
new_diction_client['token'] = diction['token']
new_diction_client['courrier_template_id'] = diction['courrier_template_id']
new_diction_client['email_test'] = diction['email_test']
new_diction_client['email_production'] = str(list_local_email_production)
new_diction_client['session_id'] = diction['session_id']
print(" ##### new_diction_client 0102 = ", new_diction_client)
# Creation de la facture du client
diction_invoice = {}
diction_invoice['token'] = diction['token']
diction_invoice['partner_client_id'] = single_client
diction_invoice['session_id'] = diction['session_id']
diction_invoice['tab_inscription_ids'] = tab_my_inscription_ids_Object
print(" ##### diction_invoice 0202 tttt = ", diction_invoice)
local_create_invoice_status, local_create_invoice_retval, local_invoice_ref_interne = Invoice_Partner_From_Session_By_Inscription_Id(
diction_invoice)
if (local_create_invoice_status is False):
return local_create_invoice_status, local_create_invoice_retval, False
"""
Mettre à jour les lignes associées à ce client pour dire que la ligne est facturé
"""
now = str(datetime.now())
update_data = {}
update_data['invoiced'] = "1"
update_data['invoiced_ref'] = str(local_invoice_ref_interne)
update_data['invoiced_date'] = now
update_data['date_update'] = now
update_data['update_by'] = str(my_partner['_id'])
update = MYSY_GV.dbname['inscription'].update_many({'partner_owner_recid': str(my_partner['recid']),
'session_id': diction['session_id'],
'facture_client_rattachement_id': str(single_client),
"_id": {'$in': tab_my_inscription_ids_Object},
},
{'$set': update_data})
tab_local_invoice_ref_interne.append(str(local_invoice_ref_interne))
return_message = " La session a été correctement facturée.\nListe des factures : "
for tmp in tab_local_invoice_ref_interne:
return_message += "\n - " + str(tmp)
return True, str(return_message), tab_local_invoice_ref_interne
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de créer et d'envoyer les factures par email ", False
"""
15/06/2024 - Facturation des inscription avec split
Cette fonction permet de factuer une ligner avec des split
c'est a dire que sur l'inscription, il a été clairement marqué (ajouté)
le champ "'invoice_split': {'split_type': 'percent', 'tab_split': [{'partner_client': '65f05b37c544f77525a30645', 'invoice_part': 40},
{'partner_client': '65f05b37c544f77525a30645', 'invoice_part': 60}]}"
algo :
On ne fait pas de regroupement dans ce cas de figure.
Pour CHAQUE LIGNE d'inscription, une facture correspondat au pourcentage ou au montant du 'partner_client'
"""
def Prepare_and_Send_SPLITED_Facture_From_Session_By_Inscription_Id(tab_files, Folder, diction):
try:
field_list_obligatoire = ['token', 'session_id', 'courrier_template_id', 'email_test', 'email_production',
'tab_inscription_ids']
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", False
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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, False
my_inscription_ids = ""
tab_my_inscription_ids = []
tab_my_inscription_ids_Object = []
if ("tab_inscription_ids" in diction.keys()):
if diction['tab_inscription_ids']:
my_inscription_ids = diction['tab_inscription_ids']
tab_my_inscription_ids = str(my_inscription_ids).split(",")
print(" ### tab_my_inscription_ids = ", tab_my_inscription_ids)
for my_inscription_id in tab_my_inscription_ids:
tmp_count = MYSY_GV.dbname['inscription'].count_documents({'session_id': str(diction['session_id']),
'_id': ObjectId(str(my_inscription_id)),
'partner_owner_recid': str(
my_partner['recid'])})
if (tmp_count != 1):
mycommon.myprint(str(inspect.stack()[0][3]) + " L'indentifiant de l'inscription " + str(
my_inscription_id) + " est invalide ")
return False, " L'indentifiant de l'inscription " + str(my_inscription_id) + " est invalide "
tab_my_inscription_ids_Object.append(ObjectId(str(my_inscription_id)))
# Verifier que la session est valide
is_session_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide ", False
# Verifier qu'il ya bien des inscriptions valides dans la session pour le client
liste_client_rattachement_id = MYSY_GV.dbname['inscription'].distinct("facture_client_rattachement_id",
{'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(
my_partner['recid']),
"facture_client_rattachement_id": {'$ne': ''},
"invoiced": {'$ne': '1'},
"_id": {
'$in': tab_my_inscription_ids_Object},
}
)
print(" ### la liste des liste_client_rattachement_id (client à facturer) = ", liste_client_rattachement_id)
# Sauvegarde des fichiers joints depuis le front
tab_saved_file_full_path = []
for file in tab_files:
status, saved_file_full_path = mycommon.Upload_Save_PDF_IMG_File(file, Folder)
if (status is False):
mycommon.myprint("Impossible de récupérer correctement le fichier à importer")
return False, "Impossible de récupérer correctement le fichier à importer", False
tab_saved_file_full_path.append(saved_file_full_path)
print(" #### tab_saved_file_full_path = ", tab_saved_file_full_path)
tab_local_invoice_ref_interne = []
# Envoie des factures pour les inscrits AVEC client_id (conventions d'entreprise)
for single_client in liste_client_rattachement_id:
print(" Traitement du client_id (client à facturer) = ", single_client)
# Recuperation des contacts de communication du client
local_diction = {}
local_diction['token'] = diction['token']
local_diction['_id'] = str(single_client)
print(" ##### local_diction = ", local_diction)
local_status, partner_client_contact_communication = partner_client.Get_Partner_Client_Communication_Contact(
local_diction)
if (local_status is False):
mycommon.myprint(" Impossible de récupérer les contacts de communication du client ")
return False, " Impossible de récupérer les contacts de communication du client ", False
print(" ### partner_client_contact_communication = ", partner_client_contact_communication)
tab_local_email_production = []
for tmp in partner_client_contact_communication:
tmp_JSON = ast.literal_eval(tmp)
if ("email" in tmp_JSON.keys()):
tab_local_email_production.append(str(tmp_JSON["email"]))
list_local_email_production = ",".join(tab_local_email_production)
new_diction_client = {}
new_diction_client['partner_client_id'] = single_client
new_diction_client['token'] = diction['token']
new_diction_client['courrier_template_id'] = diction['courrier_template_id']
new_diction_client['email_test'] = diction['email_test']
new_diction_client['email_production'] = str(list_local_email_production)
new_diction_client['session_id'] = diction['session_id']
print(" ##### new_diction_client 0102 = ", new_diction_client)
# Creation de la facture du client
diction_invoice = {}
diction_invoice['token'] = diction['token']
diction_invoice['partner_client_id'] = single_client
diction_invoice['session_id'] = diction['session_id']
diction_invoice['tab_inscription_ids'] = tab_my_inscription_ids_Object
print(" ##### diction_invoice 0202 tttt = ", diction_invoice)
local_create_invoice_status, local_create_invoice_retval, local_invoice_ref_interne = Invoice_Partner_From_Session_By_Inscription_Id(
diction_invoice)
if (local_create_invoice_status is False):
return local_create_invoice_status, local_create_invoice_retval, False
"""
Mettre à jour les lignes associées à ce client pour dire que la ligne est facturé
"""
now = str(datetime.now())
update_data = {}
update_data['invoiced'] = "1"
update_data['invoiced_ref'] = str(local_invoice_ref_interne)
update_data['invoiced_date'] = now
update_data['date_update'] = now
update_data['update_by'] = str(my_partner['_id'])
update = MYSY_GV.dbname['inscription'].update_many({'partner_owner_recid': str(my_partner['recid']),
'session_id': diction['session_id'],
'facture_client_rattachement_id': str(single_client),
"_id": {'$in': tab_my_inscription_ids_Object},
},
{'$set': update_data})
tab_local_invoice_ref_interne.append(str(local_invoice_ref_interne))
"""
07/03/20204 : mettre un statut de facturation sur la session afin de voir
tout de suite quel session est entièrement facturée ou partiellement.
regles :
Si toutes les inscription associées à une session sont facturée ==> invoiced_statut de la session = 2
Si au moins une inscription associée à une session est facturé ==> invoiced_statut de la session = 1
Si non invoiced_statut de la session =0
"""
nb_inscription_facture = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'invoiced': '1'})
nb_inscription_non_facture = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'invoiced': {'$ne': '1'}})
nb_inscription_valide = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'status': '1'})
invoiced_statut = "0"
if (nb_inscription_facture == nb_inscription_valide):
# toutes les inscription valides ont été facturée
invoiced_statut = "2"
elif (nb_inscription_facture > 0):
# Au moins une ligne a été facturée
invoiced_statut = "1"
# Mise à jour du statut de facturation de la session
MYSY_GV.dbname['session_formation'].update_one({'partner_owner_recid': my_partner['recid'],
'valide': '1',
'_id': ObjectId(str(diction['session_id']))
},
{'$set': {'invoiced_statut': invoiced_statut}})
# Creation de l'historique dans les action 'courrier_template_tracking_history'
local_qry = {'partner_owner_recid': str(my_partner['recid']), 'session_id': str(diction['session_id']),
'invoiced_ref': {'$in': tab_local_invoice_ref_interne}}
# print(" ### local_qry = ", local_qry)
"""
for val in MYSY_GV.dbname['inscription'].find({'partner_owner_recid': str(my_partner['recid']),
'session_id': str(diction['session_id']),
'invoiced_ref': {'$in': tab_local_invoice_ref_interne}}):
ref_facture = ""
if ("invoiced_ref" in val.keys()):
ref_facture = val['invoiced_ref']
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(
my_partner, "FACTURATION_SESSION", str(diction['session_id']), 'inscription',
str(val['_id']),
str(diction['courrier_template_id']),
"Facture : " + str(ref_facture)
)
if (local_status is False):
mycommon.myprint(" WARNING : Impossible de logguer l'historique l'inscription_id : " + str(val['_id']))
"""
return_message = " La session a été correctement facturée.\nListe des factures : "
for tmp in tab_local_invoice_ref_interne:
return_message += "\n - " + str(tmp)
return True, str(return_message), tab_local_invoice_ref_interne
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de créer et d'envoyer les factures par email ", False
"""
Creation des factures pour un client avec uniquement la liste des inscriptions concernées.
Ex : je veux facturer que 2 des 5 inscrits d'un client donné.
/!\ : Cette fonction se base sur le champ "facture_client_rattachement_id" de la collection "inscription"
"""
def Invoice_Partner_From_Session_By_Inscription_Id( diction):
try:
field_list_obligatoire = ['token', 'partner_client_id', 'session_id', 'tab_inscription_ids']
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", False
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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, False
# Verifier que la session est valide
is_session_id_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_id_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide ", False
# Verifier que ce client a bien des inscriptions valide pour cette session
nb_valide_inscription_pr_client = MYSY_GV.dbname['inscription'].count_documents(
{'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']}
},
)
if (nb_valide_inscription_pr_client <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Aucune inscription valide pour ce client pour cette session ")
return False, " Aucune inscription valide pour ce client pour cette session ", False
partner_client_id_data = MYSY_GV.dbname['partner_client'].find_one(
{'_id': ObjectId(str(diction['partner_client_id'])),
'valide': '1',
'locked': '0',
'partner_recid': str(my_partner['recid'])})
# Recuperation des données du stagiaire
inscription_data = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'facture_client_rattachement_id':str(diction['partner_client_id']),
'_id':{'$in':diction['tab_inscription_ids']}})
tab_inscrit_partial_data = []
tab_apprenant = []
tab_participant = []
for val in inscription_data:
tab_participant.append(val['_id'])
node = {}
node['inscription_id'] = str(val['_id'])
"""
update du 30/01/2024
si le participant à un apprenant_id, alors on recupere la valeur de l'apprenant id. On doit travailler sur cette dernier.
En general, avant d'envoyer une convocation ou convention, l'inscription est validée et donc le dossier apprenant existe.
Du coup si tout se passe bien, dans cette fonction, on travaillera tjrs avec l'apprenant_id
"""
if ("apprenant_id" in val.keys() and val['apprenant_id']):
tab_apprenant.append(ObjectId(str(val['apprenant_id'])))
node['apprenant_id'] = str(val['apprenant_id'])
else:
node['apprenant_id'] = ""
if( "invoice_split" in val.keys() ):
node['invoice_split'] = val['invoice_split']
else:
node['invoice_split'] = ""
tab_inscrit_partial_data.append(node)
print(" ### tab_inscrit_partial_data = ", tab_inscrit_partial_data)
print(" ### tab_apprenant = ", tab_apprenant)
# Recuperations des info de la session de formation
session_data = MYSY_GV.dbname['session_formation'].find_one({'_id': ObjectId(str(diction['session_id']))})
tab_session = []
tab_session.append(session_data['_id'])
# Recuperation du titre de la formation
class_data = MYSY_GV.dbname['myclass'].find({'internal_url': str(session_data['class_internal_url']),
'valide': '1',
'partner_owner_recid': str(my_partner['recid']),
'locked': '0'})
price_by = "perstagiaire"
if( "perstagiaire" in session_data.keys() ):
price_by = session_data['perstagiaire']
if( price_by not in MYSY_GV.TRAINING_PRICE) :
mycommon.myprint(str(inspect.stack()[0][3]) + " Le prix par " + str(price_by) + " n'est valide. Les valeurs autorisées sont " + str(MYSY_GV.TRAINING_PRICE))
return False, " Le prix par " + str(price_by) + " n'est valide. Les valeurs autorisées sont " + str(MYSY_GV.TRAINING_PRICE) + " ", False
partner_invoice_header_data = {}
list_partner_invoice_header_champ = ['order_header_client_id', 'order_header_ref_interne', 'order_header_email_client', 'order_header_origin', 'order_header_ref_client', 'order_header_vendeur_id',
'order_header_date_cmd', 'order_header_date_expiration', 'order_header_adr_fact_adresse', 'order_header_adr_fact_code_postal', 'order_header_adr_fact_ville', 'order_header_adr_fact_pays',
'order_header_adr_liv_adresse', 'order_header_adr_liv_code_postal', 'order_header_adr_liv_ville', 'order_header_adr_liv_pays', 'valide', 'locked', 'date_update',
'order_header_montant_reduction', 'order_header_tax', 'order_header_tax_amount', 'total_header_hors_taxe_after_header_reduction', 'total_header_hors_taxe_before_header_reduction',
'total_header_toutes_taxes', 'total_lines_hors_taxe_after_lines_reduction', 'total_lines_hors_taxe_before_lines_reduction', 'total_lines_montant_reduction', 'invoice_header_ref_interne',
'invoice_header_type', 'invoice_date', 'update_by']
# PreRemplir les champs
for val in list_partner_invoice_header_champ:
partner_invoice_header_data[str(val)] = ""
partner_invoice_header_data['order_header_client_id'] = str(partner_client_id_data['_id'])
"""
Recuperation des conditions de paiement depuis le client
"""
ction_paiement_code = ""
ction_paiement_desc = ""
ction_paiement_depart = "facture"
ction_paiement_nb_jour = "0"
if( "invoice_condition_paiement_id" in partner_client_id_data.keys() and partner_client_id_data['invoice_condition_paiement_id']):
ction_paiement_data = MYSY_GV.dbname['base_partner_paiement_condition'].find_one({'partner_owner_recid':my_partner['recid'],
'valide':'1',
'locked':'0',
'_id':ObjectId(str(partner_client_id_data['invoice_condition_paiement_id']))})
if( ction_paiement_data and "code" in ction_paiement_data.keys() and ction_paiement_data['code']):
ction_paiement_code = ction_paiement_data['code']
if (ction_paiement_data and "description" in ction_paiement_data.keys() and ction_paiement_data['description']):
ction_paiement_desc = ction_paiement_data['description']
if (ction_paiement_data and "nb_jour" in ction_paiement_data.keys() and ction_paiement_data['nb_jour'] and
"depart" in ction_paiement_data.keys() and ction_paiement_data['depart'] ):
ction_paiement_nb_jour = ction_paiement_data['nb_jour']
ction_paiement_depart = ction_paiement_data['depart']
nb_jour_int = mycommon.tryInt(str(ction_paiement_nb_jour))
today = datetime.today()
date_echance = datetime.today()
if (str(ction_paiement_depart) == "mois"):
days_in_month = lambda dt: monthrange(dt.year, dt.month)[1]
first_day_next_month = today.replace(day=1) + timedelta(days_in_month(today))
date_echance = first_day_next_month + timedelta(days=nb_jour_int)
else:
date_echance = today + timedelta(days=nb_jour_int)
date_echance = date_echance.strftime("%d/%m/%Y")
partner_invoice_header_data['invoice_date_echeance'] = str(date_echance)
partner_invoice_header_data['order_header_condition_paiement_code'] = str(ction_paiement_code)
partner_invoice_header_data['order_header_condition_paiement_description'] = str(ction_paiement_desc)
code_session = ""
if( "code_session" in session_data.keys() ):
code_session = session_data['code_session']
partner_invoice_header_data['order_header_ref_interne'] = "Code_Session_"+str(code_session)
order_header_email_client = ""
if ("email" in partner_client_id_data.keys()):
order_header_email_client = partner_client_id_data['email']
partner_invoice_header_data['order_header_email_client'] = order_header_email_client
order_header_origin = "session_id_"+str(session_data['_id'])
partner_invoice_header_data['order_header_origin'] = order_header_origin
order_header_adr_fact_adresse = ""
if( "invoice_adresse" in partner_client_id_data.keys() ):
order_header_adr_fact_adresse = partner_client_id_data['invoice_adresse']
partner_invoice_header_data['order_header_adr_fact_adresse'] = order_header_adr_fact_adresse
order_header_adr_fact_ville = ""
if ("invoice_ville" in partner_client_id_data.keys()):
order_header_adr_fact_ville = partner_client_id_data['invoice_adresse']
partner_invoice_header_data['order_header_adr_fact_ville'] = order_header_adr_fact_ville
order_header_adr_fact_code_postal = ""
if ("invoice_code_postal" in partner_client_id_data.keys()):
order_header_adr_fact_code_postal = partner_client_id_data['invoice_code_postal']
partner_invoice_header_data['order_header_adr_fact_code_postal'] = order_header_adr_fact_code_postal
order_header_adr_fact_pays = ""
if ("invoice_pays" in partner_client_id_data.keys()):
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_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
order_header_type_financeur_id = ""
if ("type_financeur_id" in partner_client_id_data.keys()):
order_header_type_financeur_id = partner_client_id_data['type_financeur_id']
partner_invoice_header_data['order_header_type_financeur_id'] = order_header_type_financeur_id
order_header_is_financeur = "0"
if ("is_financeur" in partner_client_id_data.keys()):
order_header_is_financeur = partner_client_id_data['is_financeur']
partner_invoice_header_data['order_header_is_financeur'] = order_header_is_financeur
order_header_is_client = "0"
if ("is_client" in partner_client_id_data.keys()):
order_header_is_client = partner_client_id_data['is_client']
partner_invoice_header_data['order_header_is_client'] = order_header_is_client
order_header_is_fournisseur = "0"
if ("is_fournisseur" in partner_client_id_data.keys()):
order_header_is_fournisseur = partner_client_id_data['is_fournisseur']
partner_invoice_header_data['order_header_is_fournisseur'] = order_header_is_fournisseur
order_header_is_company = ""
if ("is_company" in partner_client_id_data.keys()):
order_header_is_company = partner_client_id_data['is_company']
partner_invoice_header_data['order_header_is_company'] = order_header_is_company
order_header_type_pouvoir_public_id = ""
if ("type_pouvoir_public_id" in partner_client_id_data.keys()):
order_header_type_pouvoir_public_id = partner_client_id_data['type_pouvoir_public_id']
partner_invoice_header_data['order_header_type_pouvoir_public_id'] = order_header_type_pouvoir_public_id
order_header_is_include_bpf = ""
if ("is_bpf" in session_data.keys()):
order_header_is_include_bpf = session_data['is_bpf']
partner_invoice_header_data['order_header_is_include_bpf'] = order_header_is_include_bpf
# Calcul du Totol HT sans reduction
total_ht = 0
prix_session = 0
session_price = 0
if( "prix_session" not in session_data.keys() ):
mycommon.myprint(str(inspect.stack()[0][3]) + " Facturation : La session n'a pas de prix valide")
return False, " Facturation : La session n'a pas de prix valide ", False
if( str(session_data['prix_session']).strip() == "" ):
mycommon.myprint(str(inspect.stack()[0][3]) + " Facturation : La session n'a pas de prix valide (2) ")
return False, " Facturation : La session n'a pas de prix valide (2) ", False
prix_session = mycommon.tryFloat(str(session_data['prix_session']))
if( str(price_by).strip() == "persession" ):
total_ht = round(prix_session, 2)
else:
total_ht = round(prix_session * nb_valide_inscription_pr_client, 2)
partner_invoice_header_data['total_header_hors_taxe_before_header_reduction'] = total_ht
# Recupération de la TVA de l'entité qui facture
taux_tva_statuts, taux_tva_retval = partner_base_setup.Get_Given_Partner_Basic_Setup({'token':str(diction['token']), 'config_name':'tva'})
if( taux_tva_statuts is False ):
mycommon.myprint(str(inspect.stack()[0][3]) + " Facturation : Impossible de récupérer le taux de TVA ")
return False, " Facturation : Impossible de récupérer le taux de TVA ", False
tmp = ast.literal_eval(taux_tva_retval[0])
taux_tva_retval = tmp['config_value']
print(" ### taux_tva_retval = ", taux_tva_retval)
tva_status, tva_value = mycommon.IsFloat(str(taux_tva_retval))
if (tva_status is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " Facturation : Le taux de TVA est invalide ")
return False, " Facturation : Le taux de TVA est invalide ", False
partner_invoice_header_data['order_header_tax'] = taux_tva_retval
partner_invoice_header_data['order_header_tax_amount'] = str(round(tva_value * total_ht/100, 2))
partner_invoice_header_data['total_header_toutes_taxes'] = str(round(total_ht + (tva_value * total_ht)/100, 2))
partner_invoice_header_data['invoice_header_type'] = "facture"
# Récuperation de la sequence de l'objet "partner_invoice_header" dans la collection : "mysy_sequence"
retval_sequence_invoice = MYSY_GV.dbname['mysy_sequence'].find_one(
{'partner_invoice_header': 'partner_order_header',
'valide': '1', 'partner_owner_recid': str(
my_partner['recid'])})
if (retval_sequence_invoice is None):
# Il n'y pas de sequence pour le partenaire, on va aller chercher la sequence par defaut
retval_sequence_invoice = MYSY_GV.dbname['mysy_sequence'].find_one(
{'related_mysy_object': 'partner_invoice_header',
'valide': '1', 'partner_owner_recid': 'default'})
if (retval_sequence_invoice is None or "current_val" not in retval_sequence_invoice.keys()):
# Il n'y aucune sequence meme par defaut.
mycommon.myprint(" Facture : Impossible de récupérer la sequence 'retval_sequence_invoice' ")
return False, "Facture : Impossible de récupérer la sequence 'retval_sequence_invoice' ", False
current_seq_value = str(retval_sequence_invoice['current_val'])
new_sequence_value = int(mycommon.tryInt(current_seq_value)) + 1
new_sequance_data_to_update = {'current_val': new_sequence_value}
ret_val2 = MYSY_GV.dbname['mysy_sequence'].find_one_and_update(
{'_id': ObjectId(str(retval_sequence_invoice['_id'])), 'valide': '1'},
{"$set": new_sequance_data_to_update},
return_document=ReturnDocument.AFTER,
upsert=False,
)
invoice_date_time = str(datetime.now().strftime("%d/%m/%Y"))
"""
Verifier qu'il n'y pas une facture du partenaire avec le meme ref interne
"""
is_already_invoice_ref_exist = MYSY_GV.dbname['partner_invoice_header'].count_documents({'partner_invoice_header':str(my_partner['recid']),
'valide':'1',
'invoice_header_ref_interne':str(retval_sequence_invoice['prefixe'] + str(current_seq_value))})
if( is_already_invoice_ref_exist > 0 ):
mycommon.myprint(" Facture : Il existe déjà une facture avec la même ref. interne : "+str(retval_sequence_invoice['prefixe'] + str(current_seq_value)))
return False, " Facture : Il existe déjà une facture avec la même ref. interne : "+str(retval_sequence_invoice['prefixe'] + str(current_seq_value)), False
partner_invoice_header_data['invoice_header_ref_interne'] = retval_sequence_invoice['prefixe'] + str(current_seq_value)
partner_invoice_header_data['invoice_header_type'] = "facture"
partner_invoice_header_data['invoice_date'] = invoice_date_time
partner_invoice_header_data['update_by'] = str(my_partner['_id'])
partner_invoice_header_data['valide'] = "1"
partner_invoice_header_data['locked'] = "0"
partner_invoice_header_data['partner_owner_recid'] = str(my_partner['recid'])
partner_invoice_header_data['date_update'] = str(datetime.now())
print(" #### partner_invoice_header_data = ", partner_invoice_header_data)
inserted_invoice_id = MYSY_GV.dbname['partner_invoice_header'].insert_one(partner_invoice_header_data).inserted_id
if (not inserted_invoice_id):
mycommon.myprint(" Facture : Impossible de créer l'entête de la facture ")
return False, " Facture : Impossible de créer l'entête de la facture ", False
new_invoice_id = inserted_invoice_id
"""
Création des lignes de facture.
Pour memo, dans la collection : partner_invoice_line
order_line_formation = titre formation
order_line_qty = nb participants
order_line_comment = la liste des personnes participans
"""
partner_invoice_line_data = {}
list_partner_invoice_line_champ = ['order_line_formation', 'order_line_qty', 'order_line_prix_unitaire', 'order_line_tax', 'order_line_tax_amount', 'order_line_montant_toutes_taxes',
'order_line_montant_hors_taxes', 'order_line_type_reduction', 'order_line_type_valeur', 'order_line_montant_reduction', 'order_header_ref_interne',
'order_line_comment', 'order_header_id', 'valide', 'locked', 'date_update', 'partner_owner_recid', 'invoice_header_ref_interne', 'invoice_line_type',
'invoice_date', 'invoice_header_id', 'order_line_is_include_bpf']
# PreRemplir les champs
for val in list_partner_invoice_line_champ:
partner_invoice_line_data[str(val)] = ""
nb_participant_du_client = len(tab_apprenant)
nom_prenom_email_participant = ""
for val in tab_apprenant:
local_apprenant = MYSY_GV.dbname['apprenant'].find_one({'_id':ObjectId(val), 'partner_owner_recid':str(my_partner['recid']),
'valide':'1', 'locked':'0'})
local_nom = ""
local_prenom = ""
local_email = ""
if( "nom" in local_apprenant.keys() ):
local_nom = local_apprenant['nom']
if ("prenom" in local_apprenant.keys()):
local_prenom = local_apprenant['prenom']
if ("email" in local_apprenant.keys()):
local_email = local_apprenant['email']
nom_prenom_email_participant += local_nom+" "+local_prenom+" "+local_email+"\n"
partner_invoice_line_data['order_line_formation'] = class_data[0]['internal_url']
partner_invoice_line_data['order_line_qty'] = str(nb_participant_du_client)
partner_invoice_line_data['order_line_prix_unitaire'] = str(prix_session)
partner_invoice_line_data['order_line_montant_hors_taxes'] = str(total_ht)
partner_invoice_line_data['order_line_comment'] = str(nom_prenom_email_participant)
partner_invoice_line_data['invoice_header_id'] = str(inserted_invoice_id)
partner_invoice_line_data['invoice_line_type'] = "facture"
partner_invoice_line_data['invoice_header_ref_interne'] = partner_invoice_header_data['invoice_header_ref_interne']
partner_invoice_line_data['update_by'] = str(my_partner['_id'])
partner_invoice_line_data['valide'] = "1"
partner_invoice_line_data['locked'] = "0"
partner_invoice_line_data['partner_owner_recid'] = str(my_partner['recid'])
order_line_is_include_bpf = ""
if ("is_bpf" in session_data.keys()):
order_line_is_include_bpf = session_data['is_bpf']
partner_invoice_line_data['order_line_is_include_bpf'] = order_line_is_include_bpf
print(" #### partner_invoice_line_data = ", partner_invoice_line_data)
inserted_invoice_id = MYSY_GV.dbname['partner_invoice_line'].insert_one(
partner_invoice_line_data).inserted_id
if (not inserted_invoice_id):
mycommon.myprint(" Facture : Impossible de créer les lignes de la facture "+str(partner_invoice_header_data['invoice_header_ref_interne']))
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_qty'] = "1"
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']
order_line_is_include_bpf = ""
if ("is_bpf" in session_data.keys()):
order_line_is_include_bpf = session_data['is_bpf']
partner_invoice_line_data_detail['order_line_is_include_bpf'] = order_line_is_include_bpf
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é
"""
e_Invoice_Diction = {}
e_Invoice_Diction['token'] = diction['token']
e_Invoice_Diction['invoice_id'] = str(new_invoice_id)
print(" ### e_Invoice_Diction= ", e_Invoice_Diction )
local_E_Invoice_status, local_E_Invoice_retval = Invoice_Create_Secure_E_Document(e_Invoice_Diction)
if( local_E_Invoice_status is False ):
return True, "WARNING : L'email a été correctement envoyé ", str(
partner_invoice_header_data['invoice_header_ref_interne']+"; mais impossible de créer la e-Facture Sécurisée (2).")
return True, "L'email a été correctement envoyé ", str(partner_invoice_header_data['invoice_header_ref_interne'])
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 d'envoyer la convention par email ", False
"""
15/06/2024 :
Gestion des factures splitées sur une inscription :
Cette fonction prend une inscription_id,
On créer les differentes factures avec les montants ou pourcentage de client designé dans le split
Ici, on ne fait pas de regroupement
"""
def Invoice_Splited_Partner_From_Session_By_Inscription_Id( diction):
try:
field_list_obligatoire = ['token', 'session_id', 'inscription_id']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La valeur '" + val + "' n'est pas presente dans liste ")
return False, " La valeur '" + val + "' n'est pas presente dans liste", False
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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, False
# Verifier que la session est valide
is_session_id_valide = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_session_id_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide ", False
"""
Verfifer que l'inscription est valide
"""
inscription_valide = MYSY_GV.dbname['inscription'].count_documents({'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'},
})
if (inscription_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de l'inscription est invalide ")
return False, " L'identifiant de l'inscription est invalide ", False
# Recuperation des données du stagiaire
inscription_data = MYSY_GV.dbname['inscription'].find_one({'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'},
})
# Verifier que le mode d'eclatement de la factue est soit : percent, soit fixe
invoice_split = ""
split_type = ""
if ("invoice_split" in inscription_data.keys() and inscription_data['invoice_split'] and
"split_type" in inscription_data['invoice_split'].keys() and inscription_data['invoice_split']['split_type']):
if (str(inscription_data['invoice_split']['split_type']).lower() not in ['percent', 'fixe']):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Le mode de partage de la facture doit être 'percent' ou 'fixe' ")
return False, " Le mode de partage de la facture doit être 'percent' ou 'fixe' ", False
split_type = str(inscription_data['invoice_split']['split_type'])
if ("invoice_split" in inscription_data.keys() and inscription_data['invoice_split'] and
"tab_split" in inscription_data['invoice_split'].keys() and inscription_data['invoice_split']['tab_split']):
invoice_split = inscription_data['invoice_split']
for tmp in inscription_data['invoice_split']['tab_split']:
if ("invoice_part" in tmp.keys()):
is_float_status, is_float_retaval = mycommon.IsFloat(str(tmp['invoice_part']))
if (is_float_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La valeur de partage de la facture n'est pas un nombre decimal ")
return False, " La valeur de partage de la facture n'est pas un nombre decimal ", False
elif (is_float_retaval < 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La valeur de partage de la facture est inférieure à 0 ")
return False, " La valeur de partage de la facture est inférieure à 0 ", False
# Créer une facture pour chaque client dans le split
print(" ### pour l'inscription = ", str(diction['inscription_id']) )
tab_invoice = []
tab_date_invoice = []
for one_tab_split in invoice_split['tab_split'] :
print(" ### one_tab_split = ", one_tab_split)
print(" ### split_type = ", split_type)
print(" ### invoice_part = ", one_tab_split['invoice_part'])
split_invoice_part = one_tab_split['invoice_part']
partner_client_id_data = MYSY_GV.dbname['partner_client'].find_one(
{'_id': ObjectId(str(one_tab_split['partner_client'])),
'valide': '1',
'locked': '0',
'partner_recid': str(my_partner['recid'])})
tab_inscrit_partial_data = []
tab_apprenant = []
tab_participant = []
"""
update du 30/01/2024
si le participant à un apprenant_id, alors on recupere la valeur de l'apprenant id. On doit travailler sur cette dernier.
En general, avant d'envoyer une convocation ou convention, l'inscription est validée et donc le dossier apprenant existe.
Du coup si tout se passe bien, dans cette fonction, on travaillera tjrs avec l'apprenant_id
"""
if ("apprenant_id" in inscription_data.keys() and inscription_data['apprenant_id']):
tab_apprenant.append(ObjectId(str(inscription_data['apprenant_id'])))
print(" ### tab_apprenant = ", tab_apprenant)
# Recuperations des info de la session de formation
session_data = MYSY_GV.dbname['session_formation'].find_one({'_id': ObjectId(str(diction['session_id']))})
tab_session = []
tab_session.append(session_data['_id'])
# Recuperation du titre de la formation
class_data = MYSY_GV.dbname['myclass'].find({'internal_url': str(session_data['class_internal_url']),
'valide': '1',
'partner_owner_recid': str(my_partner['recid']),
'locked': '0'})
price_by = "perstagiaire"
if( "perstagiaire" in session_data.keys() ):
price_by = session_data['perstagiaire']
if( price_by not in MYSY_GV.TRAINING_PRICE) :
mycommon.myprint(str(inspect.stack()[0][3]) + " Le prix par " + str(price_by) + " n'est valide. Les valeurs autorisées sont " + str(MYSY_GV.TRAINING_PRICE))
return False, " Le prix par " + str(price_by) + " n'est valide. Les valeurs autorisées sont " + str(MYSY_GV.TRAINING_PRICE) + " ", False
partner_invoice_header_data = {}
list_partner_invoice_header_champ = ['order_header_client_id', 'order_header_ref_interne', 'order_header_email_client', 'order_header_origin', 'order_header_ref_client', 'order_header_vendeur_id',
'order_header_date_cmd', 'order_header_date_expiration', 'order_header_adr_fact_adresse', 'order_header_adr_fact_code_postal', 'order_header_adr_fact_ville', 'order_header_adr_fact_pays',
'order_header_adr_liv_adresse', 'order_header_adr_liv_code_postal', 'order_header_adr_liv_ville', 'order_header_adr_liv_pays', 'valide', 'locked', 'date_update',
'order_header_montant_reduction', 'order_header_tax', 'order_header_tax_amount', 'total_header_hors_taxe_after_header_reduction', 'total_header_hors_taxe_before_header_reduction',
'total_header_toutes_taxes', 'total_lines_hors_taxe_after_lines_reduction', 'total_lines_hors_taxe_before_lines_reduction', 'total_lines_montant_reduction', 'invoice_header_ref_interne',
'invoice_header_type', 'invoice_date', 'update_by']
# PreRemplir les champs
for val in list_partner_invoice_header_champ:
partner_invoice_header_data[str(val)] = ""
partner_invoice_header_data['order_header_client_id'] = str(partner_client_id_data['_id'])
"""
Recuperation des conditions de paiement depuis le client
"""
ction_paiement_code = ""
ction_paiement_desc = ""
ction_paiement_depart = "facture"
ction_paiement_nb_jour = "0"
if( "invoice_condition_paiement_id" in partner_client_id_data.keys() and partner_client_id_data['invoice_condition_paiement_id']):
ction_paiement_data = MYSY_GV.dbname['base_partner_paiement_condition'].find_one({'partner_owner_recid':my_partner['recid'],
'valide':'1',
'locked':'0',
'_id':ObjectId(str(partner_client_id_data['invoice_condition_paiement_id']))})
if( ction_paiement_data and "code" in ction_paiement_data.keys() and ction_paiement_data['code']):
ction_paiement_code = ction_paiement_data['code']
if (ction_paiement_data and "description" in ction_paiement_data.keys() and ction_paiement_data['description']):
ction_paiement_desc = ction_paiement_data['description']
if (ction_paiement_data and "nb_jour" in ction_paiement_data.keys() and ction_paiement_data['nb_jour'] and
"depart" in ction_paiement_data.keys() and ction_paiement_data['depart'] ):
ction_paiement_nb_jour = ction_paiement_data['nb_jour']
ction_paiement_depart = ction_paiement_data['depart']
nb_jour_int = mycommon.tryInt(str(ction_paiement_nb_jour))
today = datetime.today()
date_echance = datetime.today()
if (str(ction_paiement_depart) == "mois"):
days_in_month = lambda dt: monthrange(dt.year, dt.month)[1]
first_day_next_month = today.replace(day=1) + timedelta(days_in_month(today))
date_echance = first_day_next_month + timedelta(days=nb_jour_int)
else:
date_echance = today + timedelta(days=nb_jour_int)
date_echance = date_echance.strftime("%d/%m/%Y")
partner_invoice_header_data['invoice_date_echeance'] = str(date_echance)
partner_invoice_header_data['order_header_condition_paiement_code'] = str(ction_paiement_code)
partner_invoice_header_data['order_header_condition_paiement_description'] = str(ction_paiement_desc)
code_session = ""
if( "code_session" in session_data.keys() ):
code_session = session_data['code_session']
partner_invoice_header_data['order_header_ref_interne'] = "Code_Session_"+str(code_session)
order_header_email_client = ""
if ("email" in partner_client_id_data.keys()):
order_header_email_client = partner_client_id_data['email']
partner_invoice_header_data['order_header_email_client'] = order_header_email_client
order_header_origin = "session_id_"+str(session_data['_id'])
partner_invoice_header_data['order_header_origin'] = order_header_origin
order_header_adr_fact_adresse = ""
if( "invoice_adresse" in partner_client_id_data.keys() ):
order_header_adr_fact_adresse = partner_client_id_data['invoice_adresse']
partner_invoice_header_data['order_header_adr_fact_adresse'] = order_header_adr_fact_adresse
order_header_adr_fact_ville = ""
if ("invoice_ville" in partner_client_id_data.keys()):
order_header_adr_fact_ville = partner_client_id_data['invoice_adresse']
partner_invoice_header_data['order_header_adr_fact_ville'] = order_header_adr_fact_ville
order_header_adr_fact_code_postal = ""
if ("invoice_code_postal" in partner_client_id_data.keys()):
order_header_adr_fact_code_postal = partner_client_id_data['invoice_code_postal']
partner_invoice_header_data['order_header_adr_fact_code_postal'] = order_header_adr_fact_code_postal
order_header_adr_fact_pays = ""
if ("invoice_pays" in partner_client_id_data.keys()):
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_type_financeur_id = ""
if ("type_financeur_id" in partner_client_id_data.keys()):
order_header_type_financeur_id = partner_client_id_data['type_financeur_id']
partner_invoice_header_data['order_header_type_financeur_id'] = order_header_type_financeur_id
order_header_is_financeur = "0"
if ("is_financeur" in partner_client_id_data.keys()):
order_header_is_financeur = partner_client_id_data['is_financeur']
partner_invoice_header_data['order_header_is_financeur'] = order_header_is_financeur
order_header_is_client = "0"
if ("is_client" in partner_client_id_data.keys()):
order_header_is_client = partner_client_id_data['is_client']
partner_invoice_header_data['order_header_is_client'] = order_header_is_client
order_header_is_fournisseur = "0"
if ("is_fournisseur" in partner_client_id_data.keys()):
order_header_is_fournisseur = partner_client_id_data['is_fournisseur']
partner_invoice_header_data['order_header_is_fournisseur'] = order_header_is_fournisseur
order_header_is_company = ""
if ("is_company" in partner_client_id_data.keys()):
order_header_is_company = partner_client_id_data['is_company']
partner_invoice_header_data['order_header_is_company'] = order_header_is_company
order_header_type_pouvoir_public_id = ""
if ("type_pouvoir_public_id" in partner_client_id_data.keys()):
order_header_type_pouvoir_public_id = partner_client_id_data['type_pouvoir_public_id']
partner_invoice_header_data['order_header_type_pouvoir_public_id'] = order_header_type_pouvoir_public_id
order_header_montant_reduction = "0"
partner_invoice_header_data['order_header_montant_reduction'] = order_header_montant_reduction
# Calcul du Totol HT sans reduction
total_ht = 0
prix_session = 0
session_price = 0
if( "prix_session" not in session_data.keys() ):
mycommon.myprint(str(inspect.stack()[0][3]) + " Facturation : La session n'a pas de prix valide")
return False, " Facturation : La session n'a pas de prix valide ", False
if( str(session_data['prix_session']).strip() == "" ):
mycommon.myprint(str(inspect.stack()[0][3]) + " Facturation : La session n'a pas de prix valide (2) ")
return False, " Facturation : La session n'a pas de prix valide (2) ", False
prix_session = mycommon.tryFloat(str(session_data['prix_session']))
if( str(price_by).strip() == "persession" ):
total_ht = round(prix_session, 2)
else:
total_ht = round(prix_session * 1, 2)
# Recupération de la TVA de l'entité qui facture
taux_tva_statuts, taux_tva_retval = partner_base_setup.Get_Given_Partner_Basic_Setup({'token':str(diction['token']), 'config_name':'tva'})
if( taux_tva_statuts is False ):
mycommon.myprint(str(inspect.stack()[0][3]) + " Facturation : Impossible de récupérer le taux de TVA ")
return False, " Facturation : Impossible de récupérer le taux de TVA ", False
tmp = ast.literal_eval(taux_tva_retval[0])
taux_tva_retval = tmp['config_value']
print(" ### taux_tva_retval = ", taux_tva_retval)
tva_status, tva_value = mycommon.IsFloat(str(taux_tva_retval))
if (tva_status is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " Facturation : Le taux de TVA est invalide ")
return False, " Facturation : Le taux de TVA est invalide ", False
split_invoice_part_FLOAT = mycommon.tryFloat(str(split_invoice_part))
if(split_type == "percent" ):
split_invoice_part_FLOAT = round((split_invoice_part_FLOAT * total_ht)/100, 2)
print(" ### dans la facturartion : split_type = ", str(split_type))
print(" ### dans la facturartion : split_invoice_part_FLOAT = ", str(split_invoice_part_FLOAT))
partner_invoice_header_data['total_header_hors_taxe_before_header_reduction'] = str(split_invoice_part_FLOAT)
partner_invoice_header_data['order_header_tax'] = taux_tva_retval
partner_invoice_header_data['order_header_tax_amount'] = str(round(tva_value * split_invoice_part_FLOAT/100, 2))
partner_invoice_header_data['total_header_toutes_taxes'] = str(round(split_invoice_part_FLOAT + (tva_value * split_invoice_part_FLOAT)/100, 2))
partner_invoice_header_data['invoice_header_type'] = "facture"
text_comment = "Montant total HT = "+str(total_ht)
if( str(split_type) == "percent"):
text_comment = text_comment + "\nType partage facture : POURCENTAGE \nMontant de la facture = "+str(split_invoice_part)
elif (str(split_type) == "fixe"):
text_comment = text_comment + "\nType partage facture : MONTANT \nMontant de la facture = "+str(split_invoice_part)
else :
text_comment = text_comment + "\nType partage facture : INCONNU \nMontant de la facture = "+str(split_invoice_part)
partner_invoice_header_data['order_header_comment'] = text_comment
partner_invoice_header_data['annotation'] = text_comment
partner_invoice_header_data['split_type'] = split_type
partner_invoice_header_data['split_invoice_part'] = str(split_invoice_part)
# Récuperation de la sequence de l'objet "partner_invoice_header" dans la collection : "mysy_sequence"
retval_sequence_invoice = MYSY_GV.dbname['mysy_sequence'].find_one(
{'partner_invoice_header': 'partner_order_header',
'valide': '1', 'partner_owner_recid': str(
my_partner['recid'])})
if (retval_sequence_invoice is None):
# Il n'y pas de sequence pour le partenaire, on va aller chercher la sequence par defaut
retval_sequence_invoice = MYSY_GV.dbname['mysy_sequence'].find_one(
{'related_mysy_object': 'partner_invoice_header',
'valide': '1', 'partner_owner_recid': 'default'})
if (retval_sequence_invoice is None or "current_val" not in retval_sequence_invoice.keys()):
# Il n'y aucune sequence meme par defaut.
mycommon.myprint(" Facture : Impossible de récupérer la sequence 'retval_sequence_invoice' ")
return False, "Facture : Impossible de récupérer la sequence 'retval_sequence_invoice' ", False
current_seq_value = str(retval_sequence_invoice['current_val'])
new_sequence_value = int(mycommon.tryInt(current_seq_value)) + 1
new_sequance_data_to_update = {'current_val': new_sequence_value}
ret_val2 = MYSY_GV.dbname['mysy_sequence'].find_one_and_update(
{'_id': ObjectId(str(retval_sequence_invoice['_id'])), 'valide': '1'},
{"$set": new_sequance_data_to_update},
return_document=ReturnDocument.AFTER,
upsert=False,
)
invoice_date_time = str(datetime.now().strftime("%d/%m/%Y"))
"""
Verifier qu'il n'y pas une facture du partenaire avec le meme ref interne
"""
is_already_invoice_ref_exist = MYSY_GV.dbname['partner_invoice_header'].count_documents({'partner_invoice_header':str(my_partner['recid']),
'valide':'1',
'invoice_header_ref_interne':str(retval_sequence_invoice['prefixe'] + str(current_seq_value))})
if( is_already_invoice_ref_exist > 0 ):
mycommon.myprint(" Facture : Il existe déjà une facture avec la même ref. interne : "+str(retval_sequence_invoice['prefixe'] + str(current_seq_value)))
return False, " Facture : Il existe déjà une facture avec la même ref. interne : "+str(retval_sequence_invoice['prefixe'] + str(current_seq_value)), False
partner_invoice_header_data['invoice_header_ref_interne'] = retval_sequence_invoice['prefixe'] + str(current_seq_value)
partner_invoice_header_data['invoice_header_type'] = "facture"
partner_invoice_header_data['invoice_date'] = invoice_date_time
partner_invoice_header_data['update_by'] = str(my_partner['_id'])
partner_invoice_header_data['valide'] = "1"
partner_invoice_header_data['locked'] = "0"
partner_invoice_header_data['partner_owner_recid'] = str(my_partner['recid'])
partner_invoice_header_data['date_update'] = str(datetime.now())
print(" #### partner_invoice_header_data = ", partner_invoice_header_data)
inserted_invoice_id = MYSY_GV.dbname['partner_invoice_header'].insert_one(partner_invoice_header_data).inserted_id
if (not inserted_invoice_id):
mycommon.myprint(" Facture : Impossible de créer l'entête de la facture ")
return False, " Facture : Impossible de créer l'entête de la facture ", False
new_invoice_id = inserted_invoice_id
"""
Création des lignes de facture.
Pour memo, dans la collection : partner_invoice_line
order_line_formation = titre formation
order_line_qty = nb participants
order_line_comment = la liste des personnes participans
"""
partner_invoice_line_data = {}
list_partner_invoice_line_champ = ['order_line_formation', 'order_line_qty', 'order_line_prix_unitaire', 'order_line_tax', 'order_line_tax_amount', 'order_line_montant_toutes_taxes',
'order_line_montant_hors_taxes', 'order_line_type_reduction', 'order_line_type_valeur', 'order_line_montant_reduction', 'order_header_ref_interne',
'order_line_comment', 'order_header_id', 'valide', 'locked', 'date_update', 'partner_owner_recid', 'invoice_header_ref_interne', 'invoice_line_type',
'invoice_date', 'invoice_header_id']
# PreRemplir les champs
for val in list_partner_invoice_line_champ:
partner_invoice_line_data[str(val)] = ""
nb_participant_du_client = len(tab_apprenant)
nom_prenom_email_participant = ""
for val in tab_apprenant:
local_apprenant = MYSY_GV.dbname['apprenant'].find_one({'_id':ObjectId(val), 'partner_owner_recid':str(my_partner['recid']),
'valide':'1', 'locked':'0'})
local_nom = ""
local_prenom = ""
local_email = ""
if( "nom" in local_apprenant.keys() ):
local_nom = local_apprenant['nom']
if ("prenom" in local_apprenant.keys()):
local_prenom = local_apprenant['prenom']
if ("email" in local_apprenant.keys()):
local_email = local_apprenant['email']
nom_prenom_email_participant += local_nom+" "+local_prenom+" "+local_email+"\n"
partner_invoice_line_data['order_line_formation'] = class_data[0]['internal_url']
partner_invoice_line_data['order_line_qty'] = str(nb_participant_du_client)
partner_invoice_line_data['order_line_prix_unitaire'] = str(prix_session)
partner_invoice_line_data['order_line_montant_hors_taxes'] = str(total_ht)
partner_invoice_line_data['order_line_comment'] = str(nom_prenom_email_participant)
partner_invoice_line_data['invoice_header_id'] = str(inserted_invoice_id)
partner_invoice_line_data['invoice_line_type'] = "facture"
partner_invoice_line_data['invoice_header_ref_interne'] = partner_invoice_header_data['invoice_header_ref_interne']
order_line_is_include_bpf = ""
if ("is_bpf" in session_data.keys()):
order_line_is_include_bpf = session_data['is_bpf']
partner_invoice_line_data['order_line_is_include_bpf'] = order_line_is_include_bpf
partner_invoice_line_data['update_by'] = str(my_partner['_id'])
partner_invoice_line_data['valide'] = "1"
partner_invoice_line_data['locked'] = "0"
partner_invoice_line_data['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'].insert_one(
partner_invoice_line_data).inserted_id
if (not inserted_invoice_id):
mycommon.myprint(" Facture : Impossible de créer les lignes de la facture "+str(partner_invoice_header_data['invoice_header_ref_interne']))
return False, " Facture : Impossible de créer les lignes de la facture "+str(partner_invoice_header_data['invoice_header_ref_interne']), False
tab_invoice.append(partner_invoice_header_data['invoice_header_ref_interne'])
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_qty'] = "1"
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']
order_line_is_include_bpf = ""
if ("is_bpf" in session_data.keys()):
order_line_is_include_bpf = session_data['is_bpf']
partner_invoice_line_data_detail['order_line_is_include_bpf'] = order_line_is_include_bpf
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é
"""
e_Invoice_Diction = {}
e_Invoice_Diction['token'] = diction['token']
e_Invoice_Diction['invoice_id'] = str(new_invoice_id)
print(" ### e_Invoice_Diction= ", e_Invoice_Diction )
local_E_Invoice_status, local_E_Invoice_retval = Invoice_Create_Secure_E_Document(e_Invoice_Diction)
if( local_E_Invoice_status is False ):
return True, "WARNING : L'email a été correctement envoyé ", str(
partner_invoice_header_data['invoice_header_ref_interne']+"; mais impossible de créer la e-Facture Sécurisée (2).")
"""
Mettre à jour les lignes associées à ce client pour dire que la ligne est facturé
"""
update_data = {}
update_data['invoiced'] = "1"
update_data['invoiced_ref'] = ",".join(tab_invoice)
update_data['invoiced_date'] = ",".join(tab_date_invoice)
update_data['date_update'] = now
update_data['update_by'] = str(my_partner['_id'])
update = MYSY_GV.dbname['inscription'].update_one({'partner_owner_recid': str(my_partner['recid']),
'session_id': diction['session_id'],
"_id": ObjectId(str(diction['inscription_id']))
},
{'$set': update_data})
"""
07/03/20204 : mettre un statut de facturation sur la session afin de voir
tout de suite quel session est entièrement facturée ou partiellement.
regles :
Si toutes les inscription associées à une session sont facturée ==> invoiced_statut de la session = 2
Si au moins une inscription associée à une session est facturé ==> invoiced_statut de la session = 1
Si non invoiced_statut de la session =0
"""
nb_inscription_facture = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'invoiced': '1'})
nb_inscription_non_facture = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'invoiced': {'$ne': '1'}})
nb_inscription_valide = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'status': '1'})
invoiced_statut = "0"
if (nb_inscription_facture == nb_inscription_valide):
# toutes les inscription valides ont été facturée
invoiced_statut = "2"
elif (nb_inscription_facture > 0):
# Au moins une ligne a été facturée
invoiced_statut = "1"
# Mise à jour du statut de facturation de la session
MYSY_GV.dbname['session_formation'].update_one({'partner_owner_recid': my_partner['recid'],
'valide': '1',
'_id': ObjectId(str(diction['session_id']))
},
{'$set': {'invoiced_statut': invoiced_statut}})
return True, "L'email a été correctement envoyé ", str(tab_invoice)
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 génrer la facture partagée ", False
"""
05/06/2024 - Gestion des factures securisée
A la creation d'une facture, on va aller créer un document sécurisé dans la collection "e_document_signe"
en utilisant le modelè de courrier pdf
en suite, on ajoute à la collection "invoice_hader", l'_id du document securisé.
Par la suite lorsqu'un utisateur imprime ou reimprime une facture, le va aller regarder
si il y a un document securisé associé, si oui il recuper ce donc, si non, il imprime la facture comme cela se fait aujourd'hui
"""
def Invoice_Create_Secure_E_Document(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'invoice_id']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé")
return False, " Les informations fournies sont incorrectes"
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', 'invoice_id']
"""
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
"""
Verifier que la facture est valide
"""
is_invoice_valide = MYSY_GV.dbname['partner_invoice_header'].count_documents({'_id':ObjectId(str(diction['invoice_id'])),
'valide':'1',
'locked':'0',
'partner_owner_recid':str(my_partner['recid'])})
if( is_invoice_valide != 1):
mycommon.myprint(str(
inspect.stack()[0][3]) + " L'identifiant de la facture est invalide ")
return False, " L'identifiant de la facture est invalide "
Order_header_data = MYSY_GV.dbname['partner_invoice_header'].find_one(
{'_id': ObjectId(str(diction['invoice_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
"""
Recuperer du modèle de document
"""
partner_document_PART_INVOICE_data = MYSY_GV.dbname['courrier_template'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'ref_interne': 'PART_INVOICE',
'type_doc': 'pdf'})
if (partner_document_PART_INVOICE_data is None):
mycommon.myprint(str(
inspect.stack()[0][3]) + " Aucun modèle de courrier 'PART_INVOICE' n'est configuré pour le partenaire ")
return False, " Aucun modèle de courrier 'PART_INVOICE' n'est configuré pour le partenaire "
e_document_id = ""
# Recuperation des données du client
if ("order_header_client_id" in Order_header_data.keys()):
Order_header_client_data = MYSY_GV.dbname['partner_client'].find_one(
{'_id': ObjectId(str(Order_header_data['order_header_client_id'])),
'partner_recid': str(my_partner['recid']), 'valide': '1', 'locked': '0'})
if (Order_header_client_data is None):
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le client est invalide")
return False, " Le client est invalide"
### Ajout des données du client sur l'entete de la commande, exemple : le nom, email, etc
if ("raison_sociale" in Order_header_client_data.keys()):
Order_header_data['client_raison_sociale'] = Order_header_client_data['raison_sociale']
if ("nom" in Order_header_client_data.keys()):
Order_header_data['client_nom'] = Order_header_client_data['nom']
if ("email" in Order_header_client_data.keys()):
Order_header_data['client_email'] = Order_header_client_data['email']
# Ajout d'un parametre pour le data time du jour de l'edition (c'est une data static qui peut servir pour l'horodatage
Order_header_data['current_date_time'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
# Recuperation des details de lignes de : partner_invoice_line
filt_class_partner_recid = {'partner_owner_recid': str(my_partner['recid'])}
filt_order_header_order_id = {'invoice_header_id': str(diction['invoice_id'])}
query = [{'$match': {'$and': [filt_order_header_order_id,
{'partner_owner_recid': str(my_partner['recid'])}]}},
{'$lookup':
{
'from': 'myclass',
'localField': 'order_line_formation',
'foreignField': 'internal_url',
'pipeline': [{'$match': {'$and': [filt_class_partner_recid]}},
{'$project': {'title': 1, 'domaine': 1,
'duration': 1,
'duration_unit': 1,
'external_code': 1,'recyclage_delai':1, 'recyclage_periodicite':1,
'lms_class_code':1}}],
'as': 'myclass_collection'
}
}
]
# print("#### Get_Given_Partner_Order_Lines_From_order_ref_interne : query pip= ", query)
val_tmp = 0
Order_header_lines_data = []
for retval in MYSY_GV.dbname['partner_invoice_line'].aggregate(query):
if ('myclass_collection' in retval.keys() and len(retval['myclass_collection']) > 0):
user = {}
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
user['_id'] = retval['_id']
user['order_line_formation'] = retval['order_line_formation']
user['order_line_qty'] = retval['order_line_qty']
user['order_line_prix_unitaire'] = retval['order_line_prix_unitaire']
user['order_header_id'] = retval['order_header_id']
user['order_header_ref_interne'] = retval['order_header_ref_interne']
user['invoice_header_ref_interne'] = retval['invoice_header_ref_interne']
user['invoice_line_type'] = retval['invoice_line_type']
user['invoice_date'] = retval['invoice_date']
user['valide'] = retval['valide']
user['locked'] = retval['locked']
if ("order_line_montant_reduction" in retval.keys()):
user['order_line_montant_reduction'] = retval['order_line_montant_reduction']
else:
user['order_line_montant_reduction'] = "0"
if ("order_line_montant_toutes_taxes" in retval.keys()):
user['order_line_montant_toutes_taxes'] = retval['order_line_montant_toutes_taxes']
else:
user['order_line_montant_toutes_taxes'] = "0"
if ("order_line_tax" in retval.keys()):
user['order_line_tax'] = retval['order_line_tax']
else:
user['order_line_tax'] = ""
if ("order_line_tax_amount" in retval.keys()):
user['order_line_tax_amount'] = retval['order_line_tax_amount']
else:
user['order_line_tax_amount'] = "0"
if ("order_line_type_reduction" in retval.keys()):
user['order_line_type_reduction'] = retval['order_line_type_reduction']
else:
user['order_line_montant_reduction'] = ""
if ("order_line_type_valeur" in retval.keys()):
user['order_line_type_valeur'] = retval['order_line_type_valeur']
else:
user['order_line_type_valeur'] = "0"
if ("order_line_montant_hors_taxes" in retval.keys()):
user['order_line_montant_hors_taxes'] = retval['order_line_montant_hors_taxes']
else:
user['order_line_montant_hors_taxes'] = "0"
user['date_update'] = retval['date_update']
user['update_by'] = str(my_partner['_id'])
user['partner_owner_recid'] = retval['partner_owner_recid']
if ("order_line_comment" in retval.keys()):
user['order_line_comment'] = retval['order_line_comment']
else:
user['order_line_comment'] = ""
user['title'] = retval['myclass_collection'][0]['title']
user['order_line_formation_external_code'] = retval['myclass_collection'][0]['external_code']
if ("domaine" in retval['myclass_collection'][0].keys()):
user['domaine'] = retval['myclass_collection'][0]['domaine']
else:
user['domaine'] = ""
user['duration'] = retval['myclass_collection'][0]['duration']
user['duration_unit'] = retval['myclass_collection'][0]['duration_unit']
if (str(retval['myclass_collection'][0]['duration_unit']) == "heure"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " h"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "jour"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " j"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "semaine"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " s"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "mois"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " m"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "annee"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " a"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "user_rythme"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " u"
else:
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " ?"
"""
Il s'agit d'un formation, vu qu'on a un lien avec la collection "myclass", on force alors le 'order_line_type_article'
a 'formation'
"""
user['order_line_type_article'] = "formation"
Order_header_lines_data.append(user)
"""
Recuperation des produits et services
"""
query = query = [{'$match': {'$and': [filt_order_header_order_id,
{'partner_owner_recid': str(my_partner['recid'])}]}},
{'$lookup': {
'from': 'partner_produit_service',
"let": {'order_line_formation': "$order_line_formation",
"partner_produit_service_partner_owner_recid": "$partner_owner_recid"
},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$valide", "1"]},
{'$eq': ["$_id", {'$convert': {
'input': "$$order_line_formation",
'to': "objectId",
'onError': {'error': 'true'},
'onNull': {'isnull': 'true'}
}}]},
{'$eq': ["$partner_owner_recid",
'$$partner_produit_service_partner_owner_recid']},
]
}
}
},
],
'as': 'collection_partner_produit_service'
}
},
]
print("#### Get_Given_Partner_Order_Lines_From_order_ref_interne for PRODUCT & SERVICES : query pip= ", query)
for retval in MYSY_GV.dbname['partner_invoice_line'].aggregate(query):
if ('collection_partner_produit_service' in retval.keys() and len(
retval['collection_partner_produit_service']) > 0):
user = {}
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
user['_id'] = retval['_id']
user['order_line_formation'] = retval['order_line_formation']
user['order_line_qty'] = retval['order_line_qty']
user['order_line_prix_unitaire'] = retval['order_line_prix_unitaire']
user['invoice_header_id'] = retval['invoice_header_id']
user['invoice_header_ref_interne'] = retval['invoice_header_ref_interne']
user['invoice_date'] = retval['invoice_date']
user['valide'] = retval['valide']
user['locked'] = retval['locked']
if ("order_line_montant_reduction" in retval.keys()):
user['order_line_montant_reduction'] = retval['order_line_montant_reduction']
else:
user['order_line_montant_reduction'] = "0"
if ("order_line_montant_toutes_taxes" in retval.keys()):
user['order_line_montant_toutes_taxes'] = retval['order_line_montant_toutes_taxes']
else:
user['order_line_montant_toutes_taxes'] = "0"
if ("order_line_tax" in retval.keys()):
user['order_line_tax'] = retval['order_line_tax']
else:
user['order_line_tax'] = ""
if ("order_line_tax_amount" in retval.keys()):
user['order_line_tax_amount'] = retval['order_line_tax_amount']
else:
user['order_line_tax_amount'] = "0"
if ("order_line_type_reduction" in retval.keys()):
user['order_line_type_reduction'] = retval['order_line_type_reduction']
else:
user['order_line_montant_reduction'] = ""
if ("order_line_type_valeur" in retval.keys()):
user['order_line_type_valeur'] = retval['order_line_type_valeur']
else:
user['order_line_type_valeur'] = "0"
if ("order_line_montant_hors_taxes" in retval.keys()):
user['order_line_montant_hors_taxes'] = retval['order_line_montant_hors_taxes']
else:
user['order_line_montant_hors_taxes'] = "0"
user['date_update'] = retval['date_update']
user['update_by'] = str(my_partner['_id'])
user['partner_owner_recid'] = retval['partner_owner_recid']
user['invoice_line_type'] = retval['invoice_line_type']
if ("order_line_comment" in retval.keys()):
user['order_line_comment'] = retval['order_line_comment']
else:
user['order_line_comment'] = ""
user['title'] = retval['collection_partner_produit_service'][0]['nom']
user['order_line_formation_external_code'] = retval['collection_partner_produit_service'][0]['code']
user['domaine'] = ""
user['duration'] = ""
user['duration_unit'] = ""
user['duration_concat'] = ""
"""
Il s'agit d'un produit, vu qu'on a un lien avec la collection "partner_produit_service", on force alors le 'order_line_type_article'
a 'produit'
"""
user['order_line_type_article'] = "produit"
Order_header_lines_data.append(user)
if (len(Order_header_lines_data) <= 0):
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Aucune ligne de détail pour cette facture ")
return False, " Aucune ligne de détail pour cette facture "
# print(" ### Order_header_lines_data = ", Order_header_lines_data)
contenu_doc_Template = jinja2.Template(str(partner_document_PART_INVOICE_data['contenu_doc']))
# sourceHtml = contenu_doc_Template.render(params=Order_header_data)
# print(" ### Order_header_data = ", Order_header_data)
# print(" ### Order_header_lines_data = ", Order_header_lines_data)
"""
Recuperation du dictionnaire des info
"""
tab_client = []
tab_client.append(ObjectId(str(Order_header_client_data['_id'])))
new_diction = {}
new_diction['token'] = diction['token']
new_diction['list_stagiaire_id'] = []
new_diction['list_session_id'] = []
new_diction['list_class_id'] = []
new_diction['list_client_id'] = tab_client
new_diction['list_apprenant_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
company_data = {
"params": convention_dictionnary_data,
}
convention_dictionnary_data['order_header'] = Order_header_data
convention_dictionnary_data['order_lines'] = Order_header_lines_data
# sourceHtml = contenu_doc_Template.render(params=Order_header_data, param_order_lines=Order_header_lines_data, company_data=company_data)
# sourceHtml = contenu_doc_Template.render(params_order_header=Order_header_data, params_order_lines=Order_header_lines_data, params=company_data['params'])
sourceHtml = contenu_doc_Template.render(params=company_data['params'])
orig_file_name = "Partner_Invoice_" + str(Order_header_data['invoice_header_ref_interne']) + ".pdf"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)
# open output file for writing (truncated binary)
resultFile = open(outputFilename, "w+b")
# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
src=sourceHtml, # the HTML to convert
dest=resultFile) # file handle to receive result
# close output file
resultFile.close()
new_model_courrier_with_code_tag = " <div style='width: 100%'> <div style = 'width: 100%; text-align: center;' >" \
" <img style = 'height:60px; width:60px;' src = '{{ params.mysy_qrcode_securite }}' > <br/>" \
" <nav style = 'font-size: 10px; font-style: italic;' > Sécurisé par MySy Training Technology </nav>" \
" <br/> </div> </div>" + \
str(sourceHtml)
new_e_document_diction = {}
new_e_document_diction['token'] = diction['token']
new_e_document_diction['file_name'] = outputFilename
toaddrs = "contact@mysy-training.com"
new_e_document_diction['email_destinataire'] = str(toaddrs)
new_e_document_diction['source_document'] = new_model_courrier_with_code_tag
new_e_document_diction['type'] = "invoice"
new_e_document_diction['related_collection'] = "partner_invoice_header"
new_e_document_diction['related_collection_id'] = str(Order_header_data['_id'])
if ("order_header_ref_interne" in Order_header_data.keys()):
new_e_document_diction['file_cononical_name'] = str(Order_header_data['invoice_header_ref_interne'])
else:
new_e_document_diction['file_cononical_name'] = ""
local_status_e_doc, local_retval_e_doc = E_Sign_Document.Create_E_Invoice(new_e_document_diction)
if (local_status_e_doc is False):
return local_status_e_doc, local_retval_e_doc
e_Invoice_id = str(local_retval_e_doc)
"""
Mettre à jour la facture avec une clé de signature interne car on va pas envoyer
une demande pour créer la signature vu qu'on sur un processus interne
"""
local_signature_key = mycommon.create_user_recid()
retval = MYSY_GV.dbname['e_document_signe'].update_one({'_id':ObjectId(str(e_Invoice_id)),
'valide':'1',
'locked':'0',
'partner_owner_recid':str(my_partner['recid']),
'related_collection':'partner_invoice_header',
'related_collection_id':str(Order_header_data['_id'])},
{'$set':{'statut':'1',
'secret_key_signature':str(local_signature_key)}})
"""
On va auto signer la E-Facture qui a été créée
"""
new_e_document_diction2 = {}
new_e_document_diction2['token'] = str(diction['token'])
new_e_document_diction2['e_doc_id'] = str(e_Invoice_id)
new_e_document_diction2['secret_key_signature'] = str(local_signature_key)
new_e_document_diction2['email_destinataire'] = "contact@mysy-training.com"
new_e_document_diction2['user_ip'] = "127.0.0.1"
#print('laaa new_e_document_diction = ', new_e_document_diction2)
local_status_sign_e_doc, local_retval_sign_e_doc = E_Sign_Document.Create_E_Signature_For_E_Invoice(None, None, new_e_document_diction2)
if( local_status_sign_e_doc is False ):
return local_status_sign_e_doc, local_retval_sign_e_doc
"""
Mettre à jour la facture pour indiquer 'e_document_signe_id
"""
qry = {'_id':ObjectId(str(diction['invoice_id'])),
'valide':'1',
'locked':'0',
'partner_owner_recid':str(my_partner['recid'])}
update_data = {}
update_data['e_document_signe_id'] = str(e_Invoice_id)
ret_val2 = MYSY_GV.dbname['partner_invoice_header'].find_one_and_update(qry,
{"$set": update_data},
upsert=False,
return_document=ReturnDocument.AFTER
)
# zzzzz
return True, str(local_retval_e_doc)
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de créer la E-Facture "
"""
Audite action session :
Cette fonction permet de lister les inscrits pour qui
les actions ci-dessous n'ont pas été faite :
- convocation
- convention
- etc
"""
def Audit_Session_Action_Inscrit(diction):
try:
field_list = ['token', 'session_id', ]
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée")
return False, "Toutes les informations fournies ne sont pas valables"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', 'session_id', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, "Toutes les informations necessaires n'ont pas été fournies"
# Recuperation du recid du partner
mydata = {}
mytoken = ""
if ("token" in diction.keys()):
if diction['token']:
mytoken = diction['token']
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data({'token':str(diction['token'])})
if (local_status is not True):
return local_status, my_partner
# Verifier la validité de la session
is_valide_session_count = MYSY_GV.dbname['session_formation'].count_documents({'_id':ObjectId(str(diction['session_id'])),
'valide':'1',
'partner_owner_recid':str(my_partner['recid'])})
if( is_valide_session_count != 1 ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
"""
Recuperer la listes des inscrit validé à cette session
"""
tab_email_inscrti_valide = []
tab_inscrit = MYSY_GV.dbname['inscription'].find({'session_id':str(diction['session_id']),
'status':'1',
'partner_owner_recid':str(my_partner['recid'])})
for email in tab_inscrit:
if( "email" in email):
tab_email_inscrti_valide.append(email['email'])
#print(" Liste des email inscrit en tout = ", tab_email_inscrti_valide)
"""
Recuperer la liste des documents tracké pour cette session
"""
diction_list_tracked_doc = {}
diction_list_tracked_doc['token'] = str(diction['token'])
diction_list_tracked_doc['related_collection'] = "session_formation"
diction_list_tracked_doc['related_collection_recid'] = str(diction['session_id'])
diction_list_tracked_doc['session_id'] = str(diction['session_id'])
local_status, local_retval = module_editique.Get_Editable_Document_By_Partner_By_Collection(diction_list_tracked_doc)
if( local_status is False ):
return local_status, local_retval
tab_statut_action = []
local_id = 0
for tmp_val in local_retval :
document_type = ast.literal_eval(tmp_val)
tab_inscrit_ok = []
node = {}
node['id'] = local_id
node['courrier_template_nom'] = document_type['courrier_template_nom']
node['courrier_template_ref_interne'] = document_type['courrier_template_nom']
node['tab_user_statut'] = []
local_id = local_id + 1
for local_email in tab_email_inscrti_valide:
email_exist = 0
sub_node = {}
for val in document_type['list_document_history_event'] :
if( val['local_target_collection_name'] == local_email ):
email_exist = 1
sub_node['_id'] = val['_id']
sub_node['email_inscrit'] = val['local_target_collection_name']
sub_node['date_update'] = val['date_update']
sub_node['local_update_by_email'] = val['local_update_by_email']
sub_node['statut'] = "1"
if( email_exist == 0 ):
sub_node['email_inscrit'] = local_email
sub_node['date_update'] = ""
sub_node['local_update_by_email'] = ""
sub_node['statut'] = "0"
node['tab_user_statut'].append(sub_node)
tab_statut_action.append(node)
RetObject = []
RetObject.append(mycommon.JSONEncoder().encode(tab_statut_action))
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de réaliser l'audit de la session"
"""
Cette fonction permet d'envoyer une demande a un client
pour mettre à jour la liste de ses apprenant qui sont inscrit à une session.
Cette fonction s'applique uniquement au preinscrit (status = 0)
use case :
lorqu'un client valide un devis, les places sont preinscrit sur la session avec des nom par defaut
(devis_nom1, devis_nom2, etc).
Le gestionnaire de formation, peut ensuire utiliser cette fonction pour demander au client de saisir ou valider
les noms et emails definitifs.
/!\ : On traite toute la liste d'un client, pas de traitement partiel
"""
def Prepare_request_presinscription_data_validation(diction):
try:
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', 'list_inscription_id', 'session_id']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, " Les informations fournies ne sont pas correctes"
mytoken = ""
if ("token" in diction.keys()):
if diction['token']:
mytoken = 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
partner_recid = my_partner['recid']
list_client_id = []
list_inscription_id = []
if ("list_inscription_id" in diction.keys()):
if diction['list_inscription_id']:
list_inscription_id = str(diction['list_inscription_id']).replace(",", ";").split(";")
for inscription_id in list_inscription_id:
"""
# Verification que l'inscription existe et qu'elle est valide et qu'elle est au statut 0 (preinscrit)
"""
ret_val2_count = MYSY_GV.dbname['inscription'].count_documents(
{'_id': ObjectId(str(inscription_id)), 'partner_owner_recid': str(my_partner['recid']),
'session_id':diction['session_id'] },
)
if (ret_val2_count != 1):
mycommon.myprint(str(inspect.stack()[0][
3]) + "L'identifiant de l'inscription " + str(
inscription_id) + " n'est pas valide ")
return False, " L'identifiant de l'inscription " + str(inscription_id) + " n'est pas valide "
inscription_id_data = MYSY_GV.dbname['inscription'].find_one(
{'_id': ObjectId(str(inscription_id)), 'partner_owner_recid': str(my_partner['recid']), 'session_id':diction['session_id']
},
)
if ("status" not in inscription_id_data.keys() or inscription_id_data['status'] != "0"):
mycommon.myprint(str(inspect.stack()[0][
3]) + " Toutes les inscriptions doivent être au statut : 'preinscription' ")
return False, " Toutes les inscriptions doivent être au statut : preinscription "
# On enregistre le client dans la table "list_client_id"
if ("client_rattachement_id" in inscription_id_data.keys() and inscription_id_data[
'client_rattachement_id'] and inscription_id_data['client_rattachement_id'] not in list_client_id):
list_client_id.append(str(inscription_id_data['client_rattachement_id']))
# Verifier que la session de formation concernée est valide
is_valide_session = MYSY_GV.dbname['session_formation'].count_documents(
{'_id': ObjectId(str(inscription_id_data['session_id'])),
'partner_owner_recid': str(my_partner['recid']),
'valide': '1'})
if (is_valide_session != 1):
mycommon.myprint(str(inspect.stack()[0][
3]) + " L'identifiant de la session de formation " + str(
inscription_id_data['session_id']) + " n'est pas valide ")
return False, " L'identifiant de la session de formation " + str(
inscription_id_data['session_id']) + " n'est pas valide "
mycommon.myprint_debug(" list_client_id = " + str(list_client_id))
# A present les controles sont ok sur la liste on peut valide la liste des inscription
warning_msg = ""
is_warning = ""
for client_id in list_client_id:
mycommon.myprint_debug(" Traitement du client client_id = " + str(client_id))
new_local_diction = {}
new_local_diction['client_id'] = str(client_id)
new_local_diction['session_id'] = str(diction['session_id'] )
new_local_diction['partner_recid'] = str(my_partner['recid'])
new_local_diction['token'] = str(diction['token'])
local_send_status, local_retval = Send_Email_request_presinscription_data_validation(new_local_diction)
if (local_send_status is False):
is_warning = "1"
warning_msg = warning_msg + "\n" + str(local_retval)
if (is_warning == "1"):
return True, str(warning_msg)
return True, "Les demandes de mise à jour ont été envoyées"
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
print(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, " Impossible d'envoyer les demandes de mise à jour"
"""
07/02/2025 : A l'image de la fonction plus haut, cette fonction
permet de demander un client de créer lui meme les preinscriptions pour une nombre limite max de préinscrit
La fonction plus demande la mise à à jour des données des préinscrits, alors celle ci demande carrement de faire l'inscription
Alog :
Apres l'envoi de la demande au client, on va stoker dans une collection "client_preinsc_update_request"
le nombre max, le client, la session.
Aini à l'ouverture par le front de la route : "/UpadateAttendeeList/:client_id/:session_id/:partner_owner_recid/"
le systeme va regarder dans la collection précedente pour recuperer le nombre max.
Par la suite cette collection pourra etre utilisé pour d'autre regles.
"""
def Prepare_request_For_Preinsciption_Creation_By_Customer(diction):
try:
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', 'session_id', 'client_id', 'max_presinscrit']
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 ne sont pas correctes"
mytoken = ""
if ("token" in diction.keys()):
if diction['token']:
mytoken = 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
"""
Verifier la validité du client
"""
is_client_valide_count = MYSY_GV.dbname['partner_client'].count_documents({'partner_recid':str(my_partner['recid']),
'valide':'1',
'locked':'0',
'_id':ObjectId(str(diction['client_id']))})
if( is_client_valide_count != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant du client est invalide ")
return False, " L'identifiant du client est invalide "
# A present les controles sont ok sur la liste on peut valide la liste des inscription
warning_msg = ""
is_warning = ""
new_local_diction = {}
new_local_diction['client_id'] = str(diction['client_id'])
new_local_diction['session_id'] = str(diction['session_id'] )
new_local_diction['partner_recid'] = str(my_partner['recid'])
new_local_diction['token'] = str(diction['token'])
local_send_status, local_retval = Send_Email_request_presinscription_data_validation(new_local_diction)
if (local_send_status is False):
is_warning = "1"
warning_msg = warning_msg + "\n" + str(local_retval)
"""
S'il y a un enregistrement dans la collection : 'client_preinsc_update_request', pour la meme session et le meme
client alors on fait la mise à jour
"""
update_data = {}
update_data['date_update'] = str(datetime.now())
update_data['update_by'] = str(my_partner['_id'])
update_data['max_presinscrit'] = str(diction['max_presinscrit'])
update_data['session_id'] = str(diction['session_id'])
update_data['client_id'] = str(diction['client_id'])
update_data['valide'] = "1"
update_data['locked'] = "0"
result = MYSY_GV.dbname['client_preinsc_update_request'].find_one_and_update(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1',
'locked': '0',
'client_id': str(diction['client_id']),
'session_id': str(diction['session_id'])},
{"$set": update_data},
upsert=True,
return_document=ReturnDocument.AFTER
)
if (is_warning == "1"):
return True, str(warning_msg)
return True, "Les demandes de mise à jour ont été envoyées"
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
print(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, " Impossible d'envoyer les demandes de mise à jour"
"""
Cette fonction envoi l'email de demande de validation/maj
de la liste des preinscrits à une session de formation
"""
def Send_Email_request_presinscription_data_validation(diction):
try:
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['client_id', 'session_id', 'partner_recid', '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 ne sont pas correctes"
# A present les controles sont ok sur la liste on peut valide la liste des inscription
warning_msg = ""
is_warning = ""
# Recuperation des données des stagiaires
tab_stagiaire = []
for inscription_id_data in MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']), 'partner_owner_recid': str(diction['partner_recid']), 'status': '1', 'client_rattachement_id': str(diction['client_id'])}):
if (inscription_id_data is None):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant du stagiaire est invalide ")
return False, " L'identifiant du stagiaire est invalide "
tab_stagiaire.append(inscription_id_data['_id'])
# Recuperation des données du client
tab_client = []
for client_id_data in MYSY_GV.dbname['partner_client'].find(
{'_id': ObjectId(str(diction['client_id'])), 'partner_recid': str(diction['partner_recid']),
'valide': '1', 'locked':'0'}):
if (client_id_data is None):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant du client est invalide ")
return False, " L'identifiant du client est invalide "
tab_client.append(client_id_data['_id'])
# Recuperation des contacts de communucation du client
local_diction = {}
local_diction['token'] = diction['token']
local_diction['_id'] = str(diction['client_id'])
local_status, partner_client_contact_communication = partner_client.Get_Partner_Client_Communication_Contact(local_diction)
if( local_status is False ):
return local_status, partner_client_contact_communication
tab_email_contact_client_destinataire = []
for tmp_val in partner_client_contact_communication:
tmp_val_JSON = ast.literal_eval(tmp_val)
if( "email" in tmp_val_JSON.keys() and tmp_val_JSON['email']):
tab_email_contact_client_destinataire.append(str(tmp_val_JSON['email']))
# Recuperation des données de la session
tab_session = []
class_internal_url = ""
for session_id_data in MYSY_GV.dbname['session_formation'].find(
{'_id': ObjectId(str(diction['session_id'])), 'partner_owner_recid': str(diction['partner_recid']),
'valide': '1', }):
if (session_id_data is None):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la session est invalide ")
return False, " L'identifiant de la session est invalide "
tab_session.append(session_id_data['_id'])
class_internal_url = session_id_data['class_internal_url']
# Recuperation des données de la formation
tab_class = []
for class_id_data in MYSY_GV.dbname['myclass'].find(
{'internal_url': str(class_internal_url), 'partner_owner_recid': str(diction['partner_recid']),
'valide': '1', }):
if (class_id_data is None):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la formation est invalide ")
return False, " L'identifiant de la formation est invalide "
tab_class.append(class_id_data['_id'])
new_diction = {}
new_diction['token'] = diction['token']
new_diction['list_stagiaire_id'] = tab_stagiaire
new_diction['list_session_id'] = tab_session
new_diction['list_class_id'] = tab_class
new_diction['list_client_id'] = tab_client
new_diction['list_apprenant_id'] = []
new_diction['list_sequence_session_id'] = []
local_status, local_retval = mycommon.Get_Dictionnary_data_For_Template(new_diction)
convention_dictionnary_data = local_retval
convention_dictionnary_data['attendeelist_url'] = MYSY_GV.CLIENT_URL_BASE+"UpadateAttendeeList/"+str(diction['client_id'])+"/"+str(diction['session_id'])+"/"+str(diction['partner_recid'])+"/"
body = {
"params": convention_dictionnary_data,
}
"""
Recuperation du modele de courrier
"""
# field_list = ['token', "courrier_template_id", "courrier_template_ref_interne", "partner_recid"]
new_local_diction = {}
new_local_diction['courrier_template_id'] = ""
new_local_diction['courrier_template_ref_interne'] = "PARTICIPANT_LIST_UPDATE"
new_local_diction['partner_recid'] = str(diction['partner_recid'])
status_courrier_template_data , retval_courrier_template_data = mycommon.Get_Partner_Courrier_Model(new_local_diction)
if( status_courrier_template_data is False):
return status_courrier_template_data , retval_courrier_template_data
courrier_template_data = retval_courrier_template_data
## Creation du mail au format email
corps_mail_Template = jinja2.Template(str(courrier_template_data['contenu_doc']))
sourceHtml = corps_mail_Template.render(params=body["params"])
html_mime = MIMEText(sourceHtml, 'html')
#print(" ### sourceHtml === ", sourceHtml)
# Traitement du sujet du mail
sujet_mail_Template = jinja2.Template(str(courrier_template_data['sujet']))
sujetHtml = sujet_mail_Template.render(params=body["params"])
# Creation de l'email à enoyer
msg = MIMEMultipart("alternative")
# Recuperation des donnes smpt
local_stpm_status, partner_SMTP_COUNT_smtpsrv, partner_own_smtp_value, partner_SMTP_COUNT_password, partner_SMTP_COUNT_user, partner_SMTP_COUNT_From_User, partner_SMTP_COUNT_port = mycommon.Get_Partner_SMTP_Param(
diction['partner_recid'])
if (local_stpm_status is False):
return local_stpm_status, partner_own_smtp_value
msg.attach(html_mime)
msg['From'] = partner_SMTP_COUNT_From_User
msg['Bcc'] = 'contact@mysy-training.com'
msg['Subject'] = sujetHtml
# msg['to'] = "billardman01@hotmail.com"
toaddrs = ",".join(tab_email_contact_client_destinataire)
msg['to'] = str(toaddrs)
smtpserver = smtplib.SMTP(partner_SMTP_COUNT_smtpsrv, partner_SMTP_COUNT_port)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.login(partner_SMTP_COUNT_user, partner_SMTP_COUNT_password)
val = smtpserver.send_message(msg)
smtpserver.close()
print(" Email envoyé 44" + str(val))
return True, "Les demandes de mise à jour ont été envoyées"
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
print(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, " Impossible d'envoyer les demandes de mise à jour"
"""
Cette fonction permet à un client de mettre à jour
la liste de ses partipants à une session de formation.
"""
def Client_Update_Liste_Attendee_No_Token(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['client_id', 'session_id', 'list_attendee_data', 'partner_recid', 'is_client_preinsc_update_request']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé")
return False, " Les informations fournies sont incorrectes"
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['client_id', 'session_id', 'list_attendee_data', 'partner_recid']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
return False, " Les informations fournies sont incorrectes"
"""
Verifier que le client est valide
"""
is_client_valide_data = MYSY_GV.dbname['partner_client'].find_one({'_id':ObjectId(str(diction['client_id'])),
'valide':'1',
'locked':'0',
'partner_recid':str(diction['partner_recid'])})
if(is_client_valide_data is None ):
mycommon.myprint(str(
inspect.stack()[0][3]) + " L'identifiant du client n'est pas valide")
return False, " L'identifiant du client n'est pas valide "
"""
Verifier que la session est valide
"""
is_session_valide_data = MYSY_GV.dbname['session_formation'].find_one({'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(
diction['partner_recid'])})
if (is_session_valide_data is None):
mycommon.myprint(str(
inspect.stack()[0][3]) + " L'identifiant de la session n'est pas valide")
return False, " L'identifiant de la session n'est pas valide "
JSON_attendee_response = ast.literal_eval(diction['list_attendee_data'])
for val in JSON_attendee_response:
print(" analyse de val = ", val)
# Verifier que les données envoyées sont valide avant de mettre à jour tous les participants
# Cette verification n'est faite que si val['_id'] != "new"
# On va ignorer dans la mise à jour les inscription deja validées
if( str(val['_id']) != "new" and len(str(val['_id'])) > 5 and len(str(val['status'])) == "0" ) :
is_valide_attendee = MYSY_GV.dbname['inscription'].count_documents({'_id':ObjectId(str(val['_id'])),
'status':'0',
'session_id':str(diction['session_id']),
'client_rattachement_id':str(diction['client_id']),
'partner_owner_recid':str(diction['partner_recid'])})
if(is_valide_attendee <= 0 ):
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le participant "+str(val['_id'])+" n'est pas valide ou n'est pas au statut PREINSCRIT")
return False, " Le participant "+str(val['_id'])+" n'est pas valide ou n'est pas au statut PREINSCRIT"
if ("civilite" in val.keys() and str(val['civilite']).lower().strip() not in MYSY_GV.CIVILITE):
mycommon.myprint(
str(inspect.stack()[0][3]) + "La civlité " +str(val['civilite']).lower().strip() + " n'est pas valide. Les valeurs autorisées sont "+str(MYSY_GV.CIVILITE))
return False, " La civlité " +str(val['civilite']).lower().strip() + " n'est pas valide. Les valeurs autorisées sont "+str(MYSY_GV.CIVILITE)
# Verifier la validité du mail
if ("email" in val.keys()):
local_email = str(val['email']).strip()
if (mycommon.isEmailValide(local_email) is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - l'adresse email " + str(local_email) + " n'est pas valide")
return False, "- l'adresse email " + str(local_email) + " n'est pas valide "
# Si val['_id'] == "new" et is_client_preinsc_update_request == "1", alors il faut faire une creation
if( str(val['_id']) == "new" and "is_client_preinsc_update_request" in diction.keys() and str(diction['is_client_preinsc_update_request']) == "1" ):
new_presinscrit = {}
new_presinscrit['nom'] = str(val['nom'])
new_presinscrit['prenom'] = str(val['prenom'])
new_presinscrit['session_id'] = str(diction['session_id'])
new_presinscrit['client_rattachement_id'] = str(diction['client_id'])
new_presinscrit['partner_owner_recid'] = str(diction['partner_recid'])
new_presinscrit['status'] = "0"
new_presinscrit['date_du'] = str(is_session_valide_data['date_debut'])
new_presinscrit['date_au'] = str(is_session_valide_data['date_fin'])
new_presinscrit['class_internal_url'] = str(is_session_valide_data['class_internal_url'])
if( "modefinancement" in val.keys()):
new_presinscrit['modefinancement'] = str(val['modefinancement'])
else:
new_presinscrit['modefinancement'] = ""
if ("adresse" in val.keys()):
new_presinscrit['adresse'] = str(val['adresse'])
else:
new_presinscrit['adresse'] = ""
if ("employeur" in val.keys()):
new_presinscrit['employeur'] = str(val['employeur'])
else:
new_presinscrit['employeur'] = ""
if ("date_naissance" in val.keys()):
new_presinscrit['date_naissance'] = str(val['date_naissance'])
else:
new_presinscrit['date_naissance'] = ""
if ("facture_client_rattachement_id" in val.keys()):
new_presinscrit['facture_client_rattachement_id'] = str(val['facture_client_rattachement_id'])
else:
new_presinscrit['facture_client_rattachement_id'] = ""
if ("financeur_rattachement_id" in val.keys()):
new_presinscrit['financeur_rattachement_id'] = str(val['financeur_rattachement_id'])
else:
new_presinscrit['financeur_rattachement_id'] = ""
if ("type_apprenant" in val.keys()):
new_presinscrit['type_apprenant'] = str(val['type_apprenant'])
else:
new_presinscrit['type_apprenant'] = "0"
new_presinscrit['valide'] = "1"
new_presinscrit['prenom'] = str(val['prenom'])
new_presinscrit['date_creation'] = str(datetime.now())
if ("civilite" in val.keys() and str(val['civilite']).lower().strip() in MYSY_GV.CIVILITE):
new_presinscrit['civilite'] = str(val['civilite']).lower().strip()
# Verifier la validité du mail
if ("email" in val.keys()):
local_email = str(val['email']).strip()
if (mycommon.isEmailValide(local_email)):
new_presinscrit['email'] = local_email
else:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - l'adresse email " + str(local_email) + " n'est pas valide")
return False, "- l'adresse email " + str(local_email) + " n'est pas valide "
print(" ## insert ",new_presinscrit )
result = MYSY_GV.dbname['inscription'].insert_one(new_presinscrit)
"""
A présent toutes les données sont valide, on fait la mise à jour
"""
for val in JSON_attendee_response:
# Verifier qu'on mettre à jour tous les participants
if (str(val['_id']) != "new" and len(str(val['_id'])) > 5):
update_data = {}
update_data['date_update'] = str(datetime.now())
update_data['update_by'] = "Client"
update_data['nom'] = str(val['nom'])
update_data['prenom'] = str(val['prenom'])
if( "civilite" in val.keys() and str(val['civilite']).lower().strip() in MYSY_GV.CIVILITE):
update_data['civilite'] = str(val['civilite']).lower().strip()
# Verifier la validité du mail
if ("email" in val.keys() ):
local_email = str(val['email']).strip()
if (mycommon.isEmailValide(local_email)):
update_data['email'] = local_email
else:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - l'adresse email " + str(local_email) + " n'est pas valide")
return False, "- l'adresse email " + str(local_email) + " n'est pas valide "
update_attendee_data = MYSY_GV.dbname['inscription'].find_one_and_update({'_id':ObjectId(str(val['_id'])),
'status':'0',
'session_id':str(diction['session_id']),
'client_rattachement_id':str(diction['client_id']),
'partner_owner_recid':str(diction['partner_recid'])},
{"$set": update_data},
upsert=False,
return_document=ReturnDocument.AFTER
)
return True, "Les mises à jour ont été correctement faites"
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
print(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de mettre à jour la liste des participants"
"""
Cette fonction supprime une personne de liste
des attendee (inscrit), a condition que son status
d'incription ne soit pas validé"""
def Client_Delete_One_Attendee_No_Token(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['client_id', 'session_id', 'partner_recid', 'inscription_id']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé")
return False, " Les informations fournies sont incorrectes"
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['client_id', 'session_id', 'partner_recid', 'inscription_id']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
return False, " Les informations fournies sont incorrectes"
"""
Verifier que le client est valide
"""
is_client_valide_data = MYSY_GV.dbname['partner_client'].find_one({'_id':ObjectId(str(diction['client_id'])),
'valide':'1',
'locked':'0',
'partner_recid':str(diction['partner_recid'])})
if(is_client_valide_data is None ):
mycommon.myprint(str(
inspect.stack()[0][3]) + " L'identifiant du client n'est pas valide")
return False, " L'identifiant du client n'est pas valide "
"""
Verifier que la session est valide
"""
is_session_valide_data = MYSY_GV.dbname['session_formation'].find_one({'_id': ObjectId(str(diction['session_id'])),
'valide': '1',
'partner_owner_recid': str(
diction['partner_recid'])})
if (is_session_valide_data is None):
mycommon.myprint(str(
inspect.stack()[0][3]) + " L'identifiant de la session n'est pas valide")
return False, " L'identifiant de la session n'est pas valide "
"""
Verifier que l'inscrit est valide est que statuts est 0
"""
is_valide_attendee = MYSY_GV.dbname['inscription'].count_documents({'_id': ObjectId(str(diction['inscription_id'])),
'status': '0',
'session_id': str(diction['session_id']),
'client_rattachement_id': str(
diction['client_id']),
'partner_owner_recid': str(
diction['partner_recid'])})
if (is_valide_attendee <= 0):
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le participant " + str(
diction['inscription_id']) + " n'est pas valide ou n'est pas au statut PREINSCRIT")
return False, " Le participant " + str(diction['inscription_id']) + " n'est pas valide ou n'est pas au statut PREINSCRIT"
print("QRYY 0303 = ", {'_id': ObjectId(str(diction['inscription_id'])),
'status': '0',
'session_id': str(diction['session_id']),
'client_rattachement_id': str(
diction['client_id']),
'partner_owner_recid': str(
diction['partner_recid'])})
# Supression à faire
delete = MYSY_GV.dbname['inscription'].delete_one({'_id': ObjectId(str(diction['inscription_id'])),
'status': '0',
'session_id': str(diction['session_id']),
'client_rattachement_id': str(
diction['client_id']),
'partner_owner_recid': str(
diction['partner_recid'])})
return True, "La suppression a été correctement faite "
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
print(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de supprimer le participant"
"""
Cette fonction permet de créer une session de formation
à partir d'une ligne de devis
"""
"""
Fonction de creation et mise à jour d'une session de formation.
/!\ : le champ 'source' definit la source de la creation de la session
si le champ 'session_id' est renseigné alors c'est une mise à jour.
"""
def Add_SessionFormation_From_Quotation_Line(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', 'date_debut', 'date_fin', 'nb_participant', 'adresse',
'code_postal', 'ville', 'code_session',
'class_id', 'session_status', 'date_debut_inscription', 'date_fin_inscription',
'attestation_certif', "distantiel", "presentiel", "mode_animation", "prix_session", 'contenu_ftion',
'lms_class_code',
'session_ondemande', 'source', 'session_etape', 'pays', 'formateur_id',
'titre', 'location_type', 'is_bpf', 'site_formation_id', 'price_by',
'quotation_line_id', 'resa_inscrit']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé.")
return False, " Toutes les informations fournies ne sont pas valables"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', 'date_debut', 'date_fin', 'nb_participant',
'class_id','code_session', 'quotation_line_id', 'resa_inscrit' ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " La valeur '" + val + "' n'est pas presente dans liste ")
return False, "Toutes les informations necessaires n'ont pas été fournies"
mydata = {}
query_key = {}
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_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
"""
Verifier la validation de la formation
"""
is_valide_class_id_count = MYSY_GV.dbname['myclass'].count_documents({'_id':ObjectId(str(diction['class_id'])),
'valide':'1',
'locked':'0',
'partner_owner_recid':str(my_partner['recid'])})
if( is_valide_class_id_count != 1 ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant de la formation est invalide ")
return False, " L'identifiant de la formation est invalide "
class_id_data = MYSY_GV.dbname['myclass'].find_one({'_id':ObjectId(str(diction['class_id'])),
'valide':'1',
'locked':'0',
'partner_owner_recid':str(my_partner['recid'])},
{'_id':1, 'internal_url':1, 'price':1, 'presentiel':1})
"""
Verifier que le devis est valide
"""
is_valide_quotation_count = MYSY_GV.dbname['partner_order_line'].count_documents({'_id':ObjectId(str(diction['quotation_line_id'])),
'valide':'1',
'locked':'0',
'partner_owner_recid':str(my_partner['recid']),
'order_line_type':'devis',
'order_line_status': {
'$in': ['1', '3']}
})
if( is_valide_quotation_count != 1 ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le devis n'est pas valide ")
return False, " Le devis n'est pas valide "
local_resa_inscrit = diction['resa_inscrit']
local_line_qotation_qty = diction['nb_participant']
local_quotation_line_id = diction['quotation_line_id']
mydata = diction
del diction['token']
del diction['resa_inscrit']
del diction['quotation_line_id']
# Initialisation des champs non envoyés à vide
for val in field_list:
if val not in mydata.keys():
mydata[str(val)] = ""
mydata['titre'] = str(mydata['code_session'])
mydata['class_internal_url'] = str(class_id_data['internal_url'])
mydata['prix_session'] = str(class_id_data['price'])
mydata['price_by'] = "persession"
mydata['session_status'] = "1"
mydata['distantiel'] = "0"
mydata['presentiel'] = "0"
mydata['is_bpf'] = "0"
mydata['mode_animation'] = "0"
mydata['date_debut_inscription'] = str(mydata['date_debut'])
mydata['date_fin_inscription'] = str(mydata['date_fin'])
mydata['date_update'] = str(datetime.now())
mydata['update_by'] = str(my_partner['_id'])
mydata['partner_owner_recid'] = str(my_partner['recid'])
mydata['valide'] = "1"
mydata['locked'] = "0"
# Controle de cohérence sur les dates
local_status = mycommon.CheckisDate(str(diction['date_debut'])[0:10])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La date de debut n'est pas au format jj/mm/aaaa ")
return False, " La date de debut n'est pas au format jj/mm/aaaa "
local_status = mycommon.CheckisDate(str(diction['date_fin'])[0:10])
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + "La date de fin n'est pas au format jj/mm/aaaa ")
return False, " La date de fin n'est pas au format jj/mm/aaaa "
if (datetime.strptime(str(diction['date_debut'])[0:10], '%d/%m/%Y') > datetime.strptime(
str(diction['date_fin'])[0:10], '%d/%m/%Y')):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Session de Formation : La date debut " + str(
diction['date_debut'])[0:10] +
" est postérieure à la date de fin " + str(diction['date_fin'])[0:10])
return False, " Session de Formation : La date debut de formation " + str(diction['date_debut'])[0:10] + \
" est postérieure à la date de fin de formation " + str(diction['date_fin'])[0:10] + " "
# Fin Controle de cohérence sur les dates
# La session n'existe pas, on fait une simple creation
coll_name = MYSY_GV.dbname['session_formation']
ret_val = coll_name.insert_one(mydata)
local_inserted_id = ret_val.inserted_id
if (ret_val is None or not hasattr(ret_val, 'inserted_id')):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Impossible d'ajouter la session '" + str(
diction['code_session']) + "' ")
return False, "Impossible d'ajouter la session '" + str(diction['code_session']) + "' "
"""
Apres la creation de la session, on met à jour la ligne du devis en ajoutant l'id de la session
"""
update_quotation_line_id = MYSY_GV.dbname['partner_order_line'].find_one_and_update(
{'_id': ObjectId(str(local_quotation_line_id)),
'partner_owner_recid': str(my_partner['recid']),
'valide': '1',
'locked': '0'},
{"$set": {'order_line_session_id':str(local_inserted_id)}},
return_document=ReturnDocument.AFTER,
upsert=False,
)
"""
Si l'option de reservation des inscrit est activée alors on reserve les places
"""
if( local_resa_inscrit == "1"):
cpt = 0
line_qotation_qty = mycommon.tryInt(local_line_qotation_qty )
quotation_line_data = MYSY_GV.dbname['partner_order_line'].find_one(
{'_id': ObjectId(str(local_quotation_line_id)),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid']),
'order_line_type': 'devis',
})
quotation_header_data = MYSY_GV.dbname['partner_order_header'].find_one(
{'_id':ObjectId(str(quotation_line_data['order_header_id'])),
'order_header_ref_interne':str(quotation_line_data['order_header_ref_interne']),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid']),
})
nb_resa_line = 0
while (cpt < line_qotation_qty):
cpt = cpt + 1
new_data = {}
new_data['nom'] = str(quotation_header_data['order_header_ref_interne']) + "_Reservation_Nom_" + str(cpt)
new_data['prenom'] = str(quotation_header_data['order_header_ref_interne']) + "_Reservation_Prenom_" + str(cpt)
new_data['email'] = str(quotation_header_data['order_header_ref_interne']) + "_Reservation_mail_" + str( cpt) + "@mail.com"
new_data['telephone'] = "01010101"
new_data['modefinancement'] = ""
new_data['class_internal_url'] = str(class_id_data['internal_url'])
new_data['session_id'] = str(local_inserted_id)
new_data['client_rattachement_id'] = str(quotation_header_data['order_header_client_id'])
new_data['civilite'] = "neutre"
new_data['quotation_id'] = str(quotation_line_data['order_header_id'])
new_data['status'] = "0"
new_data['type_apprenant'] = "1"
"""
/!\
22/04/2024 :On a besoin du token pour utiliser la fonction standard.
On va aller recuperer le token du compte principale du partner
/!\
"""
main_account_data = MYSY_GV.dbname['partnair_account'].find_one(
{'recid': str(diction['partner_owner_recid']),
'active': '1', 'is_partner_admin_account': '1'})
new_data['token'] = str(main_account_data['token'])
local_insert_status, local_insert_retval = Inscription_mgt.AddStagiairetoClass(new_data)
if (local_insert_status is False):
is_warning = "1"
warning_msg = warning_msg + "\n" + str(local_insert_retval)
else:
nb_resa_line = nb_resa_line + 1
return True, " La session de formation à bien été créée"
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 créer la session de formation"
"""
Cette fonction permet de mettre à jour le paramettrage
d'envoie automatique des documents d'une session de formation.
Par exemple :
- Envoyer les convention X avant le début de la session de formation
/!\ : Toute mise à jour reinitialise la valeur 'statut' à 0. (sans cele
le traitement ne va s'exécuté s'il a déjà ete exécuté 1 fois
"""
def Update_SessionFormation_Doc_Automatic_Setup(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', '_id', 'nb_jour_action', 'actif', 'courrier_template_type_document_ref_interne',
'action_target_date']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé.")
return False, " Toutes les informations fournies ne sont pas valables"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', '_id', 'nb_jour_action', 'actif', 'courrier_template_type_document_ref_interne',
'action_target_date']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, "Toutes les informations necessaires n'ont pas été fournies"
mydata = {}
query_key = {}
my_token = ""
if ("token" in diction.keys()):
if diction['token']:
my_token = diction['token']
nb_jour_action = diction['nb_jour_action']
local_status, local_retval = mycommon.IsInt(str(nb_jour_action))
if (local_status is False):
mycommon.myprint(str(
inspect.stack()[0][
3]) + " Le nombre de jours est invalide ")
return False, " Le nombre de jours est invalide "
actif = diction['actif']
if (actif not in ['0', '1']):
mycommon.myprint(str(
inspect.stack()[0][
3]) + " Le status (actif/inactif) est invalide ")
return False, " Le status (actif/inactif) est invalide "
action_target_date = diction['action_target_date']
if (action_target_date not in ['start_session', 'end_session', 'every_session_sequence_day']):
mycommon.myprint(str(
inspect.stack()[0][
3]) + " La valeur du champ 'action_target_date' est invalide ")
return False, " La valeur du champ 'action_target_date' est invalide "
data_for_check_connexion = {'token': my_token}
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(data_for_check_connexion)
if (local_status is not True):
return local_status, my_partner
"""
Verifier la valididé de la session de formation
"""
is_valide_session = MYSY_GV.dbname['session_formation'].count_documents({'_id':ObjectId(str(diction['_id'])),
'valide':'1', 'partner_owner_recid':str(my_partner['recid'])})
if( is_valide_session != 1 ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - L'identifiant de la session de formation est invalide ")
return False, "L'identifiant de la session de formation est invalide"
is_valide_session_data = MYSY_GV.dbname['session_formation'].find_one({'_id': ObjectId(str(diction['_id'])),
'valide': '1',
'partner_owner_recid': str(
my_partner['recid'])})
if( "invoiced_statut" in is_valide_session_data.keys() and is_valide_session_data['invoiced_statut'] == '1'):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - Cette session est partiellement facturée. Modification impossible ")
return False, "Cette session est partiellement facturée. Modification impossible"
if ("invoiced_statut" in is_valide_session_data.keys() and is_valide_session_data['invoiced_statut'] == '2'):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Cette session est complètement facturée. Modification impossible ")
return False, "Cette session est complètement facturée. Modification impossible"
"""
Verifier la validité du type de document 'courrier_template_type_document_ref_interne'
"""
is_courrier_template_type_document_id_valide = MYSY_GV.dbname['courrier_template_type_document'].count_documents(
{'ref_interne':str(diction['courrier_template_type_document_ref_interne']),
'valide':'1',
'locked':'0'})
if( is_courrier_template_type_document_id_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Le type de modèle de courrier est invalide ")
return False, " Le type de modèle de courrier est invalide "
is_courrier_template_type_document_data = MYSY_GV.dbname[
'courrier_template_type_document'].find_one(
{'ref_interne':str(diction['courrier_template_type_document_ref_interne']),
'valide': '1',
'locked': '0'})
update = MYSY_GV.dbname['session_formation'].update_one({'_id': ObjectId(str(diction['_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid']),
'automatic_traitement.courrier_template_type_document_ref_interne': str(diction['courrier_template_type_document_ref_interne'])},
{'$set':
{
'automatic_traitement.$[xxx].actif': str(actif),
'automatic_traitement.$[xxx].statut': "0",
'automatic_traitement.$[xxx].nb_jour_action': str(nb_jour_action),
'automatic_traitement.$[xxx].date_update': str(datetime.now()),
'automatic_traitement.$[xxx].update_by': str(my_partner['_id']),
'automatic_traitement.$[xxx].action_target_date': str(action_target_date),
}
},
upsert=False,
array_filters=[
{"xxx.courrier_template_type_document_ref_interne": str(diction['courrier_template_type_document_ref_interne'])}
]
)
"""
# Ajout de l'evenement dans l'historique
"""
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = diction['token']
history_event_dict['related_collection'] = "session_formation"
history_event_dict['related_collection_recid'] = str(diction['_id'])
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Modif. automatisation d'envoi des documents. " \
" Type Doc "+str(is_courrier_template_type_document_data['nom'])+". " \
" Nouveau : actif = "+str(actif)+" - nb_jour_action = "+str(nb_jour_action)
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
return True, " La session de formation à bien été mise à jour"
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible mettre à jour la session de formation"
"""
Recuperation la list des : "automatic_traitement"
d'une session de formation
"""
def Get_Given_SessionFormation_List_Automatic_Traitement_From(diction):
try:
field_list = ['token', 'session_id', ]
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'est pas autorisé, Creation partenaire annulée")
return False, "de récupérer la liste des stagiaires . Toutes les informations fournies ne sont pas valables"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['token', 'session_id', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans liste ")
return False, "Impossible de récupérer la liste des stagiaires, Toutes les informations necessaires n'ont pas été fournies"
# Recuperation du recid du partner
mydata = {}
mytoken = ""
if ("token" in diction.keys()):
if diction['token']:
mytoken = diction['token']
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data({'token':str(diction['token'])})
if (local_status is not True):
return local_status, my_partner
partner_recid = my_partner['recid']
session_id = ""
if ("session_id" in diction.keys()):
if diction['session_id']:
session_id = diction['session_id']
if(str(session_id).strip() == ""):
return True, []
coll_session = MYSY_GV.dbname['session_formation']
RetObject = []
local_session_data = coll_session.find_one({'_id':ObjectId(str(session_id)), 'partner_owner_recid':str(partner_recid)}, {'automatic_traitement':1,
'date_debut':1,
'date_fin':1})
"""
16/03/2025 :
Ajouter un champs qui dit si l'action à venir est dans la passé ou dans le future.
cas d'utilisation :
sur le front, une action qui est dans le passé, qui est toujours actif est le signe d'un opération qui ne sait pas bien passé. donc on pourra mettre du orage.
- actif et action dans le future : Vert
- actif et action dans le passé : organce, car erreur
- inactif : gris
"""
local_session_start_date = datetime.strptime(str(local_session_data['date_debut']).strip(), '%d/%m/%Y')
local_session_end_date = datetime.strptime(str(local_session_data['date_fin']).strip(), '%d/%m/%Y')
todays_date = str(date.today().strftime("%d/%m/%Y"))
"""
if (local_session_data and "automatic_traitement" in local_session_data.keys()):
RetObject.append(mycommon.JSONEncoder().encode(local_session_data['automatic_traitement']))
"""
tab_local_automatic_traitement = []
if (local_session_data and "automatic_traitement" in local_session_data.keys()):
for automatic_traitement_data in local_session_data['automatic_traitement']:
automatic_traitement_delta_day = ""
local_status, nb_jour_action_Int = mycommon.IsInt(
str(automatic_traitement_data['nb_jour_action']).strip())
if (local_status is False):
mycommon.myprint(str(
inspect.stack()[0][
3]) + " CRON WARNING : nb_jour_action_Int n'est pas une valeur entière. Session Formation = ",
str(local_session_data['_id']))
# On log une erreur, et on continue le traitement dans la boucle.
continue
my_delta = ""
new_data = automatic_traitement_data
if (automatic_traitement_data['action_target_date'] == "start_session"):
local_session_target_date_added_nb_jour_action = local_session_start_date + timedelta(
days=nb_jour_action_Int)
local_session_target_date_added_nb_jour_action_formated = str(
local_session_target_date_added_nb_jour_action.strftime("%d/%m/%Y"))
my_delta = local_session_target_date_added_nb_jour_action - datetime.strptime(
str(todays_date).strip(), '%d/%m/%Y')
new_data['delta_day'] = str(my_delta.days)
elif (automatic_traitement_data['action_target_date'] == "end_session"):
local_session_target_date_added_nb_jour_action = local_session_end_date + timedelta(
days=nb_jour_action_Int)
local_session_target_date_added_nb_jour_action_formated = str(
local_session_target_date_added_nb_jour_action.strftime("%d/%m/%Y"))
my_delta = local_session_target_date_added_nb_jour_action - datetime.strptime(str(todays_date).strip(), '%d/%m/%Y')
new_data['delta_day'] = str(my_delta.days)
elif (automatic_traitement_data['action_target_date'] == "every_session_sequence_day"):
local_session_target_date_added_nb_jour_action = local_session_start_date
local_session_target_date_added_nb_jour_action_formated = str(local_session_target_date_added_nb_jour_action.strftime("%d/%m/%Y"))
my_delta = local_session_target_date_added_nb_jour_action - datetime.strptime(str(todays_date).strip(), '%d/%m/%Y')
if( local_session_start_date <= datetime.strptime( str(todays_date).strip(), '%d/%m/%Y') <= local_session_end_date):
new_data['delta_day'] = "0"
elif ( datetime.strptime( str(todays_date).strip(), '%d/%m/%Y') < local_session_start_date ):
# /!\ Pr calculer le my_delta, on prend tjours par rapport au début de session, toujours toujours, car c'est à ce moment que le cron devrait tourner la 1ere fois
my_delta = local_session_start_date - datetime.strptime( str(todays_date).strip(), '%d/%m/%Y')
new_data['delta_day'] = str(my_delta.days)
elif (datetime.strptime( str(todays_date).strip(), '%d/%m/%Y') > local_session_end_date ):
# /!\ Pr calculer le my_delta, on prend tjours par rapport au début de session, toujours toujours, car c'est à ce moment que le cron devrait tourner la 1ere fois
my_delta = local_session_start_date - datetime.strptime( str(todays_date).strip(), '%d/%m/%Y')
new_data['delta_day'] = str(my_delta.days)
tab_local_automatic_traitement.append(new_data)
RetObject.append(mycommon.JSONEncoder().encode(tab_local_automatic_traitement))
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible de récupérer la session de formation"
"""
Cette fonction recuperer """