24/12/2024 - 22h
parent
262c86eb44
commit
af9d74d4c8
|
@ -1,12 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="10/12/2024 - 22h">
|
||||
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="14/12/2024 - 14h">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/GlobalVariable.py" beforeDir="false" afterPath="$PROJECT_DIR$/GlobalVariable.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/E_Sign_Document.py" beforeDir="false" afterPath="$PROJECT_DIR$/E_Sign_Document.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Inscription_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/Inscription_mgt.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$/attached_file_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/attached_file_mgt.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ela_factures_mgt.py" beforeDir="false" afterPath="$PROJECT_DIR$/ela_factures_mgt.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ela_user_account.py" beforeDir="false" afterPath="$PROJECT_DIR$/ela_user_account.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/partner_client.py" beforeDir="false" afterPath="$PROJECT_DIR$/partner_client.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$/prj_common.py" beforeDir="false" afterPath="$PROJECT_DIR$/prj_common.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/tools_cherif/mysy_openai_file.py" beforeDir="false" afterPath="$PROJECT_DIR$/tools_cherif/mysy_openai_file.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/user_session.py" beforeDir="false" afterPath="$PROJECT_DIR$/user_session.py" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
|
@ -77,13 +87,6 @@
|
|||
<option name="presentableId" value="Default" />
|
||||
<updated>1680804787304</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00369" summary="11/08/2024 - 12h32s">
|
||||
<created>1723371666599</created>
|
||||
<option name="number" value="00369" />
|
||||
<option name="presentableId" value="LOCAL-00369" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1723371666602</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00370" summary="dd">
|
||||
<created>1723488781960</created>
|
||||
<option name="number" value="00370" />
|
||||
|
@ -420,7 +423,14 @@
|
|||
<option name="project" value="LOCAL" />
|
||||
<updated>1733865023239</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="418" />
|
||||
<task id="LOCAL-00418" summary="14/12/2024 - 14h">
|
||||
<created>1734181586199</created>
|
||||
<option name="number" value="00418" />
|
||||
<option name="presentableId" value="LOCAL-00418" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1734181586200</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="419" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="Vcs.Log.Tabs.Properties">
|
||||
|
@ -462,7 +472,6 @@
|
|||
</option>
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<MESSAGE value="08/09/2024 - 21h" />
|
||||
<MESSAGE value="08/09/2024 - 21terth" />
|
||||
<MESSAGE value="12/09/2024 - 13:00" />
|
||||
<MESSAGE value="15/09/2024 - 18:00" />
|
||||
|
@ -487,6 +496,7 @@
|
|||
<MESSAGE value="27/11/2024 : 12h30" />
|
||||
<MESSAGE value="08/12/2024 - 12h" />
|
||||
<MESSAGE value="10/12/2024 - 22h" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="10/12/2024 - 22h" />
|
||||
<MESSAGE value="14/12/2024 - 14h" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="14/12/2024 - 14h" />
|
||||
</component>
|
||||
</project>
|
|
@ -104,6 +104,7 @@ Add document du signe
|
|||
def Create_E_Document(diction):
|
||||
try:
|
||||
diction = mycommon.strip_dictionary(diction)
|
||||
print(" #### Create_E_Document diction = ", diction)
|
||||
|
||||
"""
|
||||
Verification des input acceptés
|
||||
|
@ -198,6 +199,7 @@ def Create_E_Document(diction):
|
|||
|
||||
new_diction['file_cononical_name'] = cononic_name
|
||||
|
||||
print(" ### new_diction aaa = ", new_diction)
|
||||
val = MYSY_GV.dbname['e_document_signe'].insert_one(new_diction)
|
||||
|
||||
|
||||
|
@ -700,7 +702,7 @@ def Create_E_Signature_For_E_Document(file_img=None, Folder=None, diction=None):
|
|||
mycommon.myprint(str(saved_file))
|
||||
return False, str(saved_file)
|
||||
|
||||
print(" signature manuelle = ", saved_file)
|
||||
#print(" signature manuelle = ", saved_file)
|
||||
with open(saved_file, "rb") as imageFile:
|
||||
image_signature_manuelle_string = base64.b64encode(imageFile.read()).decode()
|
||||
|
||||
|
@ -742,10 +744,13 @@ def Create_E_Signature_For_E_Document(file_img=None, Folder=None, diction=None):
|
|||
|
||||
e_document_data = MYSY_GV.dbname['e_document_signe'].find_one(qry)
|
||||
|
||||
#print(" ### e_document_data = ", e_document_data)
|
||||
|
||||
e_docment_type = ""
|
||||
if( "type" in e_document_data.keys() and e_document_data['type']):
|
||||
e_docment_type = e_document_data['type']
|
||||
|
||||
#print(" ### e_docment_type = ", e_docment_type)
|
||||
|
||||
local_signature_digitale = ""
|
||||
if ("email_destinataire" in e_document_data.keys() and e_document_data['email_destinataire']):
|
||||
|
@ -767,7 +772,7 @@ def Create_E_Signature_For_E_Document(file_img=None, Folder=None, diction=None):
|
|||
|
||||
# Calculating the digital signature
|
||||
msg.encrypt(key=public_key)
|
||||
print(f"Digital Signature: {msg.digitalsignature}")
|
||||
#print(f"Digital Signature: {msg.digitalsignature}")
|
||||
|
||||
# The message is still clear
|
||||
#print(f"Message: {msg.message}")
|
||||
|
@ -776,7 +781,7 @@ def Create_E_Signature_For_E_Document(file_img=None, Folder=None, diction=None):
|
|||
decrypt = PKCS1_OAEP.new(key=private_key)
|
||||
# Decrypting the message with the PKCS1_OAEP object
|
||||
decrypted_message = decrypt.decrypt(msg.digitalsignature)
|
||||
print(f"decrypted_message: {decrypted_message}")
|
||||
#print(f"decrypted_message: {decrypted_message}")
|
||||
|
||||
# We recalculate the hash of the message using the same hash function
|
||||
calcHash = calculateHash(msg.message)
|
||||
|
@ -1272,9 +1277,12 @@ def Create_E_Signature_For_E_Document(file_img=None, Folder=None, diction=None):
|
|||
|
||||
new_file['file_name'] = str(orig_file_name)
|
||||
new_file['status'] = "1"
|
||||
new_file['type_document'] = str(e_docment_type)
|
||||
|
||||
if( e_document_date_2['related_collection'] == "quotation"):
|
||||
new_file['object_owner_collection'] = "partner_client"
|
||||
new_file['object_owner_id'] = str(quotation_client_data['_id'])
|
||||
|
||||
else:
|
||||
new_file['object_owner_collection'] = e_document_date_2['related_collection']
|
||||
new_file['object_owner_id'] = e_document_date_2['related_collection_id']
|
||||
|
@ -1469,7 +1477,7 @@ def Create_E_Signature_For_E_Invoice(file_img=None, Folder=None, diction=None):
|
|||
|
||||
# Calculating the digital signature
|
||||
msg.encrypt(key=public_key)
|
||||
print(f"Digital Signature: {msg.digitalsignature}")
|
||||
#print(f"Digital Signature: {msg.digitalsignature}")
|
||||
|
||||
# The message is still clear
|
||||
# print(f"Message: {msg.message}")
|
||||
|
@ -1478,7 +1486,7 @@ def Create_E_Signature_For_E_Invoice(file_img=None, Folder=None, diction=None):
|
|||
decrypt = PKCS1_OAEP.new(key=private_key)
|
||||
# Decrypting the message with the PKCS1_OAEP object
|
||||
decrypted_message = decrypt.decrypt(msg.digitalsignature)
|
||||
print(f"decrypted_message: {decrypted_message}")
|
||||
#print(f"decrypted_message: {decrypted_message}")
|
||||
|
||||
# We recalculate the hash of the message using the same hash function
|
||||
calcHash = calculateHash(msg.message)
|
||||
|
@ -1842,6 +1850,8 @@ def Create_E_Signature_For_E_Invoice(file_img=None, Folder=None, diction=None):
|
|||
|
||||
new_file['file_name'] = str(orig_file_name)
|
||||
new_file['status'] = "1"
|
||||
new_file['type_document'] = str(type_document)
|
||||
|
||||
if (e_document_date_2['related_collection'] == "quotation"):
|
||||
new_file['object_owner_collection'] = "partner_client"
|
||||
new_file['object_owner_id'] = str(quotation_client_data['_id'])
|
||||
|
@ -2251,3 +2261,4 @@ def Get_Given_E_Document_Signed_No_Token(diction):
|
|||
exc_type, exc_obj, exc_tb = sys.exc_info()
|
||||
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
|
||||
return False, " Impossible de récupérer le document électronique "
|
||||
|
||||
|
|
|
@ -2719,7 +2719,7 @@ def AddStagiairetoClass_mass(file=None, Folder=None, diction=None):
|
|||
|
||||
clean_dict = {k: mydata[k] for k in mydata if ( str(mydata[k]) != "nan") }
|
||||
|
||||
#print( "#### clean_dict ", clean_dict)
|
||||
print( "#### clean_dict 02 ", clean_dict)
|
||||
status, retval = AddStagiairetoClass(clean_dict)
|
||||
|
||||
if( status is False ):
|
||||
|
@ -3526,7 +3526,7 @@ def AddStagiairetoClass_mass_for_many_session(file=None, Folder=None, diction=No
|
|||
|
||||
mydata['price'] = local_price
|
||||
|
||||
type_apprenant = ""
|
||||
type_apprenant = "0"
|
||||
if ("type_apprenant" in df.keys()):
|
||||
if (str(df['type_apprenant'].values[n])):
|
||||
type_apprenant = str(df['type_apprenant'].values[n]).strip()
|
||||
|
@ -3545,7 +3545,7 @@ def AddStagiairetoClass_mass_for_many_session(file=None, Folder=None, diction=No
|
|||
|
||||
clean_dict = {k: mydata[k] for k in mydata if ( str(mydata[k]) != "nan") }
|
||||
|
||||
#print( "#### clean_dict tt ", clean_dict)
|
||||
print( "#### clean_dict tt 01 ", clean_dict)
|
||||
status, retval = AddStagiairetoClass(clean_dict)
|
||||
|
||||
if( status is False ):
|
||||
|
@ -3748,9 +3748,6 @@ def Controle_AddStagiairetoClass_mass_for_many_session(saved_file=None, Folder=N
|
|||
En gros : que la formation en question a bien une session du meme code
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
modefinancement = ""
|
||||
if ("modefinancement" in df.keys()):
|
||||
if (str(df['modefinancement'].values[n])):
|
||||
|
@ -9348,7 +9345,7 @@ def Sent_Convention_Stagiaire_By_Email(tab_files, Folder, diction):
|
|||
new_e_document_diction['file_cononical_name'] = cononic_name
|
||||
new_e_document_diction['type'] = "convention"
|
||||
|
||||
|
||||
print(" ### 022 new_e_document_diction = ", new_e_document_diction)
|
||||
|
||||
local_status_e_doc, local_retval_e_doc = E_Sign_Document.Create_E_Document(new_e_document_diction)
|
||||
|
||||
|
@ -11270,6 +11267,7 @@ def Sent_Convention_Stagiaire_By_Email_By_Partner_client(tab_files_name_full_pat
|
|||
new_e_document_diction['file_cononical_name'] = cononic_name
|
||||
new_e_document_diction['type'] = "convention"
|
||||
|
||||
print(" ### 011 new_e_document_diction = ", new_e_document_diction)
|
||||
local_status_e_doc, local_retval_e_doc = E_Sign_Document.Create_E_Document(new_e_document_diction)
|
||||
|
||||
if(local_status_e_doc is False ):
|
||||
|
|
11190
Log/log_file.log
11190
Log/log_file.log
File diff suppressed because one or more lines are too long
|
@ -12172,7 +12172,7 @@ def Invoice_Create_Secure_E_Document(diction):
|
|||
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)
|
||||
#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 ):
|
||||
|
|
|
@ -69,7 +69,10 @@ metadata :
|
|||
0 : downloaded
|
||||
1 : accepted
|
||||
-1 : rejected
|
||||
|
||||
|
||||
/!\ : 24/12/2024
|
||||
- type_document : le champs 'file_business_object' semble problematique, nous allons donc introduire un champs : 'type_document' qui permettra de savori si c'est un devis, une convention, etc
|
||||
(ce champs n'est pas obligatoire)
|
||||
"""
|
||||
def Store_User_Downloaded_File(file=None, Folder=None, diction=None):
|
||||
try:
|
||||
|
@ -80,7 +83,8 @@ def Store_User_Downloaded_File(file=None, Folder=None, diction=None):
|
|||
"""
|
||||
Verification des input acceptés
|
||||
"""
|
||||
field_list = ['token', 'file_business_object', 'file_name', 'status','object_owner_collection', 'object_owner_id']
|
||||
field_list = ['token', 'file_business_object', 'file_name', 'status','object_owner_collection',
|
||||
'object_owner_id', 'type_document']
|
||||
incom_keys = diction.keys()
|
||||
for val in incom_keys:
|
||||
if val not in field_list and val.startswith('my_') is False:
|
||||
|
@ -141,6 +145,11 @@ def Store_User_Downloaded_File(file=None, Folder=None, diction=None):
|
|||
if diction['object_owner_collection']:
|
||||
object_owner_collection = diction['object_owner_collection']
|
||||
|
||||
type_document = ""
|
||||
if ("type_document" in diction.keys()):
|
||||
if diction['type_document']:
|
||||
type_document = diction['type_document']
|
||||
|
||||
object_owner_id = ""
|
||||
if ("object_owner_id" in diction.keys()):
|
||||
if diction['object_owner_id']:
|
||||
|
@ -164,6 +173,7 @@ def Store_User_Downloaded_File(file=None, Folder=None, diction=None):
|
|||
mydata['file_business_object'] = file_business_object
|
||||
mydata['date_update'] = str(datetime.now())
|
||||
mydata['file_name'] = file.filename
|
||||
mydata['type_document'] = type_document
|
||||
mydata['full_path'] = Global_file_name
|
||||
mydata['file_extention'] = file_extention
|
||||
mydata['object_owner_collection'] = object_owner_collection
|
||||
|
@ -194,6 +204,9 @@ def Store_User_Downloaded_File(file=None, Folder=None, diction=None):
|
|||
|
||||
"""
|
||||
Cette fonction est la copie de la première a l'exception qu'il s'agit d'une utilisation interne
|
||||
/!\ : 24/12/2024
|
||||
- type_document : le champs 'file_business_object' semble problematique, nous allons donc introduire un champs : 'type_document' qui permettra de savori si c'est un devis, une convention, etc
|
||||
(ce champs n'est pas obligatoire)
|
||||
"""
|
||||
def Internal_Usage_Store_User_Downloaded_File(Folder=None, diction=None):
|
||||
try:
|
||||
|
@ -205,7 +218,7 @@ def Internal_Usage_Store_User_Downloaded_File(Folder=None, diction=None):
|
|||
Verification des input acceptés
|
||||
"""
|
||||
field_list = ['token', 'file_business_object', 'file_name', 'status','object_owner_collection', 'object_owner_id',
|
||||
'file_name_to_store']
|
||||
'file_name_to_store', 'type_document']
|
||||
incom_keys = diction.keys()
|
||||
for val in incom_keys:
|
||||
if val not in field_list and val.startswith('my_') is False:
|
||||
|
@ -276,6 +289,11 @@ def Internal_Usage_Store_User_Downloaded_File(Folder=None, diction=None):
|
|||
if diction['object_owner_id']:
|
||||
object_owner_id = diction['object_owner_id']
|
||||
|
||||
type_document = ""
|
||||
if ("type_document" in diction.keys()):
|
||||
if diction['type_document']:
|
||||
type_document = diction['type_document']
|
||||
|
||||
document_display_order = ""
|
||||
if ("document_display_order" in diction.keys()):
|
||||
if diction['document_display_order']:
|
||||
|
@ -286,6 +304,7 @@ def Internal_Usage_Store_User_Downloaded_File(Folder=None, diction=None):
|
|||
mydata['date_update'] = str(datetime.now())
|
||||
mydata['file_name'] = partial_file_name_without_folder
|
||||
mydata['full_path'] = Global_file_name
|
||||
mydata['type_document'] = type_document
|
||||
mydata['file_extention'] = file_extention
|
||||
mydata['object_owner_collection'] = object_owner_collection
|
||||
mydata['object_owner_id'] = object_owner_id
|
||||
|
@ -315,7 +334,7 @@ def Internal_Usage_Store_User_Downloaded_File(Folder=None, diction=None):
|
|||
|
||||
|
||||
"""
|
||||
Fonction de recuperation des pièces jointes d'objet
|
||||
Fonction de recuperation des pièces jointes d'objet en utilisant le 'file_name'
|
||||
"""
|
||||
|
||||
def Get_Stored_Downloaded_File(diction):
|
||||
|
@ -412,6 +431,113 @@ def Get_Stored_Downloaded_File(diction):
|
|||
return False, False
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Fonction de recuperation des pièces jointes d'objet en utilisant le '_id'
|
||||
"""
|
||||
|
||||
def Get_Stored_Downloaded_File_From_Id(diction):
|
||||
try:
|
||||
full_file_path = ""
|
||||
|
||||
diction = mycommon.strip_dictionary(diction)
|
||||
"""
|
||||
Verification des input acceptés
|
||||
"""
|
||||
|
||||
|
||||
field_list = ['token', '_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', '_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",
|
||||
|
||||
"""
|
||||
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
|
||||
|
||||
file_name = ""
|
||||
if ("file_name" in diction.keys()):
|
||||
if diction['file_name']:
|
||||
file_name = diction['file_name']
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Verifier la validité de l'identifiant
|
||||
"""
|
||||
is_valide_download_files = MYSY_GV.dbname["download_files"].count_documents({'_id':ObjectId(str(diction['_id'])),
|
||||
'valide':'1',
|
||||
'partner_owner_recid':my_partner['recid']})
|
||||
if(is_valide_download_files != 1 ):
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " L'identifiant du fichier est invalide ")
|
||||
return False, " L'identifiant du fichier est invalide ",
|
||||
|
||||
|
||||
is_valide_download_files_data = MYSY_GV.dbname["download_files"].find_one(
|
||||
{'_id': ObjectId(str(diction['_id'])),
|
||||
'valide': '1',
|
||||
'partner_owner_recid': my_partner['recid']})
|
||||
|
||||
|
||||
|
||||
file_name = ""
|
||||
if( "file_name" in is_valide_download_files_data.keys() ):
|
||||
file_name = is_valide_download_files_data['full_path']
|
||||
|
||||
if( not file_name ):
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][
|
||||
3]) + " - Fichier invalide = ", str(file_name))
|
||||
|
||||
return False, " Fichier invalide "
|
||||
|
||||
full_path = str(file_name)
|
||||
|
||||
|
||||
|
||||
if os.path.exists(full_path):
|
||||
print(" ### full_path = ", full_path)
|
||||
return True, send_file(full_path, as_attachment=True)
|
||||
|
||||
else:
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][
|
||||
3]) + " Fichier invalide (2)= ", str(full_path))
|
||||
|
||||
return False, " Fichier invalide (2) "
|
||||
|
||||
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, False
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Fonction qui test la recuperation
|
||||
d'un fichier stocké sur le serveur
|
||||
|
@ -448,7 +574,9 @@ def test_get_stored_file():
|
|||
|
||||
|
||||
"""
|
||||
Recuperation de la liste des fichiers stocké
|
||||
Recuperation de la liste des fichiers stocké par :
|
||||
- object_owner_collection
|
||||
- object_owner_id
|
||||
"""
|
||||
def Get_List_object_owner_collection_Stored_Files(diction):
|
||||
try:
|
||||
|
@ -466,15 +594,7 @@ def Get_List_object_owner_collection_Stored_Files(diction):
|
|||
inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas")
|
||||
return False, " Les informations fournies sont incorrectes",
|
||||
|
||||
"""
|
||||
Verification des champs obligatoires
|
||||
"""
|
||||
field_list_obligatoire = ['token', 'object_owner_collection', 'object_owner_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",
|
||||
|
||||
|
||||
"""
|
||||
Verification de l'identité et autorisation de l'entité qui
|
||||
|
@ -501,19 +621,37 @@ def Get_List_object_owner_collection_Stored_Files(diction):
|
|||
if diction['object_owner_id']:
|
||||
object_owner_id = diction['object_owner_id']
|
||||
|
||||
"""
|
||||
Verification des champs obligatoires
|
||||
24/12/2024 :
|
||||
Les 2 valeurs ('object_owner_collection', 'object_owner_id') ne sont plus obligatories, mais au moins une doit
|
||||
etre fourni
|
||||
"""
|
||||
if( str(object_owner_collection).strip() == "" and str(object_owner_id).strip() == ""):
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " Il manque des informations obligatoires ")
|
||||
return False, " Les informations fournies sont incorrectes",
|
||||
|
||||
my_query = {}
|
||||
my_query['object_owner_collection'] = object_owner_collection
|
||||
my_query['object_owner_id'] = object_owner_id
|
||||
if( object_owner_collection ):
|
||||
my_query['object_owner_collection'] = object_owner_collection
|
||||
|
||||
if(object_owner_id ):
|
||||
my_query['object_owner_id'] = object_owner_id
|
||||
|
||||
my_query['valide'] = "1"
|
||||
my_query['partner_owner_recid'] = str(my_partner['recid'])
|
||||
|
||||
|
||||
#print(" ##### myquery = " + str(my_query))
|
||||
print(" ##### myquery = " + str(my_query))
|
||||
RetObject = []
|
||||
nb_val = 0
|
||||
for retval in MYSY_GV.dbname['download_files'].find(my_query).sort([("document_display_order", pymongo.DESCENDING)]):
|
||||
for retval in MYSY_GV.dbname['download_files'].find(my_query).sort([("_id", pymongo.DESCENDING), ("document_display_order", pymongo.DESCENDING)]):
|
||||
ret_file = {}
|
||||
ret_file['id'] = str(nb_val)
|
||||
ret_file['_id'] = str(retval['_id'])
|
||||
ret_file['file_business_object'] = retval['file_business_object']
|
||||
|
||||
if ("file_business_object" in retval.keys()):
|
||||
ret_file['file_business_object'] = retval['file_business_object']
|
||||
|
||||
|
@ -540,6 +678,38 @@ def Get_List_object_owner_collection_Stored_Files(diction):
|
|||
else:
|
||||
ret_file['file_cononical_name'] = "Anonyme"
|
||||
|
||||
if ("type_document" in retval.keys()):
|
||||
ret_file['type_document'] = retval['type_document']
|
||||
else:
|
||||
ret_file['type_document'] = "Autre"
|
||||
|
||||
if ("file_extention" in retval.keys()):
|
||||
ret_file['file_extention'] = retval['file_extention']
|
||||
else:
|
||||
ret_file['file_extention'] = "file_extention"
|
||||
|
||||
|
||||
"""
|
||||
Recuperation du nom du client
|
||||
"""
|
||||
client_raison_sociale = ""
|
||||
client_nom = ""
|
||||
|
||||
if( "object_owner_id" in retval.keys() and retval["object_owner_id"]):
|
||||
partner_client_data = MYSY_GV.dbname['partner_client'].find_one({'_id':ObjectId(str( retval["object_owner_id"]))},{'raison_sociale':1, 'nom':1})
|
||||
|
||||
if(partner_client_data and "raison_sociale" in partner_client_data.keys()):
|
||||
client_raison_sociale = partner_client_data['raison_sociale']
|
||||
|
||||
if (partner_client_data and "nom" in partner_client_data.keys()):
|
||||
client_nom = partner_client_data['nom']
|
||||
|
||||
ret_file['client_raison_sociale'] = client_raison_sociale
|
||||
ret_file['client_nom'] = client_nom
|
||||
|
||||
|
||||
|
||||
|
||||
RetObject.append(mycommon.JSONEncoder().encode(ret_file))
|
||||
nb_val = nb_val + 1
|
||||
|
||||
|
@ -553,6 +723,7 @@ def Get_List_object_owner_collection_Stored_Files(diction):
|
|||
return False, False
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Suppression d'un fichier stocké
|
||||
"""
|
||||
|
|
|
@ -1305,6 +1305,7 @@ def GetCustomerInvoice(diction):
|
|||
|
||||
if os.path.exists("./temp_direct/"+str(my_invoice_name)):
|
||||
path = "./temp_direct/"+str(my_invoice_name)
|
||||
|
||||
return send_file(path, as_attachment=True)
|
||||
|
||||
|
||||
|
|
|
@ -175,14 +175,14 @@ def desable_user_objectif(diction):
|
|||
return False, " Impossible de desactiver l'objectif"
|
||||
|
||||
# recuperation des paramettre
|
||||
user_token = ""
|
||||
partner_token = ""
|
||||
user_recid = ""
|
||||
if ("token" in diction.keys()):
|
||||
if diction['token']:
|
||||
user_token = diction['token']
|
||||
partner_token = diction['token']
|
||||
|
||||
# Recuperation du recid de l'utilisateur
|
||||
user_recid = mycommon.get_user_recid_from_token(user_token)
|
||||
user_recid = mycommon.get_user_recid_from_token(partner_token)
|
||||
if user_recid is False:
|
||||
mycommon.myprint(" Impossible de récupérer le token de l'utilisateur")
|
||||
return False, " Impossible de desactiver l'objectif utilisateur"
|
||||
|
@ -260,16 +260,16 @@ def add_update_user_objectif(diction):
|
|||
return False, " Impossible de mettre à jour l'objectif utilisateur"
|
||||
|
||||
# recuperation des paramettre
|
||||
user_token = ""
|
||||
partner_token = ""
|
||||
user_recid = ""
|
||||
|
||||
if ("token" in diction.keys()):
|
||||
if diction['token']:
|
||||
user_token = diction['token']
|
||||
partner_token = diction['token']
|
||||
|
||||
# Recuperation du recid de l'utilisateur
|
||||
user_recid = mycommon.get_user_recid_from_token(user_token)
|
||||
if user_token is False :
|
||||
user_recid = mycommon.get_user_recid_from_token(partner_token)
|
||||
if partner_token is False :
|
||||
mycommon.myprint(" Impossible de récupérer le token de l'utilisateur")
|
||||
return False, " Impossible de mettre à jour l'objectif utilisateur"
|
||||
|
||||
|
@ -382,16 +382,16 @@ def add_update_user_profile(diction):
|
|||
return False, " Impossible de mettre à jour l'objectif utilisateur"
|
||||
|
||||
# recuperation des paramettre
|
||||
user_token = ""
|
||||
partner_token = ""
|
||||
user_recid = ""
|
||||
|
||||
if ("token" in diction.keys()):
|
||||
if diction['token']:
|
||||
user_token = diction['token']
|
||||
partner_token = diction['token']
|
||||
|
||||
# Recuperation du recid de l'utilisateur
|
||||
user_recid = mycommon.get_user_recid_from_token(user_token)
|
||||
if user_token is False :
|
||||
user_recid = mycommon.get_user_recid_from_token(partner_token)
|
||||
if partner_token is False :
|
||||
mycommon.myprint(" Impossible de récupérer le token de l'utilisateur")
|
||||
return False, " Impossible de mettre à jour l'objectif utilisateur"
|
||||
|
||||
|
@ -473,16 +473,16 @@ def Get_user_profile(diction):
|
|||
return False, " Impossible de récupérer le profil de l'utilisateur"
|
||||
|
||||
# recuperation des paramettre
|
||||
user_token = ""
|
||||
partner_token = ""
|
||||
user_recid = ""
|
||||
|
||||
if ("token" in diction.keys()):
|
||||
if diction['token']:
|
||||
user_token = diction['token']
|
||||
partner_token = diction['token']
|
||||
|
||||
# Recuperation du recid de l'utilisateur
|
||||
user_recid = mycommon.get_user_recid_from_token(user_token)
|
||||
if user_token is False :
|
||||
user_recid = mycommon.get_user_recid_from_token(partner_token)
|
||||
if partner_token is False :
|
||||
mycommon.myprint(" Impossible de récupérer le profil de l'utilisateur")
|
||||
return False, " Impossible de récupérer le profil de l'utilisateur"
|
||||
|
||||
|
@ -740,31 +740,29 @@ def update_user_account(diction):
|
|||
mycommon.myprint(str(inspect.stack()[0][3]) + " -L'email ou le token ne sont pas valident")
|
||||
return False, "L'email ou le token ne sont pas valident"
|
||||
|
||||
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
|
||||
if (local_status is not True):
|
||||
return local_status, my_partner
|
||||
|
||||
mycommon.myprint(" dictionnary = "+str(dictionnary))
|
||||
|
||||
'''
|
||||
ret_val = coll_name.find_and_modify(query={'email': str(diction['email']), 'locked': '0'},
|
||||
update={"$set":
|
||||
{'active': "1",
|
||||
"date_update": str(now),
|
||||
"adr_street":str(diction['adr_street']),
|
||||
"adr_city": str(diction['adr_city']),
|
||||
"adr_zip": str(diction['adr_zip']),
|
||||
"adr_country": str(diction['adr_country']),
|
||||
}
|
||||
}
|
||||
)
|
||||
'''
|
||||
# récupérer le recid en partant du token.
|
||||
user_recid = mycommon.get_user_recid_from_token(str(mytoken))
|
||||
"""
|
||||
23/12/2024 : Après avoir verifier la validité du token,
|
||||
on va aller chercher l'_id dans la collection 'user_account'
|
||||
"""
|
||||
|
||||
if user_recid is False :
|
||||
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer le user_recid")
|
||||
return False, "Impossible de mettre à jour le compte utilisateur"
|
||||
is_token_valide_for_one_user = MYSY_GV.dbname['user_account'].count_documents({'token':str(diction['token']),
|
||||
'active':'1', 'locked':'0',
|
||||
'partner_owner_recid':my_partner['recid']})
|
||||
if( is_token_valide_for_one_user != 1 ):
|
||||
mycommon.myprint(str(inspect.stack()[0][3]) + " Le token correspond a plusieurs au aucun utilisateur de la collection 'user_account' ")
|
||||
return False, "La session est invalide "
|
||||
|
||||
|
||||
ret_val = coll_name.find_one_and_update({'recid': str(user_recid), 'locked': '0'},
|
||||
|
||||
ret_val = coll_name.find_one_and_update({'token':str(diction['token']),
|
||||
'active':'1', 'locked':'0',
|
||||
'partner_owner_recid':my_partner['recid']},
|
||||
{"$set": dictionnary },
|
||||
return_document=ReturnDocument.AFTER
|
||||
)
|
||||
|
@ -821,7 +819,7 @@ def get_user_account(diction):
|
|||
|
||||
if retval is False:
|
||||
mycommon.myprint(str(inspect.stack()[0][3]) +" L'email ou le token ne sont pas valides")
|
||||
return False, "L'email ou le token ne sont pas valides"
|
||||
return False, "L'email ou le token ne sont pas valides (1)"
|
||||
|
||||
'''
|
||||
# Verification si compte utilisateur à ete activé
|
||||
|
@ -830,20 +828,32 @@ def get_user_account(diction):
|
|||
mycommon.myprint(str(inspect.stack()[0][3]) + " le user account n'est valide ou est verrouillé")
|
||||
return False, message
|
||||
'''
|
||||
|
||||
# récupérer le recid du user
|
||||
"""
|
||||
|
||||
# récupérer le _id de l'utilisation en partant du token
|
||||
user_recid = mycommon.get_user_recid_from_token(token_value)
|
||||
if user_recid is False :
|
||||
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de récupérer le recid du user")
|
||||
return False, "Impossible de récupérer les données de l'utilisateur"
|
||||
|
||||
|
||||
"""
|
||||
|
||||
coll_name = MYSY_GV.dbname['user_account']
|
||||
|
||||
RetObject = []
|
||||
for retVal in coll_name.find({'recid': user_recid, 'active':'1', 'locked':'0'}):
|
||||
mycommon.myprint(retVal)
|
||||
"""
|
||||
Si plusieurs personnes ont ce token, alors rejette la connexion, car pas normal.
|
||||
|
||||
Un token valide ne doit appartenir qu'a un et seul user
|
||||
"""
|
||||
cout_user_with_same_token = coll_name.count_documents({'token': str(token_value), 'locked': '0', 'active':'1'})
|
||||
|
||||
if( cout_user_with_same_token > 1 ):
|
||||
mycommon.myprint(str(inspect.stack()[0][3]) + " Violation des règles du token ")
|
||||
return False, "L'email ou le token ne sont pas valides (2) "
|
||||
|
||||
RetObject = []
|
||||
for retVal in coll_name.find({'token': str(token_value), 'locked': '0', 'active':'1'}):
|
||||
mycommon.myprint(retVal)
|
||||
user = retVal
|
||||
RetObject.append(JSONEncoder().encode(user))
|
||||
|
||||
|
@ -852,7 +862,7 @@ def get_user_account(diction):
|
|||
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 le user account"
|
||||
return False, " L'email ou le token ne sont pas valides "
|
||||
|
||||
|
||||
|
||||
|
@ -1060,7 +1070,7 @@ def Reset_user_pwd_by_token(diction):
|
|||
if (ret_val and ret_val['_id']):
|
||||
# Apres avoir changer le mot passe, desactivation tu token
|
||||
|
||||
coll_name = MYSY_GV.dbname['user_token']
|
||||
coll_name = MYSY_GV.dbname['partner_token']
|
||||
ret_val = coll_name.update_many({'recid': user_recid, 'valide': '1'},
|
||||
{"$set": {'valide': '0', 'date_update': str(datetime.now())}},
|
||||
)
|
||||
|
@ -1350,7 +1360,7 @@ Pour garder la coherence du systeme, cela revient à :
|
|||
3 - Desactiver le compte
|
||||
4 - Anomyser les tables annexe :
|
||||
a) articles_avis
|
||||
b) user_token
|
||||
b) partner_token
|
||||
'''
|
||||
def delete_user_account(diction):
|
||||
try:
|
||||
|
@ -1437,15 +1447,15 @@ def delete_user_account(diction):
|
|||
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de supprimer le compte utilisateur - table : user_account")
|
||||
return False, "Impossible de supprimer le compte utilisateur"
|
||||
|
||||
# Anonymisation de la table user_token ou se trouve aussi l'adresse email.
|
||||
# table : user_token
|
||||
user_token_coll_name = MYSY_GV.dbname['user_token']
|
||||
ret_val = user_token_coll_name.update_many({'recid': str(user_recid), },
|
||||
# Anonymisation de la table partner_token ou se trouve aussi l'adresse email.
|
||||
# table : partner_token
|
||||
partner_token_coll_name = MYSY_GV.dbname['partner_token']
|
||||
ret_val = partner_token_coll_name.update_many({'recid': str(user_recid), },
|
||||
{"$set": {'email':'Anonyme',
|
||||
'valide':'0',
|
||||
'date_update':str(datetime.now()) } },
|
||||
)
|
||||
mycommon.myprint(str(inspect.stack()[0][3]) + " - Table : user_token : "+str(ret_val.matched_count)+" ont été trouvées "
|
||||
mycommon.myprint(str(inspect.stack()[0][3]) + " - Table : partner_token : "+str(ret_val.matched_count)+" ont été trouvées "
|
||||
" "+str(ret_val.acknowledged)+" ont été modifiées")
|
||||
|
||||
# table : articles_avis
|
||||
|
@ -1455,7 +1465,7 @@ def delete_user_account(diction):
|
|||
'date_update':str(datetime.now()) }},
|
||||
)
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " - Table : user_token : " + str(ret_val.matched_count) + " ont été trouvées "
|
||||
str(inspect.stack()[0][3]) + " - Table : partner_token : " + str(ret_val.matched_count) + " ont été trouvées "
|
||||
" "+str(ret_val.acknowledged) + " ont été modifiées")
|
||||
|
||||
|
||||
|
@ -1705,8 +1715,8 @@ Cette Function permet de gerer la reunitialisation du passwd
|
|||
|
||||
que fait elle exactement :
|
||||
|
||||
0 - Desactivation de toutes les entrée dans la table : user_token pour le mail, s'il est valide
|
||||
1 - elle crée une entrée dans la table : user_token
|
||||
0 - Desactivation de toutes les entrée dans la table : partner_token pour le mail, s'il est valide
|
||||
1 - elle crée une entrée dans la table : partner_token
|
||||
- recid
|
||||
- email
|
||||
3 - envoyer un mail au user (si valide) avec le token : /ResetUserPwd/:tokenx
|
||||
|
@ -1789,14 +1799,14 @@ def InitUserPasswd(diction):
|
|||
update_field = {'valide': '0', 'date_update':str(datetime.now())}
|
||||
|
||||
|
||||
coll_name_token = MYSY_GV.dbname['user_token']
|
||||
coll_name_token = MYSY_GV.dbname['partner_token']
|
||||
ret_val_user_rech = coll_name_token.update_many(
|
||||
{'recid': retVal[0]['recid']},
|
||||
{"$set": update_field}
|
||||
)
|
||||
|
||||
if (ret_val_user_rech.matched_count <= 0):
|
||||
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de desactivier les token actifs dans table 'user_token' ")
|
||||
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de desactivier les token actifs dans table 'partner_token' ")
|
||||
return True, "La demande de reinitiation à été prise en compte"
|
||||
|
||||
|
||||
|
@ -1946,7 +1956,7 @@ def IsUserTokenValide(diction):
|
|||
if( myaccounttype == "1"):
|
||||
myquery['valide'] = '1'
|
||||
# il s'agit d'un compte utilisateur
|
||||
coll_name_token = MYSY_GV.dbname['user_token']
|
||||
coll_name_token = MYSY_GV.dbname['partner_token']
|
||||
|
||||
|
||||
tmp = coll_name_token.count_documents(myquery)
|
||||
|
|
108
main.py
108
main.py
|
@ -350,7 +350,7 @@ Cette api met à jour un compte utilisateur
|
|||
@crossdomain(origin='*')
|
||||
def update_user_account():
|
||||
payload = mycommon.strip_dictionary (request.form.to_dict())
|
||||
print(" ### payload = ", payload)
|
||||
print(" ### update_user_account payload = ", payload)
|
||||
status, retval = eua.update_user_account(payload)
|
||||
return jsonify(status=status, message=retval)
|
||||
|
||||
|
@ -4525,6 +4525,60 @@ def Get_Partner_Client_Communication_Contact_NO_TOKEN():
|
|||
|
||||
|
||||
|
||||
"""
|
||||
API pour l'intranet client : Creation du compte intranet d'un client
|
||||
"""
|
||||
@app.route('/myclass/api/Create_Partner_Client_Intranet_Account/', methods=['POST','GET'])
|
||||
@crossdomain(origin='*')
|
||||
def Create_Partner_Client_Intranet_Account():
|
||||
# On recupere le corps (payload) de la requete
|
||||
payload = mycommon.strip_dictionary (request.form.to_dict())
|
||||
print(" ### Create_Partner_Client_Intranet_Account : payload = ",payload)
|
||||
localStatus, message = partner_client.Create_Partner_Client_Intranet_Account(payload)
|
||||
return jsonify(status=localStatus, message=message)
|
||||
|
||||
|
||||
"""
|
||||
API pour l'intranet client : Mise à jour du pwd du compte intranet d'un client
|
||||
"""
|
||||
@app.route('/myclass/api/Update_Pwd_Partner_Client_Intranet_Account/', methods=['POST','GET'])
|
||||
@crossdomain(origin='*')
|
||||
def Update_Pwd_Partner_Client_Intranet_Account():
|
||||
# On recupere le corps (payload) de la requete
|
||||
payload = mycommon.strip_dictionary (request.form.to_dict())
|
||||
print(" ### Update_Pwd_Partner_Client_Intranet_Account : payload = ",payload)
|
||||
localStatus, message = partner_client.Update_Pwd_Partner_Client_Intranet_Account(payload)
|
||||
return jsonify(status=localStatus, message=message)
|
||||
|
||||
|
||||
|
||||
"""
|
||||
API pour l'intranet client : Désactivation du compte intranet d'un client
|
||||
"""
|
||||
@app.route('/myclass/api/Disable_Partner_Client_Intranet_Account/', methods=['POST','GET'])
|
||||
@crossdomain(origin='*')
|
||||
def Disable_Partner_Client_Intranet_Account():
|
||||
# On recupere le corps (payload) de la requete
|
||||
payload = mycommon.strip_dictionary (request.form.to_dict())
|
||||
print(" ### Disable_Partner_Client_Intranet_Account : payload = ",payload)
|
||||
localStatus, message = partner_client.Disable_Partner_Client_Intranet_Account(payload)
|
||||
return jsonify(status=localStatus, message=message)
|
||||
|
||||
|
||||
|
||||
"""
|
||||
API pour l'intranet client : Réactivation du compte intranet d'un client
|
||||
"""
|
||||
@app.route('/myclass/api/Enable_Partner_Client_Intranet_Account/', methods=['POST','GET'])
|
||||
@crossdomain(origin='*')
|
||||
def Enable_Partner_Client_Intranet_Account():
|
||||
# On recupere le corps (payload) de la requete
|
||||
payload = mycommon.strip_dictionary (request.form.to_dict())
|
||||
print(" ### Enable_Partner_Client_Intranet_Account : payload = ",payload)
|
||||
localStatus, message = partner_client.Enable_Partner_Client_Intranet_Account(payload)
|
||||
return jsonify(status=localStatus, message=message)
|
||||
|
||||
|
||||
|
||||
"""
|
||||
API qui permet de modifier un contact donnée (nested list) d'un client de partenaire
|
||||
|
@ -6801,10 +6855,9 @@ def Store_User_Downloaded_File():
|
|||
|
||||
|
||||
"""
|
||||
API de recuperartion des fichier telechargés par une user
|
||||
API de recuperartion des fichier telechargés par une user en utilisant le 'file_name'
|
||||
"""
|
||||
|
||||
|
||||
@app.route('/myclass/api/Get_Stored_Downloaded_File/<token>/<file_name>',methods=['POST', 'GET'])
|
||||
@crossdomain(origin='*')
|
||||
def Get_Stored_Downloaded_File(token, file_name):
|
||||
|
@ -6822,6 +6875,28 @@ def Get_Stored_Downloaded_File(token, file_name):
|
|||
|
||||
return retval
|
||||
|
||||
"""
|
||||
API de recuperartion des fichier telechargés par une user en utilisant le '_id'
|
||||
"""
|
||||
|
||||
|
||||
@app.route('/myclass/api/Get_Stored_Downloaded_File_From_Id/<token>/<doc_id>',methods=['POST', 'GET'])
|
||||
@crossdomain(origin='*')
|
||||
def Get_Stored_Downloaded_File_From_Id(token, doc_id):
|
||||
# On recupere le corps (payload) de la requete
|
||||
payload = {}
|
||||
payload['token'] = str(token)
|
||||
payload['_id'] = str(doc_id)
|
||||
|
||||
payload = mycommon.strip_dictionary(payload)
|
||||
|
||||
print(" ### Get_Stored_Downloaded_File_From_Id : payload = ",payload)
|
||||
status, retval = attached_file_mgt.Get_Stored_Downloaded_File_From_Id(payload)
|
||||
if (status is False):
|
||||
return ""
|
||||
|
||||
return retval
|
||||
|
||||
|
||||
|
||||
"""
|
||||
|
@ -11335,7 +11410,7 @@ def mysy_openai():
|
|||
|
||||
|
||||
"""
|
||||
API test mysy Open AI voice to text
|
||||
API mysy Open AI qui converti un fichier audio (mp3) en texte
|
||||
"""
|
||||
@app.route('/myclass/api/mysy_openai_voice_to_text/', methods=['POST','GET'])
|
||||
@crossdomain(origin='*')
|
||||
|
@ -11347,6 +11422,19 @@ def mysy_openai_voice_to_text():
|
|||
return jsonify(status=status, message=retval)
|
||||
|
||||
|
||||
"""
|
||||
API mysy Open AI qui converti un texte en fichier audio (mp3)
|
||||
"""
|
||||
@app.route('/myclass/api/mysy_openai_text_to_voice/', methods=['POST','GET'])
|
||||
@crossdomain(origin='*')
|
||||
def mysy_openai_text_to_voice():
|
||||
# On recupere le corps (payload) de la requete
|
||||
payload = mycommon.strip_dictionary (request.form.to_dict())
|
||||
print(" ### mysy_openai_voice_to_text payload zzzz = ")
|
||||
status, retval = mysy_openai_file.mysy_openai_text_to_voice(payload)
|
||||
return jsonify(status=status, message=retval)
|
||||
|
||||
|
||||
|
||||
'''
|
||||
API test recuperation fichier blob audio
|
||||
|
@ -11427,6 +11515,18 @@ def mysy_openai_summarize_text():
|
|||
status, retval = mysy_ia.mysy_openai_summarize_text(payload)
|
||||
return jsonify(status=status, message=retval)
|
||||
|
||||
"""
|
||||
API qui permet d'envoyer le fichier audio créer par l'ia de mysy
|
||||
"""
|
||||
@app.route('/myclass/api/send_mysy_openai_to_voice_file/', methods=['POST','GET'])
|
||||
@crossdomain(origin='*')
|
||||
def send_mysy_openai_to_voice_file():
|
||||
# On recupere le corps (payload) de la requete
|
||||
payload = mycommon.strip_dictionary(request.form.to_dict())
|
||||
payload = {}
|
||||
print(" ### payload Send_mysy_openai_to_voice_file = ", payload)
|
||||
return mysy_openai_file.send_mysy_openai_to_voice_file(payload)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -1289,7 +1289,7 @@ def Get_Partner_List_Partner_Client(diction):
|
|||
# Recuperation des données du partenaire
|
||||
local_status, my_partner = mycommon.get_partner_data_from_token(token)
|
||||
if (local_status is False):
|
||||
mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données de l'utilisateur ")
|
||||
mycommon.myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données de l'utilisateur")
|
||||
return False, str(inspect.stack()[0][3]) + " - impossible de récupérer les données de l'utilisateur. "
|
||||
|
||||
"""
|
||||
|
@ -2494,3 +2494,496 @@ def Get_Partner_Client_Communication_Contact_NO_TOKEN(diction):
|
|||
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
|
||||
return False, " Impossible de récupérer la liste des contacts du client inclus dans la communication "
|
||||
|
||||
|
||||
"""
|
||||
Intranet client :
|
||||
Cette fonction permet de créer le compte intranet d'un client
|
||||
regles :
|
||||
- le login est forcement l'email princiape du client.
|
||||
|
||||
"""
|
||||
|
||||
def Create_Partner_Client_Intranet_Account(diction):
|
||||
try:
|
||||
|
||||
diction = mycommon.strip_dictionary(diction)
|
||||
|
||||
"""
|
||||
Verification des input acceptés. les filtres accepté sont :
|
||||
- ref_interne,
|
||||
"""
|
||||
field_list = ['token', 'partner_client_id', 'default_pwd']
|
||||
|
||||
incom_keys = diction.keys()
|
||||
for val in incom_keys:
|
||||
if val not in field_list and val.startswith('my_') is False:
|
||||
mycommon.myprint(str(
|
||||
inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas")
|
||||
return False, " Les informations fournies sont incorrectes"
|
||||
|
||||
"""
|
||||
Verification des champs obligatoires
|
||||
"""
|
||||
field_list_obligatoire = ['token', 'partner_client_id', 'default_pwd']
|
||||
for val in field_list_obligatoire:
|
||||
if val not in diction:
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
|
||||
return False, " Les informations fournies sont incorrectes"
|
||||
|
||||
"""
|
||||
Verification de l'identité et autorisation de l'entité qui
|
||||
appelle cette API
|
||||
"""
|
||||
token = ""
|
||||
if ("token" in diction.keys()):
|
||||
if diction['token']:
|
||||
token = diction['token']
|
||||
|
||||
client_pwd = str(diction['default_pwd']).strip()
|
||||
|
||||
if( len(str(client_pwd)) <= 5):
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " Le mot de passe doit faire plus 5 caractère ")
|
||||
return False, " Le mot de passe doit faire plus 5 caractère "
|
||||
|
||||
if( " " in str(client_pwd) ):
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " Les espaces ne sont pas autorisés dans le mot de passe ")
|
||||
return False, " Les espaces ne sont pas autorisés dans le mot de passe "
|
||||
|
||||
|
||||
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_valide_client_partner = MYSY_GV.dbname['partner_client'].count_documents({'_id':ObjectId(str(diction['partner_client_id'])),
|
||||
'valide':'1', 'locked':'0',
|
||||
'partner_recid':my_partner['recid']})
|
||||
|
||||
if( is_valide_client_partner != 1 ):
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " L'identifiant du client est invalide ")
|
||||
return False, " L'identifiant du client est invalide "
|
||||
|
||||
is_valide_client_partner_data = MYSY_GV.dbname['partner_client'].find_one(
|
||||
{'_id': ObjectId(str(diction['partner_client_id'])),
|
||||
'valide': '1', 'locked': '0',
|
||||
'partner_recid': my_partner['recid']})
|
||||
|
||||
client_email = is_valide_client_partner_data['email']
|
||||
client_id = str(is_valide_client_partner_data['_id'])
|
||||
|
||||
client_nom = ""
|
||||
if( "nom" in is_valide_client_partner_data.keys() ):
|
||||
client_nom = is_valide_client_partner_data['nom']
|
||||
|
||||
client_telephone = ""
|
||||
if ("telephone" in is_valide_client_partner_data.keys()):
|
||||
client_telephone = is_valide_client_partner_data['telephone']
|
||||
|
||||
client_adr_adresse = ""
|
||||
if ("adr_adresse" in is_valide_client_partner_data.keys()):
|
||||
client_adr_adresse = is_valide_client_partner_data['adr_adresse']
|
||||
|
||||
client_adr_code_postal = ""
|
||||
if ("adr_code_postal" in is_valide_client_partner_data.keys()):
|
||||
client_adr_code_postal = is_valide_client_partner_data['adr_code_postal']
|
||||
|
||||
client_adr_ville = ""
|
||||
if ("adr_ville" in is_valide_client_partner_data.keys()):
|
||||
client_adr_ville = is_valide_client_partner_data['adr_ville']
|
||||
|
||||
client_adr_pays = ""
|
||||
if ("adr_pays" in is_valide_client_partner_data.keys()):
|
||||
client_adr_pays = is_valide_client_partner_data['adr_pays']
|
||||
|
||||
|
||||
now = str(datetime.now())
|
||||
|
||||
|
||||
|
||||
new_data = {}
|
||||
new_data['nom'] = client_nom
|
||||
new_data['adr_street'] = client_adr_adresse
|
||||
new_data['adr_city'] = client_adr_ville
|
||||
new_data['adr_zip'] = client_adr_code_postal
|
||||
new_data['adr_country'] = client_adr_pays
|
||||
new_data['mob_phone'] = client_telephone
|
||||
|
||||
|
||||
|
||||
new_data['email'] = client_email
|
||||
new_data['pwd'] = str(client_pwd)
|
||||
new_data['recid'] = str(my_partner['recid'])
|
||||
new_data['partner_client_id'] = str(is_valide_client_partner_data['_id'])
|
||||
new_data['partner_owner_recid'] = str(my_partner['recid'])
|
||||
new_data['locked'] = "0"
|
||||
new_data['active'] = "1"
|
||||
new_data['date_creation'] = now
|
||||
new_data['created_by'] = str(my_partner['_id'])
|
||||
new_data['type'] = "user"
|
||||
|
||||
inserted_id = MYSY_GV.dbname['user_account'].insert_one(new_data).inserted_id
|
||||
if (not inserted_id):
|
||||
mycommon.myprint(
|
||||
" Impossible de créer le compte intranet du client (1) ")
|
||||
return False, " Impossible de créer le compte intranet du client (1) "
|
||||
|
||||
"""
|
||||
Mettre à jour le compte les données client (collection : partner_client )
|
||||
avec l'_id du compte
|
||||
"""
|
||||
|
||||
new_client_data = {}
|
||||
new_client_data['intranet_account_id'] = str(inserted_id)
|
||||
new_client_data['date_update'] = str(now)
|
||||
new_client_data['update_by'] = str(my_partner['_id'])
|
||||
|
||||
ret_val = MYSY_GV.dbname['partner_client'].find_one_and_update(
|
||||
{'_id': ObjectId(str(client_id)), },
|
||||
{"$set": new_client_data},
|
||||
upsert=False,
|
||||
return_document=ReturnDocument.AFTER
|
||||
)
|
||||
|
||||
return True, " Le compte intranet du client a été correctement crée"
|
||||
|
||||
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 compte intranet du client "
|
||||
|
||||
|
||||
"""
|
||||
Intranet Client :
|
||||
Mettre à jour le mot de passe d'un compte client
|
||||
"""
|
||||
def Update_Pwd_Partner_Client_Intranet_Account(diction):
|
||||
try:
|
||||
|
||||
diction = mycommon.strip_dictionary(diction)
|
||||
|
||||
"""
|
||||
Verification des input acceptés. les filtres accepté sont :
|
||||
- ref_interne,
|
||||
"""
|
||||
field_list = ['token', 'partner_client_id', 'default_pwd']
|
||||
|
||||
incom_keys = diction.keys()
|
||||
for val in incom_keys:
|
||||
if val not in field_list and val.startswith('my_') is False:
|
||||
mycommon.myprint(str(
|
||||
inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas")
|
||||
return False, " Les informations fournies sont incorrectes"
|
||||
|
||||
"""
|
||||
Verification des champs obligatoires
|
||||
"""
|
||||
field_list_obligatoire = ['token', 'partner_client_id', 'default_pwd']
|
||||
for val in field_list_obligatoire:
|
||||
if val not in diction:
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
|
||||
return False, " Les informations fournies sont incorrectes"
|
||||
|
||||
"""
|
||||
Verification de l'identité et autorisation de l'entité qui
|
||||
appelle cette API
|
||||
"""
|
||||
token = ""
|
||||
if ("token" in diction.keys()):
|
||||
if diction['token']:
|
||||
token = diction['token']
|
||||
|
||||
client_pwd = str(diction['default_pwd']).strip()
|
||||
|
||||
if( len(str(client_pwd)) <= 5):
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " Le mot de passe doit faire plus 5 caractère ")
|
||||
return False, " Le mot de passe doit faire plus 5 caractère "
|
||||
|
||||
if( " " in str(client_pwd) ):
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " Les espaces ne sont pas autorisés dans le mot de passe ")
|
||||
return False, " Les espaces ne sont pas autorisés dans le mot de passe "
|
||||
|
||||
|
||||
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_valide_client_partner = MYSY_GV.dbname['partner_client'].count_documents({'_id':ObjectId(str(diction['partner_client_id'])),
|
||||
'valide':'1', 'locked':'0',
|
||||
'partner_recid':my_partner['recid']})
|
||||
|
||||
if( is_valide_client_partner != 1 ):
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " L'identifiant du client est invalide ")
|
||||
return False, " L'identifiant du client est invalide "
|
||||
|
||||
is_valide_client_partner_data = MYSY_GV.dbname['partner_client'].find_one(
|
||||
{'_id': ObjectId(str(diction['partner_client_id'])),
|
||||
'valide': '1', 'locked': '0',
|
||||
'partner_recid': my_partner['recid']})
|
||||
|
||||
|
||||
"""
|
||||
Verifier que le compte sur l'intranet existe et est valide
|
||||
"""
|
||||
|
||||
|
||||
|
||||
is_valide_client_intranet_account = MYSY_GV.dbname['user_account'].count_documents(
|
||||
{'_id': ObjectId(str(is_valide_client_partner_data['intranet_account_id'])),
|
||||
'active': '1', 'locked': '0',
|
||||
'recid': my_partner['recid']})
|
||||
|
||||
if (is_valide_client_intranet_account != 1):
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " L'identifiant du compte intranet du client est invalide ")
|
||||
return False, " L'identifiant du compte intranet du client est invalide "
|
||||
|
||||
|
||||
client_email = is_valide_client_partner_data['email']
|
||||
|
||||
now = str(datetime.now())
|
||||
|
||||
new_data = {}
|
||||
new_data['date_update'] = now
|
||||
new_data['update_by'] = str(my_partner['_id'])
|
||||
new_data['pwd'] = str(client_pwd)
|
||||
|
||||
ret_val = MYSY_GV.dbname['user_account'].find_one_and_update(
|
||||
{'_id': ObjectId(str(is_valide_client_partner_data['intranet_account_id'])),
|
||||
'active': '1', 'locked': '0',
|
||||
'recid': my_partner['recid']},
|
||||
{"$set": new_data},
|
||||
upsert=False,
|
||||
return_document=ReturnDocument.AFTER
|
||||
)
|
||||
|
||||
return True, " Le compte intranet du client a été correctement mis à jour"
|
||||
|
||||
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 compte intranet du client "
|
||||
|
||||
|
||||
"""
|
||||
Intranet client :
|
||||
Desactiver un compte
|
||||
(mettre active = 0 )
|
||||
"""
|
||||
def Disable_Partner_Client_Intranet_Account(diction):
|
||||
try:
|
||||
|
||||
diction = mycommon.strip_dictionary(diction)
|
||||
|
||||
"""
|
||||
Verification des input acceptés. les filtres accepté sont :
|
||||
- ref_interne,
|
||||
"""
|
||||
field_list = ['token', 'partner_client_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")
|
||||
return False, " Les informations fournies sont incorrectes"
|
||||
|
||||
"""
|
||||
Verification des champs obligatoires
|
||||
"""
|
||||
field_list_obligatoire = ['token', 'partner_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, " Les informations fournies sont incorrectes"
|
||||
|
||||
"""
|
||||
Verification de l'identité et autorisation de l'entité qui
|
||||
appelle cette API
|
||||
"""
|
||||
token = ""
|
||||
if ("token" in diction.keys()):
|
||||
if diction['token']:
|
||||
token = diction['token']
|
||||
|
||||
|
||||
|
||||
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
|
||||
if (local_status is not True):
|
||||
return local_status, my_partner
|
||||
|
||||
"""
|
||||
Verifier la validité du client
|
||||
"""
|
||||
is_valide_client_partner = MYSY_GV.dbname['partner_client'].count_documents({'_id':ObjectId(str(diction['partner_client_id'])),
|
||||
'valide':'1', 'locked':'0',
|
||||
'partner_recid':my_partner['recid']})
|
||||
|
||||
if( is_valide_client_partner != 1 ):
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " L'identifiant du client est invalide ")
|
||||
return False, " L'identifiant du client est invalide "
|
||||
|
||||
is_valide_client_partner_data = MYSY_GV.dbname['partner_client'].find_one(
|
||||
{'_id': ObjectId(str(diction['partner_client_id'])),
|
||||
'valide': '1', 'locked': '0',
|
||||
'partner_recid': my_partner['recid']})
|
||||
|
||||
|
||||
"""
|
||||
Verifier que le compte sur l'intranet existe et est valide
|
||||
"""
|
||||
is_valide_client_intranet_account = MYSY_GV.dbname['user_account'].count_documents(
|
||||
{'_id': ObjectId(str(is_valide_client_partner_data['intranet_account_id'])),
|
||||
'active': '1', 'locked': '0',
|
||||
'recid': my_partner['recid']})
|
||||
|
||||
if (is_valide_client_intranet_account != 1):
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " L'identifiant du compte intranet du client est invalide ")
|
||||
return False, " L'identifiant du compte intranet du client est invalide "
|
||||
|
||||
|
||||
client_email = is_valide_client_partner_data['email']
|
||||
|
||||
now = str(datetime.now())
|
||||
|
||||
new_data = {}
|
||||
new_data['date_update'] = now
|
||||
new_data['update_by'] = str(my_partner['_id'])
|
||||
new_data['active'] = "0"
|
||||
|
||||
ret_val = MYSY_GV.dbname['user_account'].find_one_and_update(
|
||||
{'_id': ObjectId(str(is_valide_client_partner_data['intranet_account_id'])),
|
||||
'partner_owner_recid': str(my_partner['recid'])},
|
||||
{"$set": new_data},
|
||||
upsert=False,
|
||||
return_document=ReturnDocument.AFTER
|
||||
)
|
||||
|
||||
return True, " Le compte intranet du client a été correctement désactivé "
|
||||
|
||||
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 compte intranet du client "
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Intranet Client
|
||||
Reactivier un compte intranet client
|
||||
"""
|
||||
def Enable_Partner_Client_Intranet_Account(diction):
|
||||
try:
|
||||
|
||||
diction = mycommon.strip_dictionary(diction)
|
||||
|
||||
"""
|
||||
Verification des input acceptés. les filtres accepté sont :
|
||||
- ref_interne,
|
||||
"""
|
||||
field_list = ['token', 'partner_client_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")
|
||||
return False, " Les informations fournies sont incorrectes"
|
||||
|
||||
"""
|
||||
Verification des champs obligatoires
|
||||
"""
|
||||
field_list_obligatoire = ['token', 'partner_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, " Les informations fournies sont incorrectes"
|
||||
|
||||
"""
|
||||
Verification de l'identité et autorisation de l'entité qui
|
||||
appelle cette API
|
||||
"""
|
||||
token = ""
|
||||
if ("token" in diction.keys()):
|
||||
if diction['token']:
|
||||
token = diction['token']
|
||||
|
||||
|
||||
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
|
||||
if (local_status is not True):
|
||||
return local_status, my_partner
|
||||
|
||||
"""
|
||||
Verifier la validité du client
|
||||
"""
|
||||
is_valide_client_partner = MYSY_GV.dbname['partner_client'].count_documents({'_id':ObjectId(str(diction['partner_client_id'])),
|
||||
'valide':'1', 'locked':'0',
|
||||
'partner_recid':my_partner['recid']})
|
||||
|
||||
if( is_valide_client_partner != 1 ):
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " L'identifiant du client est invalide ")
|
||||
return False, " L'identifiant du client est invalide "
|
||||
|
||||
is_valide_client_partner_data = MYSY_GV.dbname['partner_client'].find_one(
|
||||
{'_id': ObjectId(str(diction['partner_client_id'])),
|
||||
'valide': '1', 'locked': '0',
|
||||
'partner_recid': my_partner['recid']})
|
||||
|
||||
|
||||
"""
|
||||
Verifier que le compte sur l'intranet existe et est valide
|
||||
"""
|
||||
is_valide_client_intranet_account = MYSY_GV.dbname['user_account'].count_documents(
|
||||
{'_id': ObjectId(str(is_valide_client_partner_data['intranet_account_id'])),
|
||||
'active': '1', 'locked': '0',
|
||||
'recid': my_partner['recid']})
|
||||
|
||||
if (is_valide_client_intranet_account != 1):
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " L'identifiant du compte intranet du client est invalide ")
|
||||
return False, " L'identifiant du compte intranet du client est invalide "
|
||||
|
||||
|
||||
client_email = is_valide_client_partner_data['email']
|
||||
|
||||
now = str(datetime.now())
|
||||
|
||||
new_data = {}
|
||||
new_data['date_update'] = now
|
||||
new_data['update_by'] = str(my_partner['_id'])
|
||||
new_data['active'] = "1"
|
||||
|
||||
ret_val = MYSY_GV.dbname['user_account'].find_one_and_update(
|
||||
{'_id': ObjectId(str(is_valide_client_partner_data['intranet_account_id'])),
|
||||
'partner_owner_recid': str(my_partner['recid'])},
|
||||
{"$set": new_data},
|
||||
upsert=False,
|
||||
return_document=ReturnDocument.AFTER
|
||||
)
|
||||
|
||||
return True, " Le compte intranet du client a été correctement activé "
|
||||
|
||||
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 compte intranet du client "
|
||||
|
||||
|
||||
|
|
|
@ -1401,7 +1401,7 @@ def Get_List_Partner_Invoice_with_filter(diction):
|
|||
if val not in field_list and val.startswith('my_') is False:
|
||||
mycommon.myprint(str(
|
||||
inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas")
|
||||
return False, " Les informations fournies sont incorrectes",
|
||||
return False, " Les informations fournies sont incorrectes", False
|
||||
|
||||
"""
|
||||
Verification des champs obligatoires
|
||||
|
@ -1411,7 +1411,7 @@ def Get_List_Partner_Invoice_with_filter(diction):
|
|||
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",
|
||||
return False, " Les informations fournies sont incorrectes", False
|
||||
|
||||
"""
|
||||
Verification de l'identité et autorisation de l'entité qui
|
||||
|
@ -1424,7 +1424,7 @@ def Get_List_Partner_Invoice_with_filter(diction):
|
|||
|
||||
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
|
||||
if (local_status is not True):
|
||||
return local_status, my_partner
|
||||
return local_status, my_partner, False
|
||||
|
||||
filt_client_nom = {}
|
||||
sub_filt_client_nom = {}
|
||||
|
@ -1507,7 +1507,7 @@ def Get_List_Partner_Invoice_with_filter(diction):
|
|||
mycommon.myprint(
|
||||
str(inspect.stack()[0][
|
||||
3]) + " La date de debut (filtre) n'est pas au format 'jj/mm/aaaa' ")
|
||||
return False, " La date de debut (filtre) n'est pas au format 'jj/mm/aaaa'"
|
||||
return False, " La date de debut (filtre) n'est pas au format 'jj/mm/aaaa'", False
|
||||
|
||||
filter_date_fin = ""
|
||||
if ("date_facture_fin" in diction.keys()):
|
||||
|
@ -1518,7 +1518,7 @@ def Get_List_Partner_Invoice_with_filter(diction):
|
|||
mycommon.myprint(
|
||||
str(inspect.stack()[0][
|
||||
3]) + " La date de fin (filtre) n'est pas au format 'jj/mm/aaaa' ")
|
||||
return False, " La date de fin (filtre) n'est pas au format 'jj/mm/aaaa'"
|
||||
return False, " La date de fin (filtre) n'est pas au format 'jj/mm/aaaa'", False
|
||||
|
||||
somme_header_ca_ht = 0
|
||||
nb_header_invoice = 0
|
||||
|
@ -1632,7 +1632,7 @@ def Get_List_Partner_Invoice_with_filter(diction):
|
|||
except Exception as e:
|
||||
exc_type, exc_obj, exc_tb = sys.exc_info()
|
||||
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
|
||||
return False, " Impossible de récupérer la liste des factures "
|
||||
return False, " Impossible de récupérer la liste des factures ", False
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1443,6 +1443,7 @@ def partner_login(diction):
|
|||
tokenfield['locked'] = '0'
|
||||
tokenfield['start_date'] = str(datetime.now())
|
||||
tokenfield['token'] = str(my_token)
|
||||
tokenfield['type'] = 'partner'
|
||||
|
||||
'''
|
||||
Insertion du nouveau token
|
||||
|
|
133
prj_common.py
133
prj_common.py
|
@ -261,7 +261,7 @@ puis verifie si la validité du trile (email, token, statut)
|
|||
def check_token_validity(email="", token=""):
|
||||
try :
|
||||
|
||||
coll_token = MYSY_GV.dbname['user_token']
|
||||
coll_token = MYSY_GV.dbname['partner_token']
|
||||
print(" check_token_validity token == "+str(token))
|
||||
tmp_count = coll_token.count_documents({ 'token': str(token), 'valide': '1'})
|
||||
if (tmp_count <= 0):
|
||||
|
@ -416,6 +416,9 @@ def get_parnter_stripe_stripe_paymentmethod_id_from_recid(recid = ""):
|
|||
|
||||
'''
|
||||
recuperation du recid du user
|
||||
|
||||
/!\ : 22/12/2024 : cette fonction es un peu bizarre.
|
||||
J'ai réecrée une fonction get_user_account_id_from_token qui retour _id de ligne au lieu du recid
|
||||
'''
|
||||
def get_user_recid_from_token(token = ""):
|
||||
try :
|
||||
|
@ -423,7 +426,7 @@ def get_user_recid_from_token(token = ""):
|
|||
myprint(" Le token est vide")
|
||||
return False
|
||||
|
||||
coll_token = MYSY_GV.dbname['user_token']
|
||||
coll_token = MYSY_GV.dbname['partner_token']
|
||||
tmp_val = coll_token.find({'token': str(token), 'valide': '1'})
|
||||
user_recid = tmp_val[0]['recid']
|
||||
return user_recid
|
||||
|
@ -433,14 +436,37 @@ def get_user_recid_from_token(token = ""):
|
|||
myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
|
||||
return False
|
||||
|
||||
|
||||
"""
|
||||
22/12/2024 :
|
||||
Cette fonction retourne l'_id depuis (user_account) en partant du token
|
||||
"""
|
||||
def get_user_account_id_from_token(token = ""):
|
||||
try :
|
||||
if len(str(token)) <= 0 :
|
||||
myprint(" Le token est vide")
|
||||
return False
|
||||
|
||||
coll_token = MYSY_GV.dbname['user_account']
|
||||
tmp_val = coll_token.find({'token': str(token), 'valide': '1', 'active':'1'})
|
||||
user_recid = tmp_val[0]['recid']
|
||||
return user_recid
|
||||
|
||||
except Exception as e:
|
||||
exc_type, exc_obj, exc_tb = sys.exc_info()
|
||||
myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
|
||||
return False
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Cette fonction retourne les données d'un user en partant du recid.
|
||||
return false si le recid est faux ou que le compte utilisateur n'est pas actif
|
||||
"""
|
||||
def get_partner_data_from_recid(user_recid = ""):
|
||||
try :
|
||||
|
||||
|
||||
if len(str(user_recid)) <= 0 :
|
||||
myprint(" Le partner_recid est vide")
|
||||
return False, ""
|
||||
|
@ -453,6 +479,7 @@ def get_partner_data_from_recid(user_recid = ""):
|
|||
|
||||
coll_token = MYSY_GV.dbname['partnair_account']
|
||||
|
||||
print(" FFFF = ",{'recid': str(user_recid), 'active': '1', 'locked':'0'} )
|
||||
|
||||
tmp_val = coll_token.find_one({'recid': str(user_recid), 'active': '1', 'locked':'0'})
|
||||
|
||||
|
@ -507,8 +534,26 @@ def get_connected_data_from_token(connected_token = ""):
|
|||
if (tmp_count <= 0):
|
||||
return False, "Le token est invalide"
|
||||
|
||||
coll_token = MYSY_GV.dbname['partnair_account']
|
||||
tmp_val = coll_token.find_one({'token': str(connected_token), 'active': '1', 'locked': '0'})
|
||||
token_data = coll_token.find_one({'token': str(connected_token), 'valide': '1', 'locked': '0'})
|
||||
|
||||
"""
|
||||
/!\ 21/12/2024 : en attendant de fusionner proprement les collection 'partnair_account' et 'user_account'
|
||||
on utiliser le champs 'partner_token['type'] pour savoir si on à faire un partner ou un user.
|
||||
|
||||
|
||||
Si c'est un user_account, on a recuperer son 'partner_owner_recid', puis aller chercher le données du partner associe
|
||||
|
||||
"""
|
||||
tmp_val = None
|
||||
|
||||
if( token_data and "type" in token_data.keys() and str(token_data['type']) == "user"):
|
||||
coll_token = MYSY_GV.dbname['user_account']
|
||||
tmp_val = coll_token.find_one({'token': str(connected_token), 'active': '1', 'locked': '0'})
|
||||
|
||||
else:
|
||||
coll_token = MYSY_GV.dbname['partnair_account']
|
||||
tmp_val = coll_token.find_one({'token': str(connected_token), 'active': '1', 'locked': '0'})
|
||||
|
||||
|
||||
return True, tmp_val
|
||||
|
||||
|
@ -527,12 +572,46 @@ def get_partner_data_from_token(token = ""):
|
|||
myprint(" Le token partner est vide")
|
||||
return False, ""
|
||||
|
||||
val_tmp = MYSY_GV.dbname['partnair_account'].count_documents({'token': str(token), 'active': '1', 'locked':'0'})
|
||||
if (val_tmp <= 0):
|
||||
return False, ""
|
||||
coll_token = MYSY_GV.dbname['partner_token']
|
||||
# print(" myquery pr demo_account = " + str(myquery))
|
||||
tmp_count = coll_token.count_documents({'token': str(token), 'valide': '1', 'locked': '0'})
|
||||
if (tmp_count <= 0):
|
||||
return False, "Le token est invalide"
|
||||
|
||||
ret_val = MYSY_GV.dbname['partnair_account'].find_one(
|
||||
{'token': str(token), 'active': '1', 'locked': '0'})
|
||||
token_data = coll_token.find_one({'token': str(token), 'valide': '1', 'locked': '0'})
|
||||
"""
|
||||
/!\ 21/12/2024 : en attendant de fusionner proprement les collection 'partnair_account' et 'user_account'
|
||||
on utiliser le champs 'partner_token['type'] pour savoir si on à faire un partner ou un user.
|
||||
|
||||
|
||||
Si c'est un user_account, on a recuperer son 'partner_owner_recid', puis aller chercher le données du partner associe
|
||||
|
||||
"""
|
||||
ret_val = None
|
||||
|
||||
if (token_data and "type" in token_data.keys() and str(token_data['type']) == "user"):
|
||||
coll_token = MYSY_GV.dbname['user_account']
|
||||
user_account_data = coll_token.find_one({'token': str(token), 'active': '1', 'locked': '0'},
|
||||
{"_id": 1, "partner_owner_recid": 1})
|
||||
|
||||
if (user_account_data and "partner_owner_recid" in user_account_data.keys() and user_account_data[
|
||||
'partner_owner_recid']):
|
||||
coll_token = MYSY_GV.dbname['partnair_account']
|
||||
ret_val = coll_token.find_one({'recid': str(user_account_data['partner_owner_recid']),
|
||||
'is_partner_admin_account': '1', 'active': '1', 'locked': '0'})
|
||||
|
||||
if (ret_val is None or '_id' not in ret_val.keys()):
|
||||
myprint(
|
||||
"ERRR : Connexion d'un compte de type utilisateur, mais erreur sur la configuration du partner_owner_recid")
|
||||
return False, "Impossible de récupérer les données de l'entité connectée"
|
||||
else:
|
||||
val_tmp = MYSY_GV.dbname['partnair_account'].count_documents(
|
||||
{'token': str(token), 'active': '1', 'locked': '0'})
|
||||
if (val_tmp <= 0):
|
||||
return False, ""
|
||||
|
||||
ret_val = MYSY_GV.dbname['partnair_account'].find_one(
|
||||
{'token': str(token), 'active': '1', 'locked': '0'})
|
||||
|
||||
return True, ret_val
|
||||
|
||||
|
@ -552,7 +631,7 @@ def get_user_email_from_token(token = ""):
|
|||
myprint(" Le token est vide")
|
||||
return False
|
||||
|
||||
coll_token = MYSY_GV.dbname['user_token']
|
||||
coll_token = MYSY_GV.dbname['partner_token']
|
||||
tmp_val = coll_token.find({'token': str(token), 'valide': '1'})
|
||||
user_email = tmp_val[0]['email']
|
||||
return user_email
|
||||
|
@ -603,13 +682,30 @@ def get_parnter_recid_from_token(token = ""):
|
|||
if( tmp_val is None ):
|
||||
return False
|
||||
|
||||
if ("recid" not in tmp_val.keys()):
|
||||
return False
|
||||
"""
|
||||
/!\ 21/12/2024 : en attendant de fusionner proprement les collection 'partnair_account' et 'user_account'
|
||||
on utiliser le champs 'partner_token['type'] pour savoir si on à faire un partner ou un user.
|
||||
|
||||
|
||||
Si c'est un user_account, on a recuperer son 'partner_owner_recid', puis aller chercher le données du partner associe
|
||||
|
||||
"""
|
||||
user_recid = False
|
||||
|
||||
if( not tmp_val['recid'] ):
|
||||
return False
|
||||
|
||||
user_recid = tmp_val['recid']
|
||||
if (tmp_val and "type" in tmp_val.keys() and str(tmp_val['type']) == "user"):
|
||||
# C'est une connexion de type USER, on retourne le 'partner_owner_recid'
|
||||
coll_token = MYSY_GV.dbname['user_account']
|
||||
user_account_data = coll_token.find_one({'token': str(token), 'active': '1', 'locked': '0'},
|
||||
{"_id": 1, "partner_owner_recid": 1})
|
||||
|
||||
if( user_account_data and "partner_owner_recid" in user_account_data.keys() and str(user_account_data['partner_owner_recid']) ):
|
||||
user_recid = str(user_account_data['partner_owner_recid'])
|
||||
else:
|
||||
# C'est une connexion de type PARTENAIRE, on retourne le 'recid'
|
||||
if ("recid" in tmp_val.keys() and str(tmp_val['recid'])):
|
||||
user_recid = str(tmp_val['recid'])
|
||||
|
||||
return user_recid
|
||||
|
||||
|
||||
|
@ -4168,17 +4264,20 @@ def Check_Connexion_And_Return_Partner_Data(diction):
|
|||
if retval is False:
|
||||
return "Err_Connexion", " La session de connexion n'est pas valide"
|
||||
|
||||
"""
|
||||
partner_recid = get_parnter_recid_from_token(token)
|
||||
if (partner_recid is False):
|
||||
myprint(
|
||||
str(inspect.stack()[0][3]) + " - partner_recid est KO. Les données de connexion sont incorrectes ")
|
||||
return False, " Vous n'etes pas autorisé à utiliser cette API "
|
||||
|
||||
print(" ### le partner_recid = ", partner_recid)
|
||||
# Recuperation des données du partenaire
|
||||
local_status, my_partner = get_partner_data_from_recid(partner_recid)
|
||||
if (local_status is False):
|
||||
myprint(str(inspect.stack()[0][3]) + " - impossible de récupérer les données du partenaire")
|
||||
return False, str(inspect.stack()[0][3]) + " - impossible de récupérer les données du partenaire. "
|
||||
"""
|
||||
|
||||
"""
|
||||
/!\ Update du 26/11/2023 :
|
||||
|
|
|
@ -11,6 +11,7 @@ import prj_common as mycommon
|
|||
import secrets
|
||||
import inspect
|
||||
import sys, os
|
||||
from flask import send_file
|
||||
import csv
|
||||
import pandas as pd
|
||||
from pymongo import ReturnDocument
|
||||
|
@ -119,6 +120,93 @@ def mysy_openai_voice_to_text(diction):
|
|||
return False, " Impossible de traiter : mysy_openai_voice_to_text"
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Cette fonction permet de convertir text en voix
|
||||
"""
|
||||
def mysy_openai_text_to_voice(diction):
|
||||
try:
|
||||
"""
|
||||
Verification des input acceptés
|
||||
"""
|
||||
field_list = ['text', ]
|
||||
|
||||
incom_keys = diction.keys()
|
||||
for val in incom_keys:
|
||||
if val not in field_list and val.startswith('my_') is False:
|
||||
mycommon.myprint(str(
|
||||
inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas")
|
||||
return False, " Les informations fournies sont incorrectes", False
|
||||
|
||||
"""
|
||||
Verification des champs obligatoires
|
||||
"""
|
||||
field_list_obligatoire = ['text', ]
|
||||
|
||||
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", False
|
||||
|
||||
|
||||
print(" ### diction = ", diction)
|
||||
now = datetime.now()
|
||||
# getting the timestamp
|
||||
ts = str(datetime.timestamp(now)).replace(".", "").replace(",", "")
|
||||
|
||||
out_file_name = str(MYSY_GV.TEMPORARY_DIRECTORY_V2)+"mysy_text_to_voice_" + str(ts[-4:])+".mp3"
|
||||
|
||||
print(" ### Traitement du fichier audio : ", out_file_name)
|
||||
|
||||
response = client.audio.speech.create(
|
||||
model="tts-1-hd",
|
||||
voice="onyx",
|
||||
input=str(diction["text"]),
|
||||
)
|
||||
|
||||
response.stream_to_file(out_file_name)
|
||||
|
||||
return True, "Ok"
|
||||
|
||||
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 traiter : mysy_openai_text_to_voice"
|
||||
|
||||
|
||||
"""
|
||||
Cette fonction permet d'envoyer un fichier audio sur le front
|
||||
"""
|
||||
def send_mysy_openai_to_voice_file(diction):
|
||||
try:
|
||||
"""
|
||||
Verification des input acceptés
|
||||
"""
|
||||
field_list = ['text', ]
|
||||
|
||||
incom_keys = diction.keys()
|
||||
for val in incom_keys:
|
||||
if val not in field_list and val.startswith('my_') is False:
|
||||
mycommon.myprint(str(
|
||||
inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas")
|
||||
return False, " Les informations fournies sont incorrectes", False
|
||||
|
||||
out_file_name = "temp_direct/mysy_text_to_voice_89.mp3"
|
||||
|
||||
if os.path.exists(out_file_name):
|
||||
path = str(out_file_name)
|
||||
print("path == ", path)
|
||||
return send_file(path, as_attachment=True)
|
||||
|
||||
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 traiter : send_mysy_openai_to_voice_file"
|
||||
|
||||
|
||||
|
||||
|
||||
def test_mysy_openai_voice_to_text(diction):
|
||||
try:
|
||||
|
||||
|
@ -145,7 +233,6 @@ def test_mysy_openai_voice_to_text(diction):
|
|||
return False, " Impossible de traiter : test_mysy_openai_voice_to_text"
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Cette fonction prend une phrase et fait un decoupage comme suit :
|
||||
1 - enleve le mot "ok Missy", "ok mysy"
|
||||
|
@ -317,8 +404,8 @@ et la transforme en un tableau de json comme suit :
|
|||
def mysy_openai_transform_instruction_text_to_json_tab(diction):
|
||||
try:
|
||||
"""
|
||||
Verification des input acceptés
|
||||
"""
|
||||
Verification des input acceptés
|
||||
"""
|
||||
field_list = ['text', "related_collection",]
|
||||
|
||||
incom_keys = diction.keys()
|
||||
|
|
|
@ -70,13 +70,15 @@ def login(diction):
|
|||
if diction['email']:
|
||||
email = diction['email']
|
||||
query['email'] = diction['email']
|
||||
query['active'] = '1'
|
||||
|
||||
|
||||
if ("pwd" in diction.keys()):
|
||||
if diction['pwd']:
|
||||
pwd = diction['pwd']
|
||||
query['pwd'] = diction['pwd']
|
||||
|
||||
query['active'] = '1'
|
||||
query['locked'] = '0'
|
||||
|
||||
# Recuperation du RecId du user connecté
|
||||
coll_name = MYSY_GV.dbname['user_account']
|
||||
|
@ -98,20 +100,23 @@ def login(diction):
|
|||
#recuperation du recid du user
|
||||
user_recid = my_user[0]['recid']
|
||||
|
||||
print("user_recid = "+user_recid)
|
||||
print("#### user_recid = "+user_recid)
|
||||
# A ce niveau le login et passe sont ok.
|
||||
# il faut donc créer le token et renvoyer le token.
|
||||
my_token = create_token_urlsafe()
|
||||
|
||||
# Enregistrement du token
|
||||
token_collection = MYSY_GV.dbname['user_token']
|
||||
token_collection = MYSY_GV.dbname['partner_token']
|
||||
|
||||
tokenfield = {}
|
||||
tokenfield['token'] = my_token
|
||||
tokenfield['email'] = email
|
||||
tokenfield['recid'] = user_recid
|
||||
tokenfield['date_update'] = str(datetime.now())
|
||||
tokenfield['start_date'] = str(datetime.now())
|
||||
tokenfield['valide'] = '1'
|
||||
tokenfield['locked'] = '0'
|
||||
tokenfield['type'] = 'user'
|
||||
|
||||
|
||||
'''
|
||||
|
@ -128,6 +133,35 @@ def login(diction):
|
|||
|
||||
if ret_val and ret_val['_id']:
|
||||
mycommon.myprint(" Ajout Token OK, _id = "+str(ret_val['_id']))
|
||||
|
||||
now = str(datetime.now())
|
||||
|
||||
"""
|
||||
Mise à jour du compte du partenaie
|
||||
avec les info de last connexion et de token
|
||||
"""
|
||||
partner_update_data = {}
|
||||
partner_update_data['lastconnexion'] = str(datetime.now())
|
||||
partner_update_data['token'] = str(my_token)
|
||||
|
||||
|
||||
partner_key_secrete_key = ""
|
||||
|
||||
# Verification que les informations sont juste
|
||||
coll_name = MYSY_GV.dbname['user_account']
|
||||
ret_val = coll_name.find_one_and_update(
|
||||
{'email': str(email), 'pwd': str(pwd), 'active': '1', 'locked': '0'},
|
||||
{"$set": partner_update_data},
|
||||
upsert=False,
|
||||
return_document=ReturnDocument.AFTER
|
||||
)
|
||||
|
||||
if ("_id" not in ret_val.keys()):
|
||||
mycommon.myprint(
|
||||
str(inspect.stack()[0][3]) + " Impossible de récupérer les données de l'utilisateur (2)")
|
||||
return False, " Impossible de récupérer les données de l'utilisateur (2) "
|
||||
|
||||
|
||||
return True, str(my_token)
|
||||
else:
|
||||
mycommon.myprint(str(inspect.stack()[0][3])+" Impossible d'enregistrer le token " + my_token)
|
||||
|
|
Loading…
Reference in New Issue