01/09/22 - 13h

master
ChérifBALDE 2022-09-01 13:20:43 +02:00 committed by cherif
parent 7ecb3ab91b
commit ed6b224f47
6 changed files with 449 additions and 51 deletions

View File

@ -142,4 +142,11 @@ SENDINBLUE_API_KEY = "xkeysib-082bdb7bda0295a93f0b3bbc597e92fc4a91f9b52803fb1d1d
'''
Taux de TVA
'''
TVA_TAUX = 0.2
TVA_TAUX = 0.2
"""
Repertoire de depot des factures
"""
#INVOICE_DIRECTORY = "/tmp/Invoices/"
INVOICE_DIRECTORY = "C:/Users/ChérifBALDE/Desktop/Tmp_New/"

View File

@ -62,7 +62,7 @@ def get_all_articles_avis(diction):
insertObject = []
for x in coll_name.find({'valide': '1', 'locked': '0'},
{ "indexed": 0, "indexed_desc": 0, "indexed_obj": 0, "indexed_title": 0,
"valide": 0, "locked": 0, "url_formation": 0, }).sort(
"valide": 0, "locked": 0, }).sort(
[("title_formation",pymongo.ASCENDING), ("date_avis",pymongo.ASCENDING)]):
# mycommon.myprint("AVANT ==> "+str(x['description']))
val = x['qualite']

View File

