17/06/2024 - 21h30

master
cherif 2024-06-17 22:36:28 +02:00
parent becc9ab015
commit cc465ebaa9
5 changed files with 21026 additions and 89 deletions

View File

@ -3,10 +3,10 @@
<component name="ChangeListManager">
<list default="true" id="c6d0259a-16e1-410d-91a1-830590ee2a08" name="Changes" comment="15/06/2024 - 21h30">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" 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$/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />

View File

@ -215,6 +215,123 @@ def Create_E_Document(diction):
return False, " Impossible de créer le E-Document "
"""
Creation d'une e-facture qui ne necessite pas un envoie d'email
"""
def Create_E_Invoice(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'file_name', 'related_collection', 'related_collection_id',
'email_destinataire', 'source_document', 'type', 'file_cononical_name']
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', 'file_name', 'related_collection', 'related_collection_id',
'email_destinataire', 'source_document']
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
if (mycommon.isEmailValide(str(diction['email_destinataire'])) is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'adresse email " + str(diction['email_destinataire']) + " n'est pas valide")
return False, " L'adresse email " + str(diction['email_destinataire']) + " n'est pas valide "
file_name = diction['file_name']
basename = os.path.basename(file_name)
basename2 = basename.split(".")
if (len(basename2) != 2):
mycommon.myprint(str(inspect.stack()[0][3]) + " - : Le nom du fichier est incorrect")
return False, "Le nom du fichier est incorrect"
if (str(basename2[1]).lower() not in MYSY_GV.ALLOWED_EXTENSIONS):
mycommon.myprint(str(inspect.stack()[0][3]) + " - : le format de fichier '"+str(basename2[1])+"' n'est pas autorisé. Les extentions autorisées sont : "+str(MYSY_GV.ALLOWED_EXTENSIONS))
return False, "le format de fichier '"+str(basename2[1])+"' n'est pas autorisé. Les extentions autorisées sont : "+str(MYSY_GV.ALLOWED_EXTENSIONS)
encoded_pdf_to_string = ""
with open(file_name, "rb") as f:
encoded_pdf_to_string = base64.b64encode(f.read())
secret_key = secrets.token_urlsafe(5)
new_diction = {}
new_diction['document_data'] = encoded_pdf_to_string
new_diction['related_collection'] = diction['related_collection']
new_diction['related_collection_id'] = diction['related_collection_id']
new_diction['partner_owner_recid'] = my_partner['recid']
new_diction['statut'] = '0'
new_diction['valide'] = '1'
new_diction['locked'] = "0"
new_diction['secret_key_open'] = str(secret_key)
new_diction['email_destinataire'] = str(diction['email_destinataire'])
new_diction['source_document'] = str(diction['source_document'])
new_diction['date_update'] = str(datetime.now())
new_diction['update_by'] = str(my_partner['_id'])
new_diction['created_by'] = str(my_partner['_id'])
if( "type" in diction.keys() ):
new_diction['type'] = str(diction['type'])
else:
new_diction['type'] = ""
if ("file_cononical_name" in diction.keys() and diction['file_cononical_name']):
new_diction['file_cononical_name'] = str(diction['file_cononical_name'])
else:
todays_date = str(datetime.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-2:]
cononic_name = "No_Name_" + str(todays_date) + "_" + str(ts)
new_diction['file_cononical_name'] = cononic_name
val = MYSY_GV.dbname['e_document_signe'].insert_one(new_diction)
if (val is None):
mycommon.myprint(
" Impossible de créer le E-Document (2) ")
return False, " Impossible de créer le E-Document (2) "
return True, str(val.inserted_id)
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 E-Document "
"""
Recuperation document à signer, sans connexion token
@ -528,7 +645,7 @@ def checkIntegrity(calculated_hash, decrypted_hash):
return False
"""
Signature du document
Signature du document 'normale'
"""
def Create_E_Signature_For_E_Document(file_img=None, Folder=None, diction=None):
try:
@ -1157,6 +1274,528 @@ def Create_E_Signature_For_E_Document(file_img=None, Folder=None, diction=None):
return False, " Impossible de signer le document "
"""
Signature d'une facture electronique : E-Invoice
"""
def Create_E_Signature_For_E_Invoice(file_img=None, Folder=None, diction=None):
try:
print(" GRR diction = ", diction)
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'e_doc_id', 'secret_key_signature', 'email_destinataire', 'user_ip']
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', 'e_doc_id', 'secret_key_signature', 'email_destinataire']
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']
saved_file = ""
image_signature_manuelle_string = ""
if (file_img):
status, saved_file = mycommon.Upload_Save_IMG_File(file_img, Folder)
if (status is False):
mycommon.myprint(str(saved_file))
return False, str(saved_file)
print(" signature manuelle = ", saved_file)
with open(saved_file, "rb") as imageFile:
image_signature_manuelle_string = base64.b64encode(imageFile.read()).decode()
"""
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
if (local_status is not True):
return local_status, my_partner
"""
if (mycommon.isEmailValide(str(diction['email_destinataire'])) is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La valeur '" + str(
diction['user_email']) + "' n'est pas un email valide ")
return False, " Les informations fournies sont incorrectes"
RetObject = []
val_tmp = 0
# Verifier la validité du document
qry = {'valide': '1', 'locked': '0',
'_id': ObjectId(str(diction['e_doc_id'])),
'secret_key_signature': str(diction['secret_key_signature']),
}
is_valide_e_document = MYSY_GV.dbname['e_document_signe'].count_documents(qry)
if (is_valide_e_document <= 0):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'idientifiant du E-Document est invalide ")
return False, " L'idientifiant du E-Document est invalide "
e_document_data = MYSY_GV.dbname['e_document_signe'].find_one(qry)
e_docment_type = ""
if ("type" in e_document_data.keys() and e_document_data['type']):
e_docment_type = e_document_data['type']
local_signature_digitale = ""
if ("email_destinataire" in e_document_data.keys() and e_document_data['email_destinataire']):
list_email = str(e_document_data['email_destinataire']).replace(",", ";")
tab_list_email = list_email.split(";")
if (str(diction['email_destinataire']) in tab_list_email):
my_str = str(e_document_data['document_data'])
document_data_as_bytes = str.encode(my_str)
print(type(document_data_as_bytes)) # ensure it is byte representation
message = document_data_as_bytes
msg = SignedMessage(message=message)
# Generating private key (RsaKey object) of key length of 1024 bits
private_key = RSA.generate(1024)
# Generating the public key (RsaKey object) from the private key
public_key = private_key.publickey()
# Calculating the digital signature
msg.encrypt(key=public_key)
print(f"Digital Signature: {msg.digitalsignature}")
# The message is still clear
# print(f"Message: {msg.message}")
# Instantiating PKCS1_OAEP object with the private key for decryption
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}")
# We recalculate the hash of the message using the same hash function
calcHash = calculateHash(msg.message)
# print(f"decrypted_message: {msg.message}")
is_signed_valide = checkIntegrity(calcHash, decrypted_message)
if (is_signed_valide is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'intégrité du document signé n'est pas valide ")
return False, " Impossible de signer le document(3) "
local_signature_digitale = msg.digitalsignature
"""
Apresent que le message est signé, on va mettre à jour le doc
"""
encoded_signed_pdf_to_string = base64.b64encode(decrypted_message)
new_data = {}
new_data['signature_digitale'] = msg.digitalsignature
new_data['signed_date'] = str(datetime.now())
new_data['signed_email'] = str(diction['email_destinataire'])
new_data['signed_ip_adress'] = str(diction['user_ip'])
new_data['statut'] = "1"
new_data['signature_nanuelle_img'] = image_signature_manuelle_string
qry_key = {'valide': '1', 'locked': '0',
'_id': ObjectId(str(diction['e_doc_id'])),
'secret_key_signature': str(diction['secret_key_signature']),
'email_destinataire': str(diction['email_destinataire'])}
result = MYSY_GV.dbname['e_document_signe'].find_one_and_update(
qry_key,
{"$set": new_data},
upsert=False,
return_document=ReturnDocument.AFTER
)
if ("_id" not in result.keys()):
mycommon.myprint(
" Impossible de signer le document (2) ")
return False, " Impossible de signer le document (2) "
else:
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'idientifiant du E-Document est invalide ")
return False, " L'idientifiant du E-Document est invalide "
local_partner_owner_recid = e_document_data['partner_owner_recid']
"""
Vu que tout est ok, on va créer le fichier pdf definif.
on va utiliser le contenu du champ "source_document" au quel on a ajouté un tag de la signature
"""
qry_key = {'valide': '1', 'locked': '0',
'_id': ObjectId(str(diction['e_doc_id'])),
'secret_key_signature': str(diction['secret_key_signature']),
'email_destinataire': str(diction['email_destinataire'])}
e_document_date_2 = MYSY_GV.dbname['e_document_signe'].find_one(qry_key)
user_created_e_document = MYSY_GV.dbname['partnair_account'].find_one(
{'_id': ObjectId(e_document_date_2['created_by']),
'active': '1',
'locked': '0',
})
if (user_created_e_document is None or "email" not in user_created_e_document.keys()):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'initiateur du document est invalide ")
return False, " L'initiateur du document est invalide "
if (mycommon.isEmailValide(user_created_e_document['email']) is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'adresse email de initiateur du document est invalide ")
return False, " L'adresse email de initiateur du document est invalide "
local_partner_owner_recid = e_document_date_2['partner_owner_recid']
local_signature_digitale = decrypt.decrypt(e_document_date_2['signature_digitale'])
local_url_securite = MYSY_GV.CLIENT_URL_BASE + "E_Document/" + str(e_document_date_2['_id']) + "/" + str(
e_document_date_2['partner_owner_recid']) + "/" + str(e_document_date_2['secret_key_signature'])
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-3:]
qr_code_img_file = str(MYSY_GV.TEMPORARY_DIRECTORY_V2) + "qr_code_" + str(ts) + ".png"
qrcode = segno.make_qr(str(local_url_securite))
qrcode.save(
qr_code_img_file,
scale=5,
dark="darkblue",
)
qr_code_converted_string = ""
with open(qr_code_img_file, "rb") as image2string:
qr_code_converted_string = base64.b64encode(image2string.read()).decode()
"""
On est sur une fonction sans token, mais pour recuperer des infos en mode connecté comme le dictionnaire
je vais aller prendre le token du compte admin
"""
temp_admin_account = MYSY_GV.dbname['partnair_account'].find_one({'recid': str(local_partner_owner_recid),
'active': '1',
'is_partner_admin_account': '1',
'locked': '0'})
if (temp_admin_account is None):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Impossible de recupérer les données du partenaire ")
return False, " Impossible de recupérer les données du partenaire "
# Creation du dictionnaire d'information à utiliser pour la creation du doc
convention_dictionnary_data = {}
new_diction = {}
new_diction['token'] = temp_admin_account['token']
new_diction['list_stagiaire_id'] = []
new_diction['list_session_id'] = []
new_diction['list_class_id'] = []
new_diction['list_client_id'] = []
new_diction['list_apprenant_id'] = []
local_status, local_retval = mycommon.Get_Dictionnary_data_For_Template(new_diction)
if (local_status is False):
return local_status, local_retval
convention_dictionnary_data = local_retval
convention_dictionnary_data["mysy_signature_digitale"] = str(local_signature_digitale)
convention_dictionnary_data["mysy_url_securite"] = local_url_securite
convention_dictionnary_data["mysy_qrcode_securite"] = "data:image/png;base64," + qr_code_converted_string
convention_dictionnary_data[
"mysy_manual_signature_img"] = "data:image/png;base64," + image_signature_manuelle_string
body = {
"params": convention_dictionnary_data
}
source_data = str(e_document_data['source_document'])
contenu_doc_Template = jinja2.Template(str(source_data))
sourceHtml = contenu_doc_Template.render(params=body["params"])
todays_date = str(datetime.today().strftime("%d_%m_%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-2:]
if (str(e_docment_type).strip() != ""):
orig_file_name = str(e_docment_type).strip() + "_Signe_" + str(todays_date) + "_" + str(ts) + ".pdf"
else:
orig_file_name = "Document_Signe_" + str(todays_date) + "_" + str(ts) + ".pdf"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)
# open output file for writing (truncated binary)
resultFile = open(outputFilename, "w+b")
# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
src=sourceHtml, # the HTML to convert
dest=resultFile) # file handle to receive result
# close output file
resultFile.close()
final_encoded_pdf_to_string = ""
with open(outputFilename, "rb") as f:
final_encoded_pdf_to_string = base64.b64encode(f.read())
qry_key = {'valide': '1', 'locked': '0',
'_id': ObjectId(str(diction['e_doc_id'])),
'secret_key_signature': str(diction['secret_key_signature']),
'email_destinataire': str(diction['email_destinataire'])}
new_data = {}
new_data['document_data_signed'] = final_encoded_pdf_to_string
result = MYSY_GV.dbname['e_document_signe'].find_one_and_update(
qry_key,
{"$set": new_data},
upsert=False,
return_document=ReturnDocument.AFTER
)
if ("_id" not in result.keys()):
mycommon.myprint(
" Impossible de signer le document (2) ")
return False, " Impossible de signer le document (2) "
"""
On envoie le mail avec le document signé
"""
# Traitement de l'eventuel fichier joint
tab_files_to_attache_to_mail = []
# Attachement du fichier joint
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(outputFilename, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(os.path.basename(outputFilename)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
"""
Recupération du modele de courrier.
le principe est de prendre le module du partenaire. si pas de modele du partenaire on
prend le modele par default
"""
courrier_template_model = MYSY_GV.dbname['courrier_template'].count_documents(
{'ref_interne': "E_DOCUMENT_SIGNED",
'valide': '1',
'locked': '0',
'type_doc': 'email',
'partner_owner_recid': str(local_partner_owner_recid)}
)
if (courrier_template_model == 1):
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'ref_interne': "E_DOCUMENT_SIGNED",
'valide': '1',
'locked': '0',
'type_doc': 'email',
'partner_owner_recid': str(local_partner_owner_recid)}
)
else:
courrier_template_model = MYSY_GV.dbname['courrier_template'].count_documents(
{'ref_interne': "E_DOCUMENT_SIGNED",
'valide': '1',
'locked': '0',
'type_doc': 'email',
'partner_owner_recid': "default"}
)
if (courrier_template_model == 1):
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one(
{'ref_interne': "E_DOCUMENT_SIGNED",
'valide': '1',
'locked': '0',
'type_doc': 'email',
'partner_owner_recid': "default"}
)
else:
mycommon.myprint(str(
inspect.stack()[0][3]) + " Aucun modèle de document configuré pour envoyer les e-documents signés ")
return False, " Aucun modèle de document configuré pour envoyer les e-documents signés "
if ("contenu_doc" not in courrier_template_data.keys() or str(
courrier_template_data['contenu_doc']).strip() == ""):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le modèle de document ne contient pas de valeur 'contenu_doc' ")
return False, " Le modèle de document ne contient pas de valeur 'contenu_doc' "
contenu_doc_Template = jinja2.Template(str(courrier_template_data['contenu_doc']))
"""
On est sur une fonction sans token, mais pour recuperer des infos en mode connecté comme le dictionnaire
je vais aller prendre le token du compte admin
"""
temp_admin_account = MYSY_GV.dbname['partnair_account'].find_one({'recid': str(local_partner_owner_recid),
'active': '1',
'is_partner_admin_account': '1',
'locked': '0'})
if (temp_admin_account is None):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Impossible de recupérer les données du partenaire ")
return False, " Impossible de recupérer les données du partenaire "
# Creation du dictionnaire d'information à utiliser pour la creation du doc
convention_dictionnary_data = {}
new_diction = {}
new_diction['token'] = temp_admin_account['token']
new_diction['list_stagiaire_id'] = []
new_diction['list_session_id'] = []
new_diction['list_class_id'] = []
new_diction['list_client_id'] = []
new_diction['list_apprenant_id'] = []
local_status, local_retval = mycommon.Get_Dictionnary_data_For_Template(new_diction)
if (local_status is False):
return local_status, local_retval
convention_dictionnary_data = local_retval
body = {
"params": convention_dictionnary_data
}
html = contenu_doc_Template.render(params=body["params"])
html_mime = MIMEText(html, 'html')
"""
Recuperer les données du client associé à la quotation
"""
quotation_client_data = None
reference_document = ""
type_document = ""
if (e_document_date_2['type'] == "quotation"):
qry = {'partner_owner_recid': local_partner_owner_recid,
'_id': ObjectId(str(e_document_date_2['related_collection_id'])),
'valide': '1',
'locked': '0'}
quotation_data = MYSY_GV.dbname['partner_order_header'].find_one(
{'partner_owner_recid': local_partner_owner_recid,
'_id': ObjectId(str(e_document_date_2['related_collection_id'])),
'valide': '1',
'locked': '0'})
if (quotation_data is None):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant du devis n'est pas valide ")
return False, " L'identifiant du devis n'est pas valide "
reference_document = quotation_data['order_header_ref_interne']
type_document = "Devis"
qry2 = {'partner_recid': local_partner_owner_recid,
'_id': ObjectId(str(quotation_data['order_header_client_id'])),
'valide': '1',
'locked': '0'}
quotation_client_data = None
quotation_client_data = MYSY_GV.dbname['partner_client'].find_one(
{'partner_recid': local_partner_owner_recid,
'_id': ObjectId(str(quotation_data['order_header_client_id'])),
'valide': '1',
'locked': '0'})
if (quotation_client_data is None):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Le client associé au devis n'est pas valide ")
return False, " Le client associé au devis n'est pas valide "
"""
Le fichier est envoyé par email, il faudrait à present le stocker
le fichier dans l'espace documentaire du client
-field_list = ['token', 'file_business_object', 'file_name', 'status','object_owner_collection', 'object_owner_id']
"""
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-2:]
todays_date = str(datetime.today().strftime("%d%m%Y"))
new_file = {}
new_file['token'] = temp_admin_account['token']
if (type_document == "Devis" and reference_document):
new_file['file_business_object'] = "e_" + str(type_document) + "_" + str(
reference_document) + "_signe_" + str(todays_date) + "_" + str(ts)
else:
new_file['file_business_object'] = "e_Document_signe_" + str(todays_date) + "_" + str(ts)
new_file['file_name'] = str(orig_file_name)
new_file['status'] = "1"
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']
new_file['file_name_to_store'] = outputFilename
# print(" ### new_file new_file = ", new_file)
local_status, local_retval = attached_file_mgt.Internal_Usage_Store_User_Downloaded_File(MYSY_GV.upload_folder,
new_file)
if (local_status is False):
print(" ## WARNONGGG Impossible de stocker le fichier")
"""
Si il s'agit d'un devis, alors on procede a la resevation des places
"""
if (str(e_docment_type).strip() == "quotation"):
"""
Recuperer les données de la quotation
"""
new_local_diction = {}
new_local_diction['partner_owner_recid'] = str(e_document_data['partner_owner_recid'])
new_local_diction['quotation_id'] = str(e_document_data['related_collection_id'])
new_local_diction['request_digital_signature'] = "0"
local_status, local_retval = partner_order.Insert_Quotation_To_Session_From_Partner_Owner_Recid(
new_local_diction)
if (local_status is False):
print(" ## WARNONGGG Impossible deInsert_Quotation_To_Session_From_Partner_Owner_Recid ")
return True, " Le document a été correction signé. Vous allez recevoir le document par email"
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 signer le document "
"""
Cette fonction fait une demande de signature d'un document

View File

@ -1424,6 +1424,13 @@ def GetAllClassStagiaire(diction):
else:
user['facture_client_rattachement_id'] = ""
if( "invoice_split" in retval.keys() ):
user['has_invoice_split'] = "1"
else:
user['has_invoice_split'] = "0"
#-----
financeur_rattachement_id = ""
financeur_rattachement_nom = ""

File diff suppressed because one or more lines are too long

View File

@ -8913,19 +8913,28 @@ def Invoice_Inscrption_With_Split_Session_By_Inscription_Id( tab_files, diction)
if diction['tab_inscription_ids']:
my_inscription_ids = diction['tab_inscription_ids']
tab_my_inscription_ids = str(my_inscription_ids).split(",")
tab_my_inscription_ids_ObjectId = []
for tmp in tab_my_inscription_ids :
tab_my_inscription_ids_ObjectId.append(ObjectId(str(tmp)))
# Recuperation des données du stagiaire
inscription_data = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
if( str(my_inscription_ids) == "all"):
# Recuperation des données du stagiaire
inscription_data = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'_id':{'$in':tab_my_inscription_ids_ObjectId},
"invoiced": {'$ne': '1'},})
"invoiced": {'$ne': '1'}, })
else:
tab_my_inscription_ids = str(my_inscription_ids).split(",")
tab_my_inscription_ids_ObjectId = []
for tmp in tab_my_inscription_ids :
tab_my_inscription_ids_ObjectId.append(ObjectId(str(tmp)))
# Recuperation des données du stagiaire
inscription_data = MYSY_GV.dbname['inscription'].find({'session_id': str(diction['session_id']),
'status': '1',
'partner_owner_recid': str(my_partner['recid']),
'_id':{'$in':tab_my_inscription_ids_ObjectId},
"invoiced": {'$ne': '1'},})
print(" ### inscription_data = ", inscription_data)
@ -8989,12 +8998,8 @@ def Invoice_Inscrption_With_Split_Session_By_Inscription_Id( tab_files, diction)
3]) + " La valeur de partage de la facture est inférieure à 0 ")
return False, " La valeur de partage de la facture est inférieure à 0 ", False
tab_inscrit_for_splited_invoice.append(node)
else:
node = {}
node['inscription_id'] = str(val['_id'])
@ -9039,10 +9044,14 @@ def Invoice_Inscrption_With_Split_Session_By_Inscription_Id( tab_files, diction)
print(" ### status = ", status)
print(" ### retval = ", retval)
print(" ### invoice_ref = ", invoice_ref)
list_non_splited_invoice.append(invoice_ref)
print(" ### local_diction_for_NOT_INVOICE_SPLIT invoice_ref = ", invoice_ref)
for tmp in invoice_ref:
list_non_splited_invoice.append(tmp)
print(" ### La liste des tab_inscrit_for_splited_invoice ", tab_inscrit_for_splited_invoice)
list_non_splited_invoice_str = ', '.join(invoice_ref)
print(" ### BBBB list_non_splited_invoice_str = ", list_non_splited_invoice_str)
global_list_facture = list_non_splited_invoice_str
list_splited_invoice = []
"""
@ -9059,15 +9068,139 @@ def Invoice_Inscrption_With_Split_Session_By_Inscription_Id( tab_files, diction)
print(" ### status = ", status)
print(" ### retval = ", retval)
print(" ### invoice_ref = ", invoice_ref)
list_splited_invoice.append(invoice_ref)
print(" ### local_diction_for_WITH_INVOICE_SPLIT invoice_ref = ", invoice_ref)
list_splited_invoice = str(invoice_ref).replace('[', '').replace(']', '').replace("'", "")
print(" Liste des factures SANS split = ", str(list_non_splited_invoice))
print(" Liste des factures avec split = ", str(list_splited_invoice))
global_list_facture = str(list_non_splited_invoice)+", "+str(list_splited_invoice)
list_non_splited_invoice_str = list_non_splited_invoice_str+", "+str(list_splited_invoice)
return True, "L'email a été correctement envoyé ", str(list_splited_invoice)
global_list_facture = list_non_splited_invoice_str
tab_global_list_facture = str(global_list_facture).split(",")
print(" ### tab_global_list_facture = ", tab_global_list_facture)
"""
Recupeer le modele de courrier "courrier_template_type_document_ref_interne":"FACTURATION_SESSION"
depuis la collection courrier_template_tracking
"""
print(' QRY : ', {'courrier_template_type_document_ref_interne':'FACTURATION_SESSION',
'partner_owner_recid':my_partner['recid'],
'valide':'1',
'locked':'0',
}
)
courrier_template_count = MYSY_GV.dbname['courrier_template'].count_documents({'ref_interne':'FACTURATION_SESSION',
'partner_owner_recid':'default',
'valide':'1',
'locked':'0',
})
if( courrier_template_count != 1):
mycommon.myprint(" WARNING : Impossible d'identifier le courrier_template_count associé à la facturation : ")
else:
courrier_template_data = MYSY_GV.dbname['courrier_template'].find_one({'ref_interne':'FACTURATION_SESSION',
'partner_owner_recid':'default',
'valide':'1',
'locked':'0',
})
print(" ### courrier_template_data = ", courrier_template_data)
print(" QRYY = ", {'partner_owner_recid': str(my_partner['recid']),
'session_id': str(diction['session_id']),
'invoiced_ref': {'$in': tab_global_list_facture}})
if( courrier_template_data and '_id' in courrier_template_data.keys() ):
for local_data in tab_inscrit_for_splited_invoice :
for val in MYSY_GV.dbname['inscription'].find({'partner_owner_recid': str(my_partner['recid']),
'session_id': str(diction['session_id']),
'_id':ObjectId(str(local_data['inscription_id']))}):
ref_facture = ""
if ("invoiced_ref" in val.keys()):
ref_facture = val['invoiced_ref']
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(
my_partner, "FACTURATION_SESSION", str(diction['session_id']), 'inscription',
str(val['_id']),
str(courrier_template_data['_id']),
"Facture : " + str(ref_facture)
)
if (local_status is False):
mycommon.myprint(" WARNING : Impossible de logguer l'historique l'inscription_id : " + str(val['_id']))
for local_data in tab_inscrit_for_NOT_splited_invoice:
for val in MYSY_GV.dbname['inscription'].find({'partner_owner_recid': str(my_partner['recid']),
'session_id': str(diction['session_id']),
'_id': ObjectId(str(
local_data['inscription_id']))}):
ref_facture = ""
if ("invoiced_ref" in val.keys()):
ref_facture = val['invoiced_ref']
print(" ### traintement login de val = ", val)
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(
my_partner, "FACTURATION_SESSION", str(diction['session_id']), 'inscription',
str(val['_id']),
str(courrier_template_data['_id']),
"Facture : " + str(ref_facture)
)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique l'inscription_id : " + str(val['_id']))
global_list_facture = str(global_list_facture).replace(",", "\n")
"""
07/03/20204 : mettre un statut de facturation sur la session afin de voir
tout de suite quel session est entièrement facturée ou partiellement.
regles :
Si toutes les inscription associées à une session sont facturée ==> invoiced_statut de la session = 2
Si au moins une inscription associée à une session est facturé ==> invoiced_statut de la session = 1
Si non invoiced_statut de la session =0
"""
nb_inscription_facture_termine = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'invoiced': '1',
'session_id':str(diction['session_id'])
})
nb_inscription_non_facture_ou_encours = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'session_id': str(diction['session_id']),
'invoiced': {'$ne': '1'}})
nb_inscription_valide = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'session_id': str(diction['session_id']),
'status': '1'})
invoiced_statut = "0"
if (nb_inscription_facture_termine == nb_inscription_valide):
# toutes les inscription valides ont été facturée
invoiced_statut = "2"
elif (nb_inscription_non_facture_ou_encours > 0):
# Au moins une ligne a été facturée
invoiced_statut = "1"
# Mise à jour du statut de facturation de la session
MYSY_GV.dbname['session_formation'].update_one({'partner_owner_recid': my_partner['recid'],
'valide': '1',
'_id': ObjectId(str(diction['session_id']))
},
{'$set': {'invoiced_statut': invoiced_statut}})
return True, " Les factures suivantes été créées : \n "+str(global_list_facture), str(global_list_facture)
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
@ -9950,65 +10083,6 @@ def Prepare_and_Send_Facture_From_Session_By_Inscription_Id_SAVE_ORIG(tab_files,
tab_local_invoice_ref_interne.append(str(local_invoice_ref_interne))
"""
07/03/20204 : mettre un statut de facturation sur la session afin de voir
tout de suite quel session est entièrement facturée ou partiellement.
regles :
Si toutes les inscription associées à une session sont facturée ==> invoiced_statut de la session = 2
Si au moins une inscription associée à une session est facturé ==> invoiced_statut de la session = 1
Si non invoiced_statut de la session =0
"""
nb_inscription_facture = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'invoiced': '1'})
nb_inscription_non_facture = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'invoiced': {'$ne': '1'}})
nb_inscription_valide = MYSY_GV.dbname['inscription'].count_documents(
{'partner_owner_recid': my_partner['recid'],
'status': '1'})
invoiced_statut = "0"
if (nb_inscription_facture == nb_inscription_valide):
# toutes les inscription valides ont été facturée
invoiced_statut = "2"
elif (nb_inscription_facture > 0):
# Au moins une ligne a été facturée
invoiced_statut = "1"
# Mise à jour du statut de facturation de la session
MYSY_GV.dbname['session_formation'].update_one({'partner_owner_recid': my_partner['recid'],
'valide': '1',
'_id': ObjectId(str(diction['session_id']))
},
{'$set': {'invoiced_statut': invoiced_statut}})
# Creation de l'historique dans les action 'courrier_template_tracking_history'
local_qry = {'partner_owner_recid': str(my_partner['recid']), 'session_id': str(diction['session_id']),
'invoiced_ref': {'$in': tab_local_invoice_ref_interne}}
# print(" ### local_qry = ", local_qry)
for val in MYSY_GV.dbname['inscription'].find({'partner_owner_recid': str(my_partner['recid']),
'session_id': str(diction['session_id']),
'invoiced_ref': {'$in': tab_local_invoice_ref_interne}}):
ref_facture = ""
if ("invoiced_ref" in val.keys()):
ref_facture = val['invoiced_ref']
local_status, local_retval = module_editique.Editic_Log_History_Action_From_courrier_template_type_document_ref_interne(
my_partner, "FACTURATION_SESSION", str(diction['session_id']), 'inscription',
str(val['_id']),
str(diction['courrier_template_id']),
"Facture : " + str(ref_facture)
)
if (local_status is False):
mycommon.myprint(" WARNING : Impossible de logguer l'historique l'inscription_id : " + str(val['_id']))
return_message = " La session a été correctement facturée.\nListe des factures : "
for tmp in tab_local_invoice_ref_interne:
@ -10240,7 +10314,7 @@ def Prepare_and_Send_SPLITED_Facture_From_Session_By_Inscription_Id(tab_files, F
'invoiced_ref': {'$in': tab_local_invoice_ref_interne}}
# print(" ### local_qry = ", local_qry)
"""
for val in MYSY_GV.dbname['inscription'].find({'partner_owner_recid': str(my_partner['recid']),
'session_id': str(diction['session_id']),
'invoiced_ref': {'$in': tab_local_invoice_ref_interne}}):
@ -10258,7 +10332,7 @@ def Prepare_and_Send_SPLITED_Facture_From_Session_By_Inscription_Id(tab_files, F
if (local_status is False):
mycommon.myprint(" WARNING : Impossible de logguer l'historique l'inscription_id : " + str(val['_id']))
"""
return_message = " La session a été correctement facturée.\nListe des factures : "
for tmp in tab_local_invoice_ref_interne:
return_message += "\n - " + str(tmp)
@ -11519,7 +11593,7 @@ def Invoice_Create_Secure_E_Document(diction):
else:
new_e_document_diction['file_cononical_name'] = ""
local_status_e_doc, local_retval_e_doc = E_Sign_Document.Create_E_Document(new_e_document_diction)
local_status_e_doc, local_retval_e_doc = E_Sign_Document.Create_E_Invoice(new_e_document_diction)
if (local_status_e_doc is False):
return local_status_e_doc, local_retval_e_doc
@ -11552,7 +11626,7 @@ def Invoice_Create_Secure_E_Document(diction):
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_Document(None, None, new_e_document_diction2)
local_status_sign_e_doc, local_retval_sign_e_doc = E_Sign_Document.Create_E_Signature_For_E_Invoice(None, None, new_e_document_diction2)
if( local_status_sign_e_doc is False ):
return local_status_sign_e_doc, local_retval_sign_e_doc