18/02/2026 - 18h

Signed-off-by: Cherif <cbalde@mysy-training.com>
master_Elyos_FI
Cherif 2026-02-18 17:54:30 +01:00
parent 6ba4292ae3
commit b1160ca2b8
8 changed files with 7395 additions and 45 deletions

View File

@ -4,19 +4,15 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="15/02/26 - 18h30">
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="16/02/26 - 18h30">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Dashbord_queries/BPF.py" beforeDir="false" afterPath="$PROJECT_DIR$/Dashbord_queries/BPF.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Inscription_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/Inscription_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/GlobalVariable.py" beforeDir="false" afterPath="$PROJECT_DIR$/GlobalVariable.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Log/log_file.log" beforeDir="false" afterPath="$PROJECT_DIR$/Log/log_file.log" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Session_Formation.py" beforeDir="false" afterPath="$PROJECT_DIR$/Session_Formation.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/code_promo_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/code_promo_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/email_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/email_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/note_evaluation_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/note_evaluation_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/partner_invoice.py" beforeDir="false" afterPath="$PROJECT_DIR$/partner_invoice.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/partners.py" beforeDir="false" afterPath="$PROJECT_DIR$/partners.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/stage_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/stage_mgt.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tools_cherif/tools_cherif.py" beforeDir="false" afterPath="$PROJECT_DIR$/tools_cherif/tools_cherif.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/partner_order.py" beforeDir="false" afterPath="$PROJECT_DIR$/partner_order.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -460,7 +456,7 @@
<option name="project" value="LOCAL" />
<updated>1747251650255</updated>
</task>
<option name="localTasksCounter" value="533" />
<option name="localTasksCounter" value="534" />
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
@ -502,7 +498,6 @@
</option>
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="26/10/2025 - 15h" />
<MESSAGE value="29/10/2025 - 22h" />
<MESSAGE value="04/11/2025 - 12h" />
<MESSAGE value="12/11/2025 - 22h30" />
@ -527,6 +522,7 @@
<MESSAGE value="12/02/26 - 10h" />
<MESSAGE value="12/02/26 - 10h30" />
<MESSAGE value="15/02/26 - 18h30" />
<option name="LAST_COMMIT_MESSAGE" value="15/02/26 - 18h30" />
<MESSAGE value="16/02/26 - 18h30" />
<option name="LAST_COMMIT_MESSAGE" value="16/02/26 - 18h30" />
</component>
</project>

View File