@ -11,6 +11,7 @@ import prj_common as mycommon
import secrets
import inspect
import sys, os
import shutil
import csv
import pandas as pd
from pymongo import ReturnDocument
@ -19,6 +20,8 @@ import GlobalVariable as MYSY_GV
import email_mgt as email
from dateutil import tz
import pytz
from xhtml2pdf import pisa
import jinja2
class JSONEncoder(json.JSONEncoder):
@ -81,13 +84,17 @@ def get_invoice_by_customer(diction):
RetObject = []
coll_facture = MYSY_GV.dbname['factures']
for retVal in coll_facture.find({'client_recid':user_recid, 'valide': '1'} )\
for retVal in coll_facture.find({'client_recid':user_recid, 'valide': '1'},
{'invoice_nom':1, 'total_ht':1, 'total_tva':1, 'total_ttc':1,
'order_id':1, 'invoice_id':1, 'due_date':1, 'invoice_date':1,
}
)\
.sort([("date_facture", pymongo.ASCENDING), ("num_facture", pymongo.DESCENDING), ]):
user = retVal
if ("_id" in user.keys()):
user['class_id'] = user.pop('_id')
RetObject.append(JSONEncoder().encode(user))
print(" les facture du client = "+str(RetObject))
return True, RetObject
except Exception as e:
@ -456,56 +463,13 @@ def createOrder(diction):
new_data['invoice_telephone'] = part_account[0]['invoice_telephone']
total_ht = 0
new_data['total_ht'] = total_ht
new_data['total_tva'] = mycommon.tryFloat(str(total_ht)) * MYSY_GV.TVA_TAUX
new_data['total_ttc'] = mycommon.tryFloat(str(total_ht)) + mycommon.tryFloat(str(new_data['total_tva']))
# Recuperation ds données de payement
coll_part_payment = MYSY_GV.dbname['payement_mode']
part_account = coll_part_payment.find({'client_recid': user_recid, 'valide': '1'})
total_ttc_float = mycommon.tryFloat(str(new_data['total_ttc']))
print( "str(new_data['total_ttc']) === "+str(total_ttc_float))
if( part_account.count() <= 0 and total_ttc_float > 0):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Aucune donnée de payement, Impossible de créer la commande ")
return False, " Aucune donnée de payement,, Impossible de créer la commande ", None
# Les données de payement ne sont utilisées que si le montatn > 0
if( total_ttc_float > 0 ):
if ("type" in part_account[0].keys()):
if part_account[0]['type']:
new_data['type_payment'] = part_account[0]['type']
if ("bic" in part_account[0].keys()):
if part_account[0]['bic']:
new_data['bic_payment'] = part_account[0]['bic']
if ("cvv_carte" in part_account[0].keys()):
if part_account[0]['cvv_carte']:
new_data['cvv_carte_payment'] = part_account[0]['cvv_carte']
if ("date_exp_carte" in part_account[0].keys()):
if part_account[0]['date_exp_carte']:
new_data['date_exp_carte_payment'] = part_account[0]['date_exp_carte']
if ("iban" in part_account[0].keys()):
if part_account[0]['iban']:
new_data['iban_payment'] = part_account[0]['iban']
if ("nom_carte" in part_account[0].keys()):
if part_account[0]['nom_carte']:
new_data['nom_carte_payment'] = part_account[0]['nom_carte']
if ("nom_compte" in part_account[0].keys()):
if part_account[0]['nom_compte']:
new_data['nom_compte_payment'] = part_account[0]['nom_compte']
if ("num_carte" in part_account[0].keys()):
if part_account[0]['num_carte']:
new_data['num_carte_payment'] = part_account[0]['num_carte']
new_data['nb_product'] = str(nb_line)
i = 0
@ -536,10 +500,57 @@ def createOrder(diction):
i = i + 1
new_data['total_ht'] = total_ht
new_data['total_tva'] = mycommon.tryFloat(str(total_ht)) * MYSY_GV.TVA_TAUX
new_data['total_ttc'] = mycommon.tryFloat(str(total_ht)) + mycommon.tryFloat(str(new_data['total_tva']))
total_ttc_float = mycommon.tryFloat(str(new_data['total_ttc']))
print("str(new_data['total_ttc']) === " + str(total_ttc_float))
if (part_account.count() <= 0 and total_ttc_float > 0):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Aucune donnée de payement, Impossible de créer la commande ")
return False, " Aucune donnée de payement,, Impossible de créer la commande ", None
print(" new_data['total_ht'] = "+str(new_data['total_ht']) + " -- new_data['total_tva'] "
+str(new_data['total_tva'])+ " -- new_data['total_ttc'] = "+ str(new_data['total_ttc']))
# Les données de payement ne sont utilisées que si le montant > 0
if (total_ttc_float > 0):
if ("type" in part_account[0].keys()):
if part_account[0]['type']:
new_data['type_payment'] = part_account[0]['type']
if ("bic" in part_account[0].keys()):
if part_account[0]['bic']:
new_data['bic_payment'] = part_account[0]['bic']
if ("cvv_carte" in part_account[0].keys()):
if part_account[0]['cvv_carte']:
new_data['cvv_carte_payment'] = part_account[0]['cvv_carte']
if ("date_exp_carte" in part_account[0].keys()):
if part_account[0]['date_exp_carte']:
new_data['date_exp_carte_payment'] = part_account[0]['date_exp_carte']
if ("iban" in part_account[0].keys()):
if part_account[0]['iban']:
new_data['iban_payment'] = part_account[0]['iban']
if ("nom_carte" in part_account[0].keys()):
if part_account[0]['nom_carte']:
new_data['nom_carte_payment'] = part_account[0]['nom_carte']
if ("nom_compte" in part_account[0].keys()):
if part_account[0]['nom_compte']:
new_data['nom_compte_payment'] = part_account[0]['nom_compte']
if ("num_carte" in part_account[0].keys()):
if part_account[0]['num_carte']:
new_data['num_carte_payment'] = part_account[0]['num_carte']
new_data['valide'] = "1"
now = datetime.now()
@ -572,7 +583,10 @@ def createOrder(diction):
return_document=ReturnDocument.AFTER
)
# Facturation de la commande
print(" ######## lancement de la facturation total_ttc_float = " + str(total_ttc_float))
if (total_ttc_float > 0):
CreateInvoice(new_data)
return True, "la commande été correctement créee", str(new_data['order_id'])
else:
@ -586,3 +600,177 @@ def createOrder(diction):
return False, " Impossible de créer la facture"
"""
Cette fontion recuperer l'id de la dernière facture
"""
def Get_Last_Invoice_ID():
try:
last_invoice_id = 0
coll_invoice = MYSY_GV.dbname["factures"]
tmp_val = coll_invoice.count_documents({})
if( tmp_val ):
last_invoice_id = tmp_val
return True, last_invoice_id
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 recuperer l'ID de la dernière facture "
"""
Cette fonction créer une facture
"""
def CreateInvoice(diction):
try:
field_list_obligatoire = ['client_recid', 'invoice_nom', 'order_id', 'order_date', 'total_ttc','total_tva','total_ht','item_0']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le champ '" + val + "' n'existe pas, Creation facture annulée")
return False, " Impossible de créer la facture"
order_id = ""
status_tmp, last_invoice_id = Get_Last_Invoice_ID()
if( status_tmp is False):
mycommon.myprint(str(inspect.stack()[0][
3]) + " Impossible de recuperer Get_Last_Invoice_ID ")
return False, " Impossible de créer la facture"
print(" ######## last_invoice_id = "+str(last_invoice_id))
last_invoice_id = last_invoice_id + 1
Order_Invoice = "MySy_0000"+str(last_invoice_id)
diction['invoice_id']= str(Order_Invoice)
now = datetime.now()
diction['due_date'] = str(now.strftime("%d/%m/%Y"))
diction['invoice_date'] = str(now.strftime("%d/%m/%Y"))
diction['printed'] = "0"
print(" collection de facture = "+str(diction))
coll_facture = MYSY_GV.dbname['factures']
ret_val = coll_facture.insert_one(diction)
if ret_val and ret_val.inserted_id:
print("str(new_data['invoice_email']) = " + str(diction['invoice_email']))
print("str(diction['invoice_id']) = " + str(diction['invoice_id']))
# Envoie de l'email de la facture
PrintAndSendInvoices(str(diction['invoice_id']))
#email.SalesOrderConfirmationEmail(str(new_data['invoice_email']), new_data)
return 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 facturer la commande N° "+str(order_id)+" "
"""
Cette fonction recupere toutes le factures non imprimé (c'est a dire que le pdf n'est pas créé)
1 - Crée le fichier PDF
2 - Envoie l'email avec la facture
"""
def PrintAndSendInvoices(invoice_id=None):
try:
i = 0
query = {'printed':'0'}
if ( invoice_id and len(str(invoice_id)) > 0):
query = {'printed':'0','factures':str(invoice_id) }
coll_invoice = MYSY_GV.dbname['factures']
for val in coll_invoice.find({'printed':'0'}):
i = i +1
if( convertHtmlToPdf( val ) is False ):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible d'imprimer la facture N° "+
str(val['invoice_id']))
else:
mycommon.myprint(" Impression facture N° " +str(val['invoice_id'])+" OK")
ret_val = coll_invoice.find_one_and_update(
{'invoice_id': str(val['invoice_id'])}, {"$set": {'printed':'1'}},
upsert=False,
return_document=ReturnDocument.AFTER
)
if (ret_val['_id'] is False):
mycommon.myprint(" Impression facture N° " +str(val['invoice_id'])+" ==> Impossible de mettre à jour la facture")
return True, str(i)+" Factures ont été traitées"
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, " Impossible d'imprimer les factures "
def convertHtmlToPdf(diction):
try:
field_list_obligatoire =['invoice_nom', 'invoice_adr_street', 'invoice_adr_zip', 'invoice_adr_city',
'invoice_adr_country', 'invoice_id', 'invoice_date', 'due_date', 'order_id', 'item_0', 'total_ht', 'total_tva', 'total_ttc',]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
return False, " Impossible d'imprimer les factures"
templateLoader = jinja2.FileSystemLoader(searchpath="./")
templateEnv = jinja2.Environment(loader=templateLoader)
TEMPLATE_FILE = "Template/invoice.html"
template = templateEnv.get_template(TEMPLATE_FILE)
# This data can come from database query
body = {
"data": {
"client_name": str(diction['invoice_nom']),
"client_address": str(diction['invoice_adr_street']),
"client_zip_ville": str(diction['invoice_adr_zip'])+" "+str(diction['invoice_adr_city']),
"client_pays": str(diction['invoice_adr_country']),
"invoice_id": str(diction['invoice_id']),
"invoice_date": str(diction['invoice_date']),
"due_date": str(diction['due_date']),
"orign_order": str(diction['order_id']),
"packs": str(diction['item_0']['code']),
"qty": str(diction['item_0']['qty']),
"unit_price": str(diction['item_0']['prix']),
"montant": str(diction['item_0']['amount']),
"total_ht": str(diction['total_ht']),
"tva": str(diction['total_tva']),
"total_ttc": str(diction['total_ttc']),
}
}
sourceHtml = template.render(json_data=body["data"])
outputFilename = "invoice_"+str(diction['invoice_id'])+"_.pdf"
# 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()
# On deplace la facture vers le serveur ftp
os.rename(outputFilename, MYSY_GV.INVOICE_DIRECTORY+outputFilename)
print(" debut envoie de la factureeee "+diction['invoice_id'])
email.SendInvoiceEmail(str(diction['invoice_email']), diction )
# return True on success and False on errors
print(pisaStatus.err, type(pisaStatus.err))
return True
except Exception as e:
print("Exception when calling SMTPApi->send_transac_email: %s\n" % e)
return False

View File

@ -495,6 +495,153 @@ def SalesOrderConfirmationEmail(account_mail, diction):
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
print(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False
"""
Cette fonction envoi les factures
"""
def SendInvoiceEmail(account_mail, diction):
try:
'''
Verification des données obligatoires
'''
'''
Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
On controle que les champs obligatoires sont presents dans la liste
'''
field_list_obligatoire = ['invoice_nom', 'invoice_adr_street', 'invoice_adr_zip', 'invoice_adr_city',
'invoice_adr_country', 'invoice_id', 'invoice_date', 'due_date', 'order_id', 'item_0',
'total_ht', 'total_tva', 'total_ttc', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
return False, " Impossible d'envoyer la facture par email"
order_id = diction['order_id']
date_order = diction['order_date']
client_name = str(diction['invoice_nom'])
client_address= str(diction['invoice_adr_street'])
client_zip_ville = str(diction['invoice_adr_zip']) + " " + str(diction['invoice_adr_city'])
client_pays = str(diction['invoice_adr_country'])
invoice_id = str(diction['invoice_id'])
invoice_date = str(diction['invoice_date'])
due_date = str(diction['due_date'])
orign_order = str(diction['order_id'])
packs = str(diction['item_0']['code'])
qty = str(diction['item_0']['qty'])
unit_price = str(diction['item_0']['prix'])
montant = str(diction['item_0']['amount'])
total_ht = str(diction['total_ht'])
tva = str(diction['total_tva'])
total_ttc = str(diction['total_ttc'])
my_end_date = ""
if ("end_date" in diction.keys()):
if diction.keys():
my_end_date = "*Offre valable jusqu'au "+str(diction['end_date'])
nb_line = mycommon.tryInt(diction['nb_product'])
if( nb_line == 0 ):
mycommon.myprint(str(inspect.stack()[0][3]) + " - nb_line = '" + nb_line + "' : Aucun produit à facturer")
return False, " Impossible d'envoyer l'email de confirmation"
print("Facture client_name = "+str(client_name))
print("Facture client_address = " + str(client_address))
print("Facture client_zip_ville = " + str(client_zip_ville))
print("Facture client_pays = " + str(client_pays))
print("Facture order_id = " + str(order_id))
print("Facture date_order = " + str(date_order))
print("Facture nb_line = " + str(nb_line))
print("Facture End Date = " + str(my_end_date))
# Recuperation des produits (max 3 produits)
# produit 1
if ("item_0" in diction.keys()):
if( diction["item_0"] ):
packs = diction["item_0"]['code']
qty = diction["item_0"]['qty']
unit_price = diction["item_0"]['prix']
montant = diction["item_0"]['amount']
detail_packs = diction["item_0"]['pack_products']
print("diction['item_0']['pack_products'] = "+str(diction["item_0"]['pack_products']))
# produit 2
if ("item_1" in diction.keys()):
if (diction["item_1"]):
packs1 = diction["item_1"]['code']
qty1 = diction["item_0"]['qty']
unit_price1 = diction["item_1"]['prix']
montant1 = diction["item_1"]['amount']
detail_packs1 = diction["item_1"]['pack_products']
# produit 3
if ("item_2" in diction.keys()):
if (diction["item_2"]):
packs2 = diction["item_2"]['code']
qty2 = diction["item_0"]['qty']
unit_price2 = diction["item_2"]['prix']
montant2 = diction["item_2"]['amount']
detail_packs2 = diction["item_1"]['pack_products']
i = 0
while (i < nb_line):
row = "item_" + str(i)
print(" product = "+ str(diction[str(row)]))
i = i + 1
receiver = [str(account_mail)]
toaddrs = ", ".join(receiver)
print("Facture mail enoye à toaddrs : " + toaddrs)
print("Facture debut envoi mail de test ")
# on rentre les renseignements pris sur le site du fournisseur
msg = MIMEMultipart("alternative")
msg['Subject'] = '[MySy Training]: votre compte PRO est pret'
msg['From'] = 'contact@mysy-training.com'
msg['To'] = str(toaddrs)
msg['Cc'] = 'contact@mysy-training.com'
to = [{"email": str(account_mail)}]
print(" Facture ############# to = "+str(to))
bcc = [{"email": "contact@mysy-training.com"}]
send_smtp_email = sib_api_v3_sdk.SendSmtpEmail(template_id=23, params={"order_id": order_id,
"date_order": date_order,
"total_ht": total_ht,
"tva": tva,
"total_ttc": total_ttc,
"client_name": client_name,
"client_address": client_address,
"client_zip_ville": client_zip_ville,
"client_pays": client_pays,
"packs": packs,
"detail_packs": detail_packs,
"qty": qty,
"unit_price": unit_price,
"montant":montant,
"invoice_id":invoice_id,
"invoice_date":invoice_date,
"due_date":due_date,
"orign_order":orign_order,
}, to=to, bcc=bcc)
api_response = api_instance.send_transac_email(send_smtp_email)
print("Facture "+str(api_response))
return True
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
print(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))

17
main.py
View File

@ -26,6 +26,7 @@ import youtubes_analyse as YTA
import test_perso as TP
import ela_factures_mgt as invoice
import product_service as PS
import ela_factures_mgt as factures
app = Flask(__name__)
cors = CORS(app, resources={r"/foo": {"origins": "*"}})
@ -1315,6 +1316,22 @@ def Get_Suggested_Word():
status, message = mycommon.Get_Suggested_Word()
return jsonify(status=status, message=message)
"""
Cette API imprime et envoie les factures aux clients
"""
@app.route('/myclass/api/PrintAndSendInvoices/', methods=['GET','POST'])
@crossdomain(origin='*')
def PrintAndSendInvoices():
# On recupere le corps (payload) de la requete
payload = request.form.to_dict()
print(" ### payload = ", str(payload))
status, message = factures.PrintAndSendInvoices()
return jsonify(status=status, message=message)
if __name__ == '__main__':
print(" debut api")
context = SSL.Context(SSL.SSLv23_METHOD)

View File

@ -26,11 +26,11 @@ from pymongo import ReturnDocument
from unidecode import unidecode
import GlobalVariable as MYSY_GV
from serpapi import GoogleSearch
import prj_common as mycommon
import re
import email_mgt as email_mgt
import random
import json
import Ela_Spacy as ElaSpacy
class JSONEncoder(json.JSONEncoder):
def default(self, o):
@ -1081,7 +1081,6 @@ def GetMotFromElaIndex(diction):
'''
correction erreur titre mymooc.com
'''
def Migration_mooc_title():
try:
coll_name = MYSY_GV.dbname['myclass']
@ -1627,4 +1626,44 @@ def Get_partner_nb_active_training(partner_recid):
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
print(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, False
return False, False
""""
Cette fonction recuperer les mot du titre et de la description
pour remplir la collection des suggestions de mot
"""
def fillSuggestionCollection():
try:
coll_name = MYSY_GV.dbname['myclass']
for retVal in coll_name.find({'valide':'1'}).limit(10):
mytitle = str(retVal['title'])
mydesc = str(retVal['description'])
class_contact = str(mytitle)+". "+str(mydesc)
class_token = ElaSpacy.Ela_Tokenize(class_contact)
status, tab_tokens2 = ElaSpacy.Ela_remove_stop_words(class_token)
if (status is False):
break
status, tab_tokens3 = ElaSpacy.Ela_remove_pronoun(tab_tokens2)
if (status is False):
break
status, tab_tokens4 = ElaSpacy.Ela_stemmize_Class(tab_tokens3)
if (status is False):
break
print(" Pour "+str(retVal['title'])+" : On a "+str(tab_tokens4))
return True
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
print(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False,