@ -405,6 +405,13 @@ Nombre maximum de participants importable par csv
"""
MAX_PARTICIPANT_BY_CSV = 500
"""
Nombre maximum de ligne de note importable par csv
"""
MAX_IMPORT_LINE_NOTE_BY_CSV = 500
"""
Nombre maximum de clients de partner importable par csv
"""
@ -746,6 +753,18 @@ En termes de process, un document de type devis peut avoir le un des statuts ci-
PARTNER_QUOTATION_STATUS = ['-1', '0', '1', '2', '3', '4']
"""
Les Facture :
En termes de process, une facture peut avoir le statut de :
-1 => Annulé
0 => Brouillon
1 => Confirmé
vide => Confirmé
"""
PARTNER_INVOICE_STATUS = ['-1', '0', '1', '',]
"""
Pour mettre en place un système de configuration global, on va definir les valeur acceptée
"""

File diff suppressed because it is too large Load Diff

View File

@ -15036,7 +15036,13 @@ def Invoice_Create_Secure_E_Document(diction):
else:
user['order_line_montant_hors_taxes'] = "0"
user['update_date'] = retval['update_date']
if( "date_update" in retval.keys() ):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['update_by'] = str(my_partner['_id'])
user['partner_owner_recid'] = retval['partner_owner_recid']
@ -16956,7 +16962,7 @@ def Update_SessionFormation_Relance_Automation_Setup(diction):
{"xxx._id": ObjectId(str(diction['automation_relance_relance_auto_id']))},
]
)
print(" ## update 03 = ", update.modified_count)
print(" ## update = ", update.modified_count)
"""
# Ajout de l'evenement dans l'historique
"""

122
main.py
View File

@ -10689,6 +10689,107 @@ def Create_Invoice_Avoir_Total():
"""
API permet de créer une facture depuis l'ecran des factures
"""
@app.route('/myclass/api/Add_Partner_Draft_Invoice/', methods=['POST','GET'])
@crossdomain(origin='*')
def Add_Partner_Draft_Invoice():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Add_Partner_Draft_Invoice payload = ",payload)
status, retval , list_credit_note = partner_invoice.Add_Partner_Draft_Invoice(payload)
return jsonify(status=status, message=retval, list_credit_note = list_credit_note)
"""
API permet de mettre à jour une facture
important ceci tant qu'elle est au statut 'draft'
"""
@app.route('/myclass/api/Update_Partner_Draft_Invoice/', methods=['POST','GET'])
@crossdomain(origin='*')
def Update_Partner_Draft_Invoice():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Update_Partner_Draft_Invoice payload = ",payload)
status, retval = partner_invoice.Update_Partner_Draft_Invoice(payload)
return jsonify(status=status, message=retval)
"""
API permet d'annuler un facture qui est statut 'draft
"""
@app.route('/myclass/api/Cancel_Partner_Draft_Invoice/', methods=['POST','GET'])
@crossdomain(origin='*')
def Cancel_Partner_Draft_Invoice():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Cancel_Partner_Draft_Invoice payload = ",payload)
status, retval = partner_invoice.Cancel_Partner_Draft_Invoice(payload)
return jsonify(status=status, message=retval)
"""
API permet la suppression d'une facture qui est statut 'draft'
"""
@app.route('/myclass/api/Delete_Partner_Draft_Invoice/', methods=['POST','GET'])
@crossdomain(origin='*')
def Delete_Partner_Draft_Invoice():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Delete_Partner_Draft_Invoice payload = ",payload)
status, retval = partner_invoice.Delete_Partner_Draft_Invoice(payload)
return jsonify(status=status, message=retval)
"""
API permet d'ajouter des lignes à une facture qui existe et qui est au statut : draft
"""
@app.route('/myclass/api/Add_Update_Partner_Draft_Invoice_Line/', methods=['POST','GET'])
@crossdomain(origin='*')
def Add_Update_Partner_Draft_Invoice_Line():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Add_Update_Partner_Draft_Invoice_Line payload = ",payload)
status, retval = partner_invoice.Add_Update_Partner_Draft_Invoice_Line(payload)
return jsonify(status=status, message=retval)
"""
API permet la Suppression d'une LIGNE DE facture qui est statut 'draft'
"""
@app.route('/myclass/api/Delete_Partner_Draft_Invoice_Line/', methods=['POST','GET'])
@crossdomain(origin='*')
def Delete_Partner_Draft_Invoice_Line():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Delete_Partner_Draft_Invoice_Line payload = ",payload)
status, retval = partner_invoice.Delete_Partner_Draft_Invoice_Line(payload)
return jsonify(status=status, message=retval)
"""
API permet la Confirmation d'un brouillon de facture et transformation en facture reelle.
La facture doit etre au statut 'Draft', puis passer au statut confirmé
"""
@app.route('/myclass/api/Confirm_Partner_Invoice_Header_And_Lines/', methods=['POST','GET'])
@crossdomain(origin='*')
def Confirm_Partner_Invoice_Header_And_Lines():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Confirm_Partner_Invoice_Header_And_Lines payload = ",payload)
status, retval = partner_invoice.Confirm_Partner_Invoice_Header_And_Lines(payload)
return jsonify(status=status, message=retval)
"""
API pour ajouter / mettre à jour une unité d'enseignement (UE) à une formation
"""
@ -11743,6 +11844,27 @@ def Export_To_Excel_List_Apprenant_Notes_With_Filter(token, list_session_id, lis
"""
API pour importer les notes d'une évaluation
"""
@app.route('/myclass/api/Import_Evaluation_Notes_mass/', methods=['POST','GET'])
@crossdomain(origin='*')
def Import_Evaluation_Notes_mass():
# On recupere le corps (payload) de la requete
payload = mycommon.strip_dictionary (request.form.to_dict())
print(" ### Import_Evaluation_Notes_mass payload = ",payload)
#print(request.files)
if request.method == 'POST':
# Create variable for uploaded file
f = request.files['File']
localStatus, message = note_evaluation_mgt.Import_Evaluation_Notes_mass(f, MYSY_GV.TEMPORARY_DIRECTORY_V2, payload)
return jsonify(status=localStatus, message=message)
"""
API pour verifier la disponibilité d'une ressource sur un creneau donnée dans l'agenda
"""

View File

@ -1072,7 +1072,6 @@ def Get_Given_Evaluation_Planification(diction):
return False, " Impossible de récupérer le types d'évaluation "
"""
Supprimer une evaluation planifiée
@ -2096,10 +2095,6 @@ def Send_Evaluation_Convocation_Participant_By_PDF(diction):
"""
Mise à jour note evaluation
Cette fonction met à jour la note d'un inscrit ou groupe d'inscrit.
@ -2180,9 +2175,9 @@ def Update_Participant_Evaluation_Note(diction):
new_data['note'] = "-1"
if ("publish" in val.keys() and str(val['publish']) == "false"):
new_data['publish'] = False
new_data['publish'] = "0"
elif ("publish" in val.keys() and str(val['publish']) == "true"):
new_data['publish'] = True
new_data['publish'] = "1"
else:
new_data['publish'] = "0"
@ -3040,7 +3035,7 @@ def Export_To_Excel_List_Participant_To_Evaluation(diction):
tab_exported_fields_header = ["formation", "classe", "evaluation_code","evaluation_titre",
"evaluation_eval_date_heure_debut", "evaluation_eval_date_heure_fin", "nom_apprenant",
"prenom_apprenant", "email_apprenant", "evaluation_note",]
"prenom_apprenant", "email_apprenant", "evaluation_note", "publie"]
# Create a workbook and add a worksheet.
@ -3173,6 +3168,16 @@ def Export_To_Excel_List_Participant_To_Evaluation(diction):
worksheet.write(row, column, user['note'])
column += 1
# Champ : publié
if( "publish" in user.keys() and user['publish'] == "1"):
worksheet.write(row, column, "1")
elif ("publish" in user.keys() and user['publish'] == "0"):
worksheet.write(row, column, "0")
else:
worksheet.write(row, column, "0")
column += 1
workbook.close()
@ -3873,3 +3878,529 @@ def Export_To_Excel_List_Apprenant_Notes_With_Filter(diction):
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'exporter les notes de l'apprenant"
"""
Importer des notes d'une évaluation
"""
def Import_Evaluation_Notes_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', 'evaluation_id', 'max_note', 'type_notation']
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 participants annulée")
return False, " Verifier votre API"
'''
Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
On controle que les champs obligatoires sont presents dans la liste
'''
field_list_obligatoire = ['token', 'evaluation_id', 'max_note', 'type_notation']
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 la liste des arguments ")
return False, " Verifier votre API, Toutes les informations techniques ne sont pas fournies"
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 l'evaluation est valide
"""
is_evaluation_valide = MYSY_GV.dbname['note_evaluation'].count_documents(
{"_id": ObjectId(str(diction['evaluation_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (is_evaluation_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant de l'évaluation n'est pas valide ")
return False, " L'identifiant de l'évaluation n'est pas valide "
evaluation_data = MYSY_GV.dbname['note_evaluation'].find_one(
{"_id": ObjectId(str(diction['evaluation_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
status, saved_file = mycommon.Upload_Save_CSV_File(file, Folder)
if (status == False):
mycommon.myprint("Impossible de récupérer correctement le fichier à importer")
return False, "Impossible d'importer la liste des participants, le nom du fichier est incorrect "
# " Lecture du fichier "
# print(" Lecture du fichier : "+saved_file)
nb_line = 0
""""
update du 21/08/23 : Controle de l'integrité du fichier
"""
local_controle_status, local_controle_message = Controle_Import_Evaluation_Notes_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',
skipinitialspace=True)
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 = ['evaluation_code', 'classe', 'nom_apprenant', 'prenom_apprenant', 'email_apprenant',
'evaluation_note', 'publie', 'formation', 'evaluation_eval_date_heure_debut', 'evaluation_eval_date_heure_fin',
'evaluation_titre']
# Controle du nombre de lignes dans le fichier.
total_rows = len(df)
if (total_rows > MYSY_GV.MAX_IMPORT_LINE_NOTE_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_IMPORT_LINE_NOTE_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, " L'entête du fichier csv. La Colonne '" + val + "' n'est pas acceptée"
# Verification des champs obligatoires dans le fichier
field_list_obligatoire_file = ['evaluation_code', 'classe', 'nom_apprenant', 'prenom_apprenant', 'email_apprenant',
'evaluation_note', 'publie', ]
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)
tab_participant_note = []
for n in x:
mydata = {}
mydata['evaluation_code'] = str(df['evaluation_code'].values[n]).strip()
mydata['classe'] = str(df['classe'].values[n]).strip()
mydata['nom_apprenant'] = str(df['nom_apprenant'].values[n]).strip().lower()
mydata['email_apprenant'] = str(df['email_apprenant'].values[n]).strip().lower()
mydata['evaluation_note'] = str(df['evaluation_note'].values[n]).strip()
tmp_publie = str(df['publie'].values[n]).strip()
if (mydata['evaluation_code'] and mydata['classe'] and mydata['email_apprenant']):
if (tmp_publie not in ['0', '1', '']):
mycommon.myprint(
str(inspect.stack()[0][3]) + "Ligne : " + str(
n + 2) + ": La valeur 'publié' est invalide ")
return False, "Ligne : " + str(
n + 2) + ": La valeur 'publié' est invalide. Valeurs acceptées : '0', '1', '' "
if (tmp_publie == "1"):
mydata['publie'] = "true"
else:
mydata['publie'] = "false"
mydata['email'] = str(df['email_apprenant'].values[n]).strip().lower()
regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
if (not re.fullmatch(regex, str(mydata['email_apprenant']))):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Ligne : " + str(n + 2) + " : L'adresse email " + str(
mydata['email']) + " est invalide")
return False, " Ligne : " + str(n + 2) + " : L'adresse email -" + str(
mydata['email_apprenant']) + "- est invalide"
mydata['token'] = str(my_token)
"""
Verifier la validité de evaluation_code
"""
is_valide_evaluation_code = MYSY_GV.dbname['note_evaluation'].count_documents(
{'code': {'$regex': '^' + mycommon.regex_replace_cartere(str(mydata['evaluation_code'])) + '$',
"$options": "i"},
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (is_valide_evaluation_code != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + "Ligne : " + str(
n + 2) + ": Le code de l'évaluation est invalide ")
return False, "Ligne : " + str(n + 2) + ": Le code de l'évaluation est invalide ."
evaluation_data = MYSY_GV.dbname['note_evaluation'].find_one(
{'code': {'$regex': '^' + mycommon.regex_replace_cartere(str(mydata['evaluation_code'])) + '$',
"$options": "i"},
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
"""
Verifier la validité de promotion_code
"""
is_valide_promotion_code = MYSY_GV.dbname['session_formation'].count_documents(
{'code_session': {
'$regex': '^' + mycommon.regex_replace_cartere(str(mydata['classe'])) + '$',
"$options": "i"},
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_valide_promotion_code != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + "Ligne : " + str(
n + 2) + ": Le code de la promotion est invalide ")
return False, "Ligne : " + str(n + 2) + ": Le code de la promotion est invalide ."
promotion_data = MYSY_GV.dbname['session_formation'].find_one(
{'code_session': {
'$regex': '^' + mycommon.regex_replace_cartere(str(mydata['classe'])) + '$',
"$options": "i"},
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
"""
Verifier la validité de l'inscrit
"""
is_valide_inscrit = MYSY_GV.dbname['inscription'].count_documents(
{'email': {'$regex': '^' + mycommon.regex_replace_cartere(str(mydata['email_apprenant'])) + '$',
"$options": "i"},
'session_id': str(promotion_data['_id']),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (is_valide_inscrit != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + "Ligne : " + str(
n + 2) + ": L'email, le nom et le code promotion ne correspondent pas à un inscrit valide.")
return False, "Ligne : " + str(
n + 2) + ": L'email, le nom et le code promotion ne correspondent pas à un inscrit valide."
inscrit_data = MYSY_GV.dbname['inscription'].find_one(
{'email': {'$regex': '^' + mycommon.regex_replace_cartere(str(mydata['email'])) + '$',
"$options": "i"},
'session_id': str(promotion_data['_id']),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
"""
Recuperer la ligne de 'note_evaluation_participant' associé à cet inscrit
"""
note_evaluation_participant_data = MYSY_GV.dbname['note_evaluation_participant'].find_one(
{'evaluation_id': str(evaluation_data['_id']),
'inscription_id': str(inscrit_data['_id']),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (note_evaluation_participant_data is None or '_id' not in note_evaluation_participant_data.keys()):
mycommon.myprint(
str(inspect.stack()[0][3]) + "Ligne : " + str(
n + 2) + ": Aucune évaluation valide pour cette ligne")
return False, "Ligne : " + str(
n + 2) + ": Aucune évaluation valide pour cette ligne"
clean_dict = {k: mydata[k] for k in mydata if (str(mydata[k]) != "nan")}
local_node_note = {}
local_node_note['_id'] = str(note_evaluation_participant_data['_id'])
local_node_note['note'] = str(mydata['evaluation_note'])
local_node_note['publish'] = str(mydata['publie'])
tab_participant_note.append(local_node_note)
local_diction = {}
local_diction['token'] = str(diction['token'])
local_diction['evaluation_id'] = str(diction['evaluation_id'])
local_diction['tab_participant_note'] = str(tab_participant_note)
print("#### diction to import notes ", local_diction)
status, retval = Update_Participant_Evaluation_Note(local_diction)
if (status is False):
return status, retval
print(str(total_rows) + " participants ont été inserés")
return True, str(total_rows) + " ligne(s) de note mises à 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 d'importer les notes en masse "
"""
Fonction de controle du fichier
"""
def Controle_Import_Evaluation_Notes_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', 'evaluation_id', 'max_note', 'type_notation']
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 participants annulée")
return False, " Verifier votre API"
'''
Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
On controle que les champs obligatoires sont presents dans la liste
'''
field_list_obligatoire = ['token', 'evaluation_id', 'max_note', 'type_notation']
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 la liste des arguments ")
return False, " Verifier votre API, Toutes les informations techniques ne sont pas fournies"
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
partner_recid = str(my_partner['recid'])
df = pd.read_csv(saved_file, encoding='utf8', on_bad_lines='skip', sep=';', encoding_errors='ignore',
skipinitialspace=True)
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 = ['evaluation_code', 'classe', 'nom_apprenant', 'prenom_apprenant', 'email_apprenant',
'evaluation_note', 'publie', 'formation', 'evaluation_eval_date_heure_debut', 'evaluation_eval_date_heure_fin',
'evaluation_titre']
# Controle du nombre de lignes dans le fichier.
total_rows = len(df)
if (total_rows > MYSY_GV.MAX_IMPORT_LINE_NOTE_BY_CSV):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le fichier comporte plus de " + str(
MYSY_GV.MAX_IMPORT_LINE_NOTE_BY_CSV) + " lignes.")
return False, " Le fichier comporte plus de " + str(MYSY_GV.MAX_IMPORT_LINE_NOTE_BY_CSV) + " lignes."
# print(" ### df.columns = ", df.columns)
for val in df.columns:
# print(" ### val = ", val)
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 = ['evaluation_code', 'classe', 'nom_apprenant', 'prenom_apprenant', 'email_apprenant',
'evaluation_note', 'publie', ]
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)
for n in x:
mydata = {}
mydata['evaluation_code'] = str(df['evaluation_code'].values[n]).strip()
mydata['classe'] = str(df['classe'].values[n]).strip()
mydata['nom_apprenant'] = str(df['nom_apprenant'].values[n]).strip().lower()
mydata['email_apprenant'] = str(df['email_apprenant'].values[n]).strip().lower()
mydata['evaluation_note'] = str(df['evaluation_note'].values[n]).strip()
if( diction['type_notation'] == "num"):
local_price_status, local_status_retval = mycommon.IsFloat(str(mydata['evaluation_note']))
if (local_price_status is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + "Ligne : " + str(
n + 2) + ": La note doit être une valeur numérique ")
return False, "Ligne : " + str(
n + 2) + ": La note doit être une valeur numérique "
if( float(str(local_status_retval)) > float( diction['max_note'])):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Ligne : " + str(
n + 2) + ": La note "+str(mydata['evaluation_note'])+" ne doit pas dépasser la valeur de "+str(diction['max_note']))
return False, " Ligne : " + str(
n + 2) + " : La note "+str(mydata['evaluation_note'])+" ne doit pas dépasser la valeur de "+str(diction['max_note'])
tmp_publie = str(df['publie'].values[n]).strip()
if( mydata['evaluation_code'] and mydata['classe'] and mydata['email_apprenant'] ):
if (tmp_publie not in ['0', '1', '']):
mycommon.myprint(
str(inspect.stack()[0][3]) + "Ligne : " + str(
n + 2) + ": La valeur 'publié' est invalide ")
return False, "Ligne : " + str(
n + 2) + ": La valeur 'publié' est invalide. Valeurs acceptées : '0', '1', '' "
if (tmp_publie == "1"):
mydata['publie'] = "true"
else:
mydata['publie'] = "false"
mydata['email'] = str(df['email_apprenant'].values[n]).strip().lower()
regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
if (not re.fullmatch(regex, str(mydata['email_apprenant']))):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Ligne : " + str(n + 2) + " : L'adresse email " + str(
mydata['email']) + " est invalide")
return False, " Ligne : " + str(n + 2) + " : L'adresse email -" + str(
mydata['email_apprenant']) + "- est invalide"
mydata['token'] = str(my_token)
"""
Verifier la validité de evaluation_code
"""
is_valide_evaluation_code = MYSY_GV.dbname['note_evaluation'].count_documents(
{'code': {'$regex': '^'+mycommon.regex_replace_cartere(str(mydata['evaluation_code']))+'$', "$options": "i"},
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (is_valide_evaluation_code != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + "Ligne : " + str(
n + 2) + ": Le code de l'évaluation est invalide ")
return False, "Ligne : " + str(n + 2) + ": Le code de l'évaluation est invalide ."
evaluation_data = MYSY_GV.dbname['note_evaluation'].find_one(
{'code': {'$regex': '^'+mycommon.regex_replace_cartere(str(mydata['evaluation_code']))+'$', "$options": "i"},
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
"""
Verifier la validité de promotion_code
"""
is_valide_promotion_code = MYSY_GV.dbname['session_formation'].count_documents(
{'code_session': {'$regex': '^'+mycommon.regex_replace_cartere(str(mydata['classe']))+'$', "$options": "i"},
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (is_valide_promotion_code != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + "Ligne : " + str(
n + 2) + ": Le code de la promotion est invalide ")
return False, "Ligne : " + str(n + 2) + ": Le code de la promotion est invalide ."
promotion_data = MYSY_GV.dbname['session_formation'].find_one(
{'code_session': {'$regex': '^'+mycommon.regex_replace_cartere(str(mydata['classe']))+'$', "$options": "i"},
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
"""
Verifier la validité de l'inscrit
"""
is_valide_inscrit = MYSY_GV.dbname['inscription'].count_documents(
{'email': {'$regex': '^'+mycommon.regex_replace_cartere(str(mydata['email_apprenant']))+'$', "$options": "i"},
'session_id': str(promotion_data['_id']),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (is_valide_inscrit != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + "Ligne : " + str(
n + 2) + ": L'email, le nom et le code promotion ne correspondent pas à un inscrit valide.")
return False, "Ligne : " + str(
n + 2) + ": L'email, le nom et le code promotion ne correspondent pas à un inscrit valide."
inscrit_data = MYSY_GV.dbname['inscription'].find_one(
{'email': {'$regex': '^' + mycommon.regex_replace_cartere(str(mydata['email'])) + '$', "$options": "i"},
'session_id': str(promotion_data['_id']),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
"""
Recuperer la ligne de 'note_evaluation_participant' associé à cet inscrit
"""
note_evaluation_participant_data = MYSY_GV.dbname['note_evaluation_participant'].find_one(
{'evaluation_id': str(evaluation_data['_id']),
'inscription_id': str(inscrit_data['_id']),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (note_evaluation_participant_data is None or '_id' not in note_evaluation_participant_data.keys()):
mycommon.myprint(
str(inspect.stack()[0][3]) + "Ligne : " + str(
n + 2) + ": Aucune évaluation valide pour cette ligne")
return False, "Ligne : " + str(
n + 2) + ": Aucune évaluation valide pour cette ligne"
return True, str(total_rows) + " lignes de notes 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 contrôler le fichier des notes à importer en masse "

File diff suppressed because it is too large Load Diff

View File

@ -3831,8 +3831,12 @@ def Get_Given_Partner_Order_Lines(diction):
else:
user['order_line_taux_taxe'] = "20"
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['update_date'] = retval['update_date']
user['partner_owner_recid'] = retval['partner_owner_recid']
user['order_line_type'] = retval['order_line_type']
user['order_line_status'] = retval['order_line_status']
@ -4003,7 +4007,14 @@ def Get_Given_Partner_Order_Lines(diction):
else:
user['order_line_montant_hors_taxes'] = "0"
user['update_date'] = retval['update_date']
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['partner_owner_recid'] = retval['partner_owner_recid']
user['order_line_type'] = retval['order_line_type']
user['order_line_status'] = retval['order_line_status']
@ -4184,7 +4195,12 @@ def Get_Given_Partner_Order_Lines_From_order_ref_interne(diction):
user['order_line_montant_hors_taxes'] = "0"
user['update_date'] = retval['update_date']
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['partner_owner_recid'] = retval['partner_owner_recid']
user['order_line_type'] = retval['order_line_type']
user['order_line_status'] = retval['order_line_status']
@ -4349,7 +4365,15 @@ def Get_Given_Partner_Order_Lines_From_order_ref_interne(diction):
else:
user['order_line_montant_hors_taxes'] = "0"
user['update_date'] = retval['update_date']
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['partner_owner_recid'] = retval['partner_owner_recid']
user['order_line_type'] = retval['order_line_type']
user['order_line_status'] = retval['order_line_status']
@ -5070,7 +5094,13 @@ def Get_Given_Line_Of_Partner_Order_Lines(diction):
user['valide'] = retval['valide']
user['locked'] = retval['locked']
user['update_date'] = retval['update_date']
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['partner_owner_recid'] = retval['partner_owner_recid']
user['order_line_type'] = retval['order_line_type']
user['order_line_status'] = retval['order_line_status']
@ -5242,7 +5272,13 @@ def Get_Given_Line_Of_Partner_Order_Lines(diction):
else:
user['order_line_montant_hors_taxes'] = "0"
user['update_date'] = retval['update_date']
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['partner_owner_recid'] = retval['partner_owner_recid']
user['order_line_type'] = retval['order_line_type']
user['order_line_status'] = retval['order_line_status']
@ -5770,7 +5806,13 @@ def GerneratePDF_Partner_Order(diction):
else:
user['order_line_montant_hors_taxes'] = "0"
user['update_date'] = retval['update_date']
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['partner_owner_recid'] = retval['partner_owner_recid']
user['order_line_type'] = retval['order_line_type']
user['order_line_status'] = retval['order_line_status']
@ -5946,7 +5988,14 @@ def GerneratePDF_Partner_Order(diction):
else:
user['order_line_montant_hors_taxes'] = "0"
user['update_date'] = retval['update_date']
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['partner_owner_recid'] = retval['partner_owner_recid']
user['order_line_type'] = retval['order_line_type']
user['order_line_status'] = retval['order_line_status']
@ -6302,7 +6351,13 @@ def Gernerate_Stock_PDF_Partner_Order(diction):
else:
user['order_line_montant_hors_taxes'] = "0"
user['update_date'] = retval['update_date']
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['partner_owner_recid'] = retval['partner_owner_recid']
user['order_line_type'] = retval['order_line_type']
user['order_line_status'] = retval['order_line_status']
@ -6477,7 +6532,14 @@ def Gernerate_Stock_PDF_Partner_Order(diction):
else:
user['order_line_montant_hors_taxes'] = "0"
user['update_date'] = retval['update_date']
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['partner_owner_recid'] = retval['partner_owner_recid']
user['order_line_type'] = retval['order_line_type']
user['order_line_status'] = retval['order_line_status']
@ -6811,7 +6873,13 @@ def Send_Partner_Order_By_Email(tab_files, Folder, diction):
else:
user['order_line_montant_hors_taxes'] = "0"
user['update_date'] = retval['update_date']
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['partner_owner_recid'] = retval['partner_owner_recid']
user['order_line_type'] = retval['order_line_type']
user['order_line_status'] = retval['order_line_status']
@ -6984,7 +7052,12 @@ def Send_Partner_Order_By_Email(tab_files, Folder, diction):
else:
user['order_line_montant_hors_taxes'] = "0"
user['update_date'] = retval['update_date']
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['partner_owner_recid'] = retval['partner_owner_recid']
user['order_line_type'] = retval['order_line_type']
user['order_line_status'] = retval['order_line_status']
@ -8799,7 +8872,13 @@ def Send_Quotation_Remind_Level1(diction):
else:
user['order_line_montant_hors_taxes'] = "0"
user['update_date'] = retval['update_date']
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['partner_owner_recid'] = retval['partner_owner_recid']
user['order_line_type'] = retval['order_line_type']
user['order_line_status'] = retval['order_line_status']
@ -8973,7 +9052,13 @@ def Send_Quotation_Remind_Level1(diction):
else:
user['order_line_montant_hors_taxes'] = "0"
user['update_date'] = retval['update_date']
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['partner_owner_recid'] = retval['partner_owner_recid']
user['order_line_type'] = retval['order_line_type']
user['order_line_status'] = retval['order_line_status']