Elyos_FI_Back_Office/partner_invoice.py

7492 lines
371 KiB
Python

"""
Ce fichier permet de gerer la facturation des commandes des partenaires vers leur client.
Il se base sur les commandes faite à l'aide du fichier "partner_order.py"
"""
import ast
from calendar import monthrange
import bson
import pymongo
from pymongo import MongoClient
import json
from bson import ObjectId
import re
from datetime import datetime, timedelta, date
import Session_Formation
import invoice_paiement_mgt
import partners
import prj_common as mycommon
import secrets
import inspect
import sys, os
import csv
import pandas as pd
from pymongo import ReturnDocument
import GlobalVariable as MYSY_GV
from math import isnan
import GlobalVariable as MYSY_GV
import ela_index_bdd_classes as eibdd
import email_mgt as email
import jinja2
from flask import send_file
from xhtml2pdf import pisa
from email.message import EmailMessage
from email.mime.text import MIMEText
from email import encoders
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import partner_order as partner_order
import base64
from prj_common import tryFloat
"""
Creation de la facture d'un commande
"""
def Invoice_Partner_Order(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'order_id', 'order_ref_interne']
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", False
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', 'order_id', 'order_ref_interne']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
return False, " Les informations fournies sont incorrectes",False
"""
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, False
# Verification de la validité de la commande à facturer
order_to_invoice_data_count = MYSY_GV.dbname['partner_order_header'].count_documents(
{'_id': ObjectId(str(diction['order_id'])), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner['recid'], 'order_header_type':'commande', 'valide': '1',
'locked': '0'})
if( order_to_invoice_data_count < 0 ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - Les references de la commande sont invalides ")
return False, " Les references de la commande sont invalides", False
if (order_to_invoice_data_count > 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - Les references correspondent à plusieurs commandes. Facturation annulée. ")
return False, " Les references correspondent à plusieurs commandes. Facturation annulée.",False
order_to_invoice_data = MYSY_GV.dbname['partner_order_header'].find_one({'_id':ObjectId(str(diction['order_id'])), 'order_header_ref_interne':str(diction['order_ref_interne']),
'partner_owner_recid':my_partner['recid'], 'valide':'1',
'locked':'0', 'order_header_type':'commande'})
print(" #### order_to_invoice_data = ", order_to_invoice_data);
if( order_to_invoice_data is None or str(order_to_invoice_data['order_header_status']) != "2" ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - La commande n'est pas au statut 'Traité'. Facturation annulée. ")
return False, " La commande n'est pas au statut 'Traité'. Facturation annulée.",False
# Verifier que toutes lignes sont au statut 'traité'
nb_line_a_facturer = 0
for order_lines_to_invoice_data in MYSY_GV.dbname['partner_order_line'].find(
{'order_header_id': str(diction['order_id']), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner['recid']}):
nb_line_a_facturer = nb_line_a_facturer +1
if( str(order_lines_to_invoice_data['order_line_type']) != "commande" or str(order_lines_to_invoice_data['order_line_status']) != "2"
or str(order_lines_to_invoice_data['valide']) != "1" or str(order_lines_to_invoice_data['locked']) != "0"):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - La ligne de commande "+str(order_lines_to_invoice_data['order_line_formation'])+" avec la Quantite "+ str(order_lines_to_invoice_data['order_line_qty'])+" n'est pas cohérente. Facturation annulée. ")
return False, " La ligne de commande "+str(order_lines_to_invoice_data['order_line_formation'])+" avec la Quantite "+ str(order_lines_to_invoice_data['order_line_qty'])+" n'est pas cohérente. Facturation annulée.",False
if( nb_line_a_facturer == 0):
# Alors il n'y a aucune ligne à facturer
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Il n'y a aucune ligne à facturer. Facturation annulée. ")
return False, "Il n'y a aucune ligne à facturer. Facturation annulée.",False
# Verification de la validité du client
is_client_valide = MYSY_GV.dbname['partner_client'].count_documents({'_id':ObjectId(str(order_to_invoice_data['order_header_client_id'])),
'valide':'1', 'locked':'0', 'partner_owner_recid':str(my_partner['recid'])})
if( is_client_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le client à facturer est invalide. Facturation annulée. ")
return False, "Le client à facturer est invalide. Facturation annulée.",False
"""
A présent la commande est valide, on va
0 - Mettre à jour la commande en mettant le statut "facturé' ==> comme ca on bloque d'evenuelles modification de la commande
1 - Relancer un compute de la commande
2 - copier les données dans la collection 'facture'
3 - on met à jour les lignes de la commande, pr la mettre à facturé
"""
# 0 - Mettre à jour la commande en mettant le statut "facturé' ==> comme ca on bloque d'evenuelles modification de la commande
order_updated = MYSY_GV.dbname['partner_order_header'].update_one({'_id':ObjectId(str(diction['order_id'])), 'order_header_ref_interne':str(diction['order_ref_interne']),
'partner_owner_recid':my_partner['recid'], 'valide':'1',
'locked':'0', 'order_header_type':'commande'},
{'$set':{'order_header_status':'3'}
}
)
if(order_updated.modified_count != 1 ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de verrouiller la commande à facturer. Facturation annulée. ")
return False, "Impossible de verrouiller la commande à facturer. Facturation annulée.",False
# 1 - Relancer un compute de la commande
comput_diction = {}
comput_diction['token'] = diction['token']
comput_diction['_id'] = diction['order_id']
local_retval, local_message = partner_order.Compute_Order_Header(comput_diction)
if (local_retval is False):
order_updated = MYSY_GV.dbname['partner_order_header'].update_one({{'_id': ObjectId(
str(diction['order_id'])), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner[
'recid'], 'valide': '1',
'locked': '0',
'order_header_type': 'commande'},
{'$set': {'order_header_status': '2'}}
})
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de mettre à jour les prix de la commande à facturer. Facturation annulée. ")
return False, "Impossible de mettre à jour les prix de la commande à facturer. Facturation annulée.",False
#2 - copier les données dans la collection 'facture'
"""
Important : On va recopier les header et line, tel quel.
On fera les changements plus tard si besoin
"""
# Récuperation de la sequence de l'objet "partner_invoice_header" dans la collection : "mysy_sequence"
retval_sequence_invoice = MYSY_GV.dbname['mysy_sequence'].find_one({'related_mysy_object': 'partner_invoice_header',
'valide': '1', 'partner_owner_recid': str(
my_partner['recid'])})
if (retval_sequence_invoice is None):
# Il n'y pas de sequence pour le partenaire, on va aller chercher la sequence par defaut
retval_sequence_invoice = MYSY_GV.dbname['mysy_sequence'].find_one(
{'related_mysy_object': 'partner_invoice_header',
'valide': '1', 'partner_owner_recid': 'default'})
if (retval_sequence_invoice is None or "current_val" not in retval_sequence_invoice.keys()):
# Il n'y aucune sequence meme par defaut.
order_updated = MYSY_GV.dbname['partner_order_header'].update_one({{'_id': ObjectId(
str(diction['order_id'])), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner[
'recid'], 'valide': '1',
'locked': '0',
'order_header_type': 'commande'},
{'$set': {'order_header_status': '2'}}
})
mycommon.myprint(" Impossible de récupérer la sequence 'retval_sequence_invoice' ")
return False, "Impossible de récupérer la sequence 'retval_sequence_invoice'", False
current_seq_value = str(retval_sequence_invoice['current_val'])
new_sequence_value = int(mycommon.tryInt(current_seq_value)) + 1
new_sequance_data_to_update = {'current_val': new_sequence_value}
ret_val2 = MYSY_GV.dbname['mysy_sequence'].find_one_and_update(
{'_id': ObjectId(str(retval_sequence_invoice['_id'])), 'valide': '1'},
{"$set": new_sequance_data_to_update},
return_document=ReturnDocument.AFTER,
upsert=False,
)
invoice_date_time = str(datetime.now().strftime("%d/%m/%Y"))
new_invoice_data_header = MYSY_GV.dbname['partner_order_header'].find_one({'_id':ObjectId(str(diction['order_id'])), 'order_header_ref_interne':str(diction['order_ref_interne']),
'partner_owner_recid':my_partner['recid'], 'valide':'1',
'locked':'0', 'order_header_type':'commande'}, {'_id':0, 'order_header_type':0, 'order_header_status':0})
print(" #### A COPIER new_invoice_data_header = ", str(new_invoice_data_header))
invoice_ref_interne = retval_sequence_invoice['prefixe']+str(current_seq_value)
new_invoice_data_header['invoice_header_ref_interne'] = invoice_ref_interne
new_invoice_data_header['invoice_header_type'] = "facture"
new_invoice_data_header['status'] = "1"
new_invoice_data_header['invoice_date'] = invoice_date_time
new_invoice_data_header['update_by'] = str(my_partner['_id'])
"""
Calcul de la date d'échance de la facture :
Si pas de conidtion de paiement, alors la date à la date du jour
"""
if( "order_header_condition_paiement_id" in new_invoice_data_header.keys() and
new_invoice_data_header['order_header_condition_paiement_id'] ) :
paiement_condition_data = MYSY_GV.dbname['base_partner_paiement_condition'].find_one({'partner_owner_recid':str(my_partner['recid']),
'_id':ObjectId(str(new_invoice_data_header['order_header_condition_paiement_id'])),
'valide':'1',
'locked':'0'})
if(paiement_condition_data is None or 'depart' not in paiement_condition_data.keys() or
'nb_jour' not in paiement_condition_data.keys() ):
mycommon.myprint(str(inspect.stack()[0][3]) + " WARNING - DATE ECHEANCE : Condition de paiement invalide pour calculer la date d'échéance ")
if( paiement_condition_data['depart'] not in MYSY_GV.PAIEMENT_CONDITION_DEPART ):
mycommon.myprint(str(inspect.stack()[0][3]) + " WARNING - DATE ECHEANCE : Condition de départ n'est pas dans la liste "+str(MYSY_GV.PAIEMENT_CONDITION_DEPART))
nb_jour_int = mycommon.tryInt(str(paiement_condition_data['nb_jour']))
today = datetime.today()
date_echance = datetime.today()
if (str(paiement_condition_data['depart']) == "mois"):
days_in_month = lambda dt: monthrange(dt.year, dt.month)[1]
first_day_next_month = today.replace(day=1) + timedelta(days_in_month(today))
date_echance = first_day_next_month + timedelta(days=nb_jour_int)
if( str(paiement_condition_data['depart']) == "facture") :
date_echance = today + timedelta(days=nb_jour_int)
date_echance = date_echance.strftime("%d/%m/%Y")
new_invoice_data_header['invoice_date_echeance'] = str(date_echance)
new_invoice_data_header['order_header_condition_paiement_code'] = str(paiement_condition_data['code'])
new_invoice_data_header['order_header_condition_paiement_description'] = str(paiement_condition_data['description'])
else:
today = datetime.today()
date_echance = datetime.today().strftime("%d/%m/%Y")
new_invoice_data_header['invoice_date_echeance'] = str(date_echance)
new_invoice_data_header['order_header_condition_paiement_code'] = ""
new_invoice_data_header['order_header_condition_paiement_description'] = ""
inserted_invoice_id = MYSY_GV.dbname['partner_invoice_header'].insert_one(new_invoice_data_header).inserted_id
if (not inserted_invoice_id):
order_updated = MYSY_GV.dbname['partner_order_header'].update_one({{'_id': ObjectId(
str(diction['order_id'])), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner[
'recid'], 'valide': '1',
'locked': '0',
'order_header_type': 'commande'},
{'$set': {'order_header_status': '2'}}
})
mycommon.myprint(
" Impossible de créer l'entete de la facture ")
return False, "Impossible de créer l'entete de la facture ", False
tab_session_3001 = []
for new_invoice_data_line in MYSY_GV.dbname['partner_order_line'].find( {'order_header_id': str(diction['order_id']), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner['recid']}, {'_id':0, 'order_line_type':0, 'order_line_status':0,
}):
new_invoice_data_line['invoice_header_ref_interne'] = retval_sequence_invoice['prefixe']+str(current_seq_value)
new_invoice_data_line['invoice_line_type'] = "facture"
new_invoice_data_line['invoice_date'] = invoice_date_time
new_invoice_data_line['invoice_header_id'] = str(inserted_invoice_id)
new_invoice_data_line['update_by'] = str(my_partner['_id'])
if( "order_line_session_id" in new_invoice_data_line.keys() and new_invoice_data_line['order_line_session_id']):
tab_session_3001.append(str(new_invoice_data_line['order_line_session_id']))
work_tab = []
if ("order_line_tab_inscrit_id" in new_invoice_data_line.keys()):
for tmp in new_invoice_data_line['order_line_tab_inscrit_id']:
if ("_id" in tmp.keys() and tmp['_id']):
work_tab.append(ObjectId(str(tmp['_id'])))
del new_invoice_data_line['order_line_tab_inscrit_id']
new_invoice_data_line['tab_inscription_ids'] = work_tab
#print(" ### on Va inserer la ligne de factue new_invoice_data_line = ", new_invoice_data_line)
inserted_line = MYSY_GV.dbname['partner_invoice_line'].insert_one(new_invoice_data_line)
#print(" ### inserted_line de la ligne inserée = ", inserted_line)
inserted_line_id = inserted_line.inserted_id
#print(" ### inserted_line_id de la ligne inserée = ", inserted_line_id)
if (not inserted_line_id):
# Vu quil y a un souci avec l'une des lignes, on fait un roll back complet de la facturation
order_updated = MYSY_GV.dbname['partner_order_header'].update_one({{'_id': ObjectId(
str(diction['order_id'])), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner[
'recid'], 'valide': '1',
'locked': '0',
'order_header_type': 'commande'},
{'$set': {'order_header_status': '2'}}
})
MYSY_GV.dbname['partner_invoice_header'].delete_one({'_id':ObjectId(str(str(inserted_invoice_id)))})
MYSY_GV.dbname['partner_invoice_line'].delete_many({'invoice_header_id': ObjectId(str(str(inserted_invoice_id)))})
mycommon.myprint(
" Impossible de finaliser la facturation des lignes de la ligne la commande ")
return False, " Impossible de finaliser la facturation des lignes de la ligne la commande. ", False
"""
04/10/2024 - update pour faire le BPF
on va créer une table de detail qui reprend le detail des inscription
"""
"""
09/01/2026 - si on a des inscrits idenifié - new_invoice_data_line['tab_inscription_ids'] = work_tab
Alors on va aller recuperer les données de l'inscrits
"""
if(len(work_tab) > 0 ):
for inscrit in work_tab:
inscrit_data = MYSY_GV.dbname['inscription'].find_one({'_id':ObjectId(str(inscrit)), 'partner_owner_recid':my_partner['recid']})
partner_invoice_line_data_detail = {}
partner_invoice_line_data_detail['order_line_inscription_id'] = str(inscrit_data['_id'])
partner_invoice_line_data_detail['order_line_inscription_type_apprenant'] = str( inscrit_data['type_apprenant'])
partner_invoice_line_data_detail['order_line_inscription_modefinancement'] = str( inscrit_data['modefinancement'])
partner_invoice_line_data_detail['order_line_formation'] = str(new_invoice_data_line['order_line_formation'])
"""
27/07/25 : aller recuperer le 'class_id'
"""
local_class_id = ""
if ("order_line_formation" in new_invoice_data_line.keys() and new_invoice_data_line[
'order_line_formation']):
class_data = MYSY_GV.dbname['myclass'].find_one(
{'internal_url': str(new_invoice_data_line['order_line_formation']),
'partner_owner_recid': str(my_partner['recid'])}, {'_id': 1})
if (class_data and '_id' in class_data.keys()):
local_class_id = str(class_data['_id'])
partner_invoice_line_data_detail['order_line_class_id'] = local_class_id
partner_invoice_line_data_detail['order_line_prix_unitaire'] = str(inscrit_data['price'])
partner_invoice_line_data_detail['order_line_montant_hors_taxes'] = str( new_invoice_data_line['order_line_montant_hors_taxes'])
partner_invoice_line_data_detail['order_line_invoiced_amount'] = str( new_invoice_data_line['order_line_montant_hors_taxes'])
partner_invoice_line_data_detail['order_line_qty'] = "1"
if ("order_line_tab_inscrit_id" in new_invoice_data_line.keys()):
del new_invoice_data_line['order_line_tab_inscrit_id']
partner_invoice_line_data_detail['tab_inscription_ids'] = [ObjectId(str(inscrit_data['_id']))]
partner_invoice_line_data_detail['order_line_comment'] = ""
partner_invoice_line_data_detail['invoice_header_id'] = str(inserted_invoice_id)
partner_invoice_line_data_detail['invoice_line_type'] = "facture"
partner_invoice_line_data_detail['invoice_header_ref_interne'] = str(invoice_ref_interne)
order_line_is_include_bpf = ""
if ("order_header_inclus_bpf" in order_to_invoice_data.keys()):
order_line_is_include_bpf = order_to_invoice_data['order_header_inclus_bpf']
partner_invoice_line_data_detail['order_line_is_include_bpf'] = order_line_is_include_bpf
partner_invoice_line_data_detail['update_by'] = str(my_partner['_id'])
partner_invoice_line_data_detail['valide'] = "1"
partner_invoice_line_data_detail['locked'] = "0"
partner_invoice_line_data_detail['partner_owner_recid'] = str(my_partner['recid'])
print(" #### partner_invoice_line_data = ", partner_invoice_line_data_detail)
inserted_detail_invoice_line_id = MYSY_GV.dbname['partner_invoice_line_detail'].insert_one(
partner_invoice_line_data_detail).inserted_id
else:
partner_invoice_line_data_detail = {}
partner_invoice_line_data_detail['order_line_inscription_id'] = ""
partner_invoice_line_data_detail['order_line_inscription_type_apprenant'] = str(new_invoice_data_line['order_line_type_apprenant'])
partner_invoice_line_data_detail['order_line_inscription_modefinancement'] = ""
partner_invoice_line_data_detail['order_line_formation'] = str(new_invoice_data_line['order_line_formation'])
"""
27/07/25 : aller recuperer le 'class_id'
"""
local_class_id = ""
if( "order_line_formation" in new_invoice_data_line.keys() and new_invoice_data_line['order_line_formation']):
class_data = MYSY_GV.dbname['myclass'].find_one({'internal_url':str(new_invoice_data_line['order_line_formation']),
'partner_owner_recid':str(my_partner['recid'])}, {'_id':1})
if( class_data and '_id' in class_data.keys() ):
local_class_id = str(class_data['_id'])
partner_invoice_line_data_detail['order_line_class_id'] = local_class_id
partner_invoice_line_data_detail['order_line_prix_unitaire'] = str(new_invoice_data_line['order_line_prix_unitaire'])
partner_invoice_line_data_detail['order_line_montant_hors_taxes'] = str(new_invoice_data_line['order_line_montant_hors_taxes'])
partner_invoice_line_data_detail['order_line_invoiced_amount'] = str(new_invoice_data_line['order_line_montant_hors_taxes'])
partner_invoice_line_data_detail['order_line_qty'] = str( new_invoice_data_line['order_line_qty'])
if( "order_line_tab_inscrit_id" in new_invoice_data_line.keys()):
del new_invoice_data_line['order_line_tab_inscrit_id']
partner_invoice_line_data_detail['tab_inscription_ids'] = work_tab
partner_invoice_line_data_detail['order_line_comment'] = ""
partner_invoice_line_data_detail['invoice_header_id'] = str(inserted_invoice_id)
partner_invoice_line_data_detail['invoice_line_type'] = "facture"
partner_invoice_line_data_detail['invoice_header_ref_interne'] = str(invoice_ref_interne)
order_line_is_include_bpf = ""
if ("order_header_inclus_bpf" in order_to_invoice_data.keys()):
order_line_is_include_bpf = order_to_invoice_data['order_header_inclus_bpf']
partner_invoice_line_data_detail['order_line_is_include_bpf'] = order_line_is_include_bpf
partner_invoice_line_data_detail['update_by'] = str(my_partner['_id'])
partner_invoice_line_data_detail['valide'] = "1"
partner_invoice_line_data_detail['locked'] = "0"
partner_invoice_line_data_detail['partner_owner_recid'] = str(my_partner['recid'])
print(" #### partner_invoice_line_data = ", partner_invoice_line_data_detail)
inserted_detail_invoice_line_id = MYSY_GV.dbname['partner_invoice_line_detail'].insert_one(
partner_invoice_line_data_detail).inserted_id
# 3 - on met à jour les lignes de la commande, pr la mettre à facturé
qry = {'order_header_id': str(diction['order_id']), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner['recid'], 'valide': '1',
'locked': '0', 'order_header_type': 'commande'}
#print(" #### qry = ", qry)
order_updated = MYSY_GV.dbname['partner_order_line'].update_many(
{'order_header_id': str(diction['order_id']), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner['recid'], 'valide': '1',
'locked': '0', 'order_line_type': 'commande'},
{'$set': {'order_line_status': '3'}}
)
if (order_updated.modified_count <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " WARNING - Impossible de mettre les lignes à facturer pour order_header_id = "+str(str(diction['order_id'])))
"""
05/06/2024 Gestion E-Facture
Apres la creation de la facture, on va aller créer le document securisé
"""
e_Invoice_Diction = {}
e_Invoice_Diction['token'] = diction['token']
e_Invoice_Diction['invoice_id'] = str(inserted_invoice_id)
local_E_Invoice_status, local_E_Invoice_retval = Session_Formation.Invoice_Create_Secure_E_Document(e_Invoice_Diction)
if (local_E_Invoice_status is False):
return True, "WARNING : La facture a été créée avec la réf. "+str(new_invoice_data_header['invoice_header_ref_interne'])+"; mais impossible de créer la e-Facture Sécurisée (1).", str(new_invoice_data_header['invoice_header_ref_interne'])
"""
30/01/2026 -
Après avoir créer la facture, on va aller mettre à jour les EVENTUELLE Session concernée avec les clients concernés.
C'est a dire, si le client facturé à des apprenants dans la session, je vais aller dire qu'ils sont facturés
les lignes sont facturés, je vais juste le num de facture comme ca depuis la session, on vera qu'il y a 2 facturer.
"""
if( "order_header_client_id" in new_invoice_data_header.keys() and new_invoice_data_header['order_header_client_id']
and "invoice_header_ref_interne" in new_invoice_data_header.keys() and new_invoice_data_header['invoice_header_ref_interne']
and "invoice_date" in new_invoice_data_header.keys() and new_invoice_data_header['invoice_date'] ):
now = str(datetime.now())
update_data = {}
update_data['invoiced'] = "1"
update_data['invoiced_ref'] = str(new_invoice_data_header['invoice_header_ref_interne'])
update_data['invoiced_date'] = new_invoice_data_header['invoice_date']
update_data['update_date'] = str(now)
update_data['update_by'] = str(my_partner['_id'])
update = MYSY_GV.dbname['inscription'].update_many({'partner_owner_recid': str(my_partner['recid']),
'session_id': {'$in':tab_session_3001},
'facture_client_rattachement_id': str(new_invoice_data_header['order_header_client_id']),
},
{'$set': update_data})
"""
Ajout l'action dans l'historique
"""
## Add to log history pour la facture
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = diction['token']
history_event_dict['related_collection'] = "partner_invoice_header"
history_event_dict['related_collection_recid'] = str(inserted_invoice_id)
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Creation facture"
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
## Add to log history pour la commande
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = diction['token']
history_event_dict['related_collection'] = "partner_order_header"
history_event_dict['related_collection_recid'] = str(diction['order_id'])
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Facturé. Ref. Facture :"+str(new_invoice_data_header['invoice_header_ref_interne'])
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
return True, " La commande a été correctement facturée", str(new_invoice_data_header['invoice_header_ref_interne'])
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de facturer la commande ", False
"""
Cette fonction permet de facturer un devis
"""
def Invoice_Partner_Quotation(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'order_id', 'order_ref_interne']
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", False
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', 'order_id', 'order_ref_interne']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
return False, " Les informations fournies sont incorrectes", False
"""
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, False
# Verification de la validité du devis à facturer
order_to_invoice_data_count = MYSY_GV.dbname['partner_order_header'].count_documents(
{'_id': ObjectId(str(diction['order_id'])), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner['recid'], 'order_header_type': 'devis', 'valide': '1',
'locked': '0'})
if (order_to_invoice_data_count < 0):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - Les references du devis sont invalides ")
return False, " Les references du devis sont invalides", False
if (order_to_invoice_data_count > 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Les references correspondent à plusieurs commandes. Facturation annulée. ")
return False, " Les references correspondent à plusieurs commandes. Facturation annulée.", False
order_to_invoice_data = MYSY_GV.dbname['partner_order_header'].find_one(
{'_id': ObjectId(str(diction['order_id'])), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner['recid'], 'valide': '1',
'locked': '0', 'order_header_type': 'devis'})
print(" #### order_to_invoice_data = ", order_to_invoice_data);
if (order_to_invoice_data is None or str(order_to_invoice_data['order_header_status']) not in ['1', '3'] ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le devis n'est pas au statut 'Confirmé' ou 'Gagné'. Facturation annulée. ")
return False, " Le devis n'est pas au statut 'Confirmé' ou 'Gagné'. Facturation annulée.", False
# Verifier que toutes lignes sont au statut 'traité'
nb_line_a_facturer = 0
for order_lines_to_invoice_data in MYSY_GV.dbname['partner_order_line'].find(
{'order_header_id': str(diction['order_id']),
'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner['recid']}):
nb_line_a_facturer = nb_line_a_facturer + 1
if (str(order_lines_to_invoice_data['order_line_type']) != "devis" or str(
order_lines_to_invoice_data['order_line_status']) not in ["1", "3"]
or str(order_lines_to_invoice_data['valide']) != "1" or str(
order_lines_to_invoice_data['locked']) != "0"):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - La ligne de commande " + str(
order_lines_to_invoice_data['order_line_formation']) + " avec la Quantité " + str(
order_lines_to_invoice_data['order_line_qty']) + " n'est pas cohérente. Facturation annulée. ")
return False, " La ligne de commande " + str(
order_lines_to_invoice_data['order_line_formation']) + " avec la Quantité " + str(
order_lines_to_invoice_data['order_line_qty']) + " n'est pas cohérente. Facturation annulée.", False
if (nb_line_a_facturer == 0):
# Alors il n'y a aucune ligne à facturer
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Il n'y a aucune ligne à facturer. Facturation annulée. ")
return False, "Il n'y a aucune ligne à facturer. Facturation annulée.", False
# Verification de la validité du client
is_client_valide = MYSY_GV.dbname['partner_client'].count_documents(
{'_id': ObjectId(str(order_to_invoice_data['order_header_client_id'])),
'valide': '1', 'locked': '0', 'partner_owner_recid': str(my_partner['recid'])})
if (is_client_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le client à facturer est invalide. Facturation annulée. ")
return False, "Le client à facturer est invalide. Facturation annulée.", False
"""
A présent la commande est valide, on va
0 - Mettre à jour la commande en mettant le statut "facturé' ==> comme ca on bloque d'evenuelles modification de la commande
1 - Relancer un compute de la commande
2 - copier les données dans la collection 'facture'
3 - on met à jour les lignes de la commande, pr la mettre à facturé
"""
# 0 - Mettre à jour la commande en mettant le statut "facturé' ==> comme ca on bloque d'evenuelles modification de la commande
order_updated = MYSY_GV.dbname['partner_order_header'].update_one(
{'_id': ObjectId(str(diction['order_id'])), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner['recid'], 'valide': '1',
'locked': '0', 'order_header_type': 'devis'},
{'$set': {'order_header_status': '5'}
}
)
if (order_updated.modified_count != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de verrouiller la commande à facturer. Facturation annulée. ")
return False, "Impossible de verrouiller la commande à facturer. Facturation annulée.", False
# 1 - Relancer un compute de la commande
comput_diction = {}
comput_diction['token'] = diction['token']
comput_diction['_id'] = diction['order_id']
local_retval, local_message = partner_order.Compute_Order_Header(comput_diction)
if (local_retval is False):
order_updated = MYSY_GV.dbname['partner_order_header'].update_one({{'_id': ObjectId(
str(diction['order_id'])), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner[
'recid'], 'valide': '1',
'locked': '0',
'order_header_type': 'devis'},
{'$set': {'order_header_status': '1'}}
})
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Impossible de mettre à jour les prix de la commande à facturer. Facturation annulée. ")
return False, "Impossible de mettre à jour les prix de la commande à facturer. Facturation annulée.", False
# 2 - copier les données dans la collection 'facture'
"""
Important : On va recopier les header et line, tel quel.
On fera les changements plus tard si besoin
"""
# Récuperation de la sequence de l'objet "partner_invoice_header" dans la collection : "mysy_sequence"
retval_sequence_invoice = MYSY_GV.dbname['mysy_sequence'].find_one(
{'related_mysy_object': 'partner_invoice_header',
'valide': '1', 'partner_owner_recid': str(
my_partner['recid'])})
if (retval_sequence_invoice is None):
# Il n'y pas de sequence pour le partenaire, on va aller chercher la sequence par defaut
retval_sequence_invoice = MYSY_GV.dbname['mysy_sequence'].find_one(
{'related_mysy_object': 'partner_invoice_header',
'valide': '1', 'partner_owner_recid': 'default'})
if (retval_sequence_invoice is None or "current_val" not in retval_sequence_invoice.keys()):
# Il n'y aucune sequence meme par defaut.
order_updated = MYSY_GV.dbname['partner_order_header'].update_one({{'_id': ObjectId(
str(diction['order_id'])), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner[
'recid'], 'valide': '1',
'locked': '0',
'order_header_type': 'devis'},
{'$set': {'order_header_status': '1'}}
})
mycommon.myprint(" Impossible de récupérer la sequence 'retval_sequence_invoice' ")
return False, "Impossible de récupérer la sequence 'retval_sequence_invoice'", False
current_seq_value = str(retval_sequence_invoice['current_val'])
new_sequence_value = int(mycommon.tryInt(current_seq_value)) + 1
new_sequance_data_to_update = {'current_val': new_sequence_value}
ret_val2 = MYSY_GV.dbname['mysy_sequence'].find_one_and_update(
{'_id': ObjectId(str(retval_sequence_invoice['_id'])), 'valide': '1'},
{"$set": new_sequance_data_to_update},
return_document=ReturnDocument.AFTER,
upsert=False,
)
invoice_date_time = str(datetime.now().strftime("%d/%m/%Y"))
new_invoice_data_header = MYSY_GV.dbname['partner_order_header'].find_one(
{'_id': ObjectId(str(diction['order_id'])), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner['recid'], 'valide': '1',
'locked': '0', 'order_header_type': 'devis'},
{'_id': 0, 'order_header_type': 0, 'order_header_status': 0})
print(" #### A COPIER new_invoice_data_header = ", str(new_invoice_data_header))
invoice_ref_interne = retval_sequence_invoice['prefixe'] + str(current_seq_value)
new_invoice_data_header['invoice_header_ref_interne'] = invoice_ref_interne
new_invoice_data_header['invoice_header_type'] = "facture"
new_invoice_data_header['status'] = "1"
new_invoice_data_header['invoice_date'] = invoice_date_time
new_invoice_data_header['update_by'] = str(my_partner['_id'])
"""
Calcul de la date d'échance de la facture :
Si pas de conidtion de paiement, alors la date à la date du jour
"""
if ("order_header_condition_paiement_id" in new_invoice_data_header.keys() and
new_invoice_data_header['order_header_condition_paiement_id']):
paiement_condition_data = MYSY_GV.dbname['base_partner_paiement_condition'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'_id': ObjectId(str(new_invoice_data_header['order_header_condition_paiement_id'])),
'valide': '1',
'locked': '0'})
if (paiement_condition_data is None or 'depart' not in paiement_condition_data.keys() or
'nb_jour' not in paiement_condition_data.keys()):
mycommon.myprint(str(inspect.stack()[0][
3]) + " WARNING - DATE ECHEANCE : Condition de paiement invalide pour calculer la date d'échéance ")
if (paiement_condition_data['depart'] not in MYSY_GV.PAIEMENT_CONDITION_DEPART):
mycommon.myprint(str(inspect.stack()[0][
3]) + " WARNING - DATE ECHEANCE : Condition de départ n'est pas dans la liste " + str(
MYSY_GV.PAIEMENT_CONDITION_DEPART))
nb_jour_int = mycommon.tryInt(str(paiement_condition_data['nb_jour']))
today = datetime.today()
date_echance = datetime.today()
if (str(paiement_condition_data['depart']) == "mois"):
days_in_month = lambda dt: monthrange(dt.year, dt.month)[1]
first_day_next_month = today.replace(day=1) + timedelta(days_in_month(today))
date_echance = first_day_next_month + timedelta(days=nb_jour_int)
if (str(paiement_condition_data['depart']) == "facture"):
date_echance = today + timedelta(days=nb_jour_int)
date_echance = date_echance.strftime("%d/%m/%Y")
new_invoice_data_header['invoice_date_echeance'] = str(date_echance)
new_invoice_data_header['order_header_condition_paiement_code'] = str(paiement_condition_data['code'])
new_invoice_data_header['order_header_condition_paiement_description'] = str(
paiement_condition_data['description'])
else:
today = datetime.today()
date_echance = datetime.today().strftime("%d/%m/%Y")
new_invoice_data_header['invoice_date_echeance'] = str(date_echance)
new_invoice_data_header['order_header_condition_paiement_code'] = ""
new_invoice_data_header['order_header_condition_paiement_description'] = ""
inserted_invoice_id = MYSY_GV.dbname['partner_invoice_header'].insert_one(new_invoice_data_header).inserted_id
if (not inserted_invoice_id):
order_updated = MYSY_GV.dbname['partner_order_header'].update_one({{'_id': ObjectId(
str(diction['order_id'])), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner[
'recid'], 'valide': '1',
'locked': '0',
'order_header_type': 'devis'},
{'$set': {'order_header_status': '5', 'invoice_header_ref_interne':str(new_invoice_data_header['invoice_header_ref_interne'])}}
})
mycommon.myprint(
" Impossible de créer l'entete de la facture ")
return False, "Impossible de créer l'entete de la facture ", False
tab_session_3001 = []
for new_invoice_data_line in MYSY_GV.dbname['partner_order_line'].find(
{'order_header_id': str(diction['order_id']),
'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner['recid']}, {'_id': 0, 'order_line_type': 0, 'order_line_status': 0,
}):
new_invoice_data_line['invoice_header_ref_interne'] = retval_sequence_invoice['prefixe'] + str(
current_seq_value)
new_invoice_data_line['invoice_line_type'] = "facture"
new_invoice_data_line['invoice_date'] = invoice_date_time
new_invoice_data_line['invoice_header_id'] = str(inserted_invoice_id)
new_invoice_data_line['update_by'] = str(my_partner['_id'])
if ("order_line_session_id" in new_invoice_data_line.keys() and new_invoice_data_line[
'order_line_session_id']):
tab_session_3001.append(str(new_invoice_data_line['order_line_session_id']))
work_tab = []
if ("order_line_tab_inscrit_id" in new_invoice_data_line.keys()):
for tmp in new_invoice_data_line['order_line_tab_inscrit_id']:
if ("_id" in tmp.keys() and tmp['_id']):
work_tab.append(ObjectId(str(tmp['_id'])))
del new_invoice_data_line['order_line_tab_inscrit_id']
new_invoice_data_line['tab_inscription_ids'] = work_tab
# print(" ### on Va inserer la ligne de factue new_invoice_data_line = ", new_invoice_data_line)
inserted_line = MYSY_GV.dbname['partner_invoice_line'].insert_one(new_invoice_data_line)
# print(" ### inserted_line de la ligne inserée = ", inserted_line)
inserted_line_id = inserted_line.inserted_id
# print(" ### inserted_line_id de la ligne inserée = ", inserted_line_id)
if (not inserted_line_id):
# Vu quil y a un souci avec l'une des lignes, on fait un roll back complet de la facturation
order_updated = MYSY_GV.dbname['partner_order_header'].update_one({{'_id': ObjectId(
str(diction['order_id'])), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner[
'recid'], 'valide': '1',
'locked': '0',
'order_header_type': 'devis'},
{'$set': {'order_header_status': '2', 'invoice_header_ref_interne':''}}
})
MYSY_GV.dbname['partner_invoice_header'].delete_one({'_id': ObjectId(str(str(inserted_invoice_id)))})
MYSY_GV.dbname['partner_invoice_line'].delete_many(
{'invoice_header_id': ObjectId(str(str(inserted_invoice_id)))})
mycommon.myprint(
" Impossible de finaliser la facturation des lignes de la ligne la commande ")
return False, " Impossible de finaliser la facturation des lignes de la ligne la commande. ", False
"""
04/10/2024 - update pour faire le BPF
on va créer une table de detail qui reprend le detail des inscription
"""
"""
09/01/2026 - si on a des inscrits idenifié - new_invoice_data_line['tab_inscription_ids'] = work_tab
Alors on va aller recuperer les données de l'inscrits
"""
if (len(work_tab) > 0):
for inscrit in work_tab:
inscrit_data = MYSY_GV.dbname['inscription'].find_one(
{'_id': ObjectId(str(inscrit)), 'partner_owner_recid': my_partner['recid']})
partner_invoice_line_data_detail = {}
partner_invoice_line_data_detail['order_line_inscription_id'] = str(inscrit_data['_id'])
partner_invoice_line_data_detail['order_line_inscription_type_apprenant'] = str(
inscrit_data['type_apprenant'])
partner_invoice_line_data_detail['order_line_inscription_modefinancement'] = str(
inscrit_data['modefinancement'])
partner_invoice_line_data_detail['order_line_formation'] = str(
new_invoice_data_line['order_line_formation'])
"""
27/07/25 : aller recuperer le 'class_id'
"""
local_class_id = ""
if ("order_line_formation" in new_invoice_data_line.keys() and new_invoice_data_line[
'order_line_formation']):
class_data = MYSY_GV.dbname['myclass'].find_one(
{'internal_url': str(new_invoice_data_line['order_line_formation']),
'partner_owner_recid': str(my_partner['recid'])}, {'_id': 1})
if (class_data and '_id' in class_data.keys()):
local_class_id = str(class_data['_id'])
partner_invoice_line_data_detail['order_line_class_id'] = local_class_id
partner_invoice_line_data_detail['order_line_prix_unitaire'] = str(inscrit_data['price'])
partner_invoice_line_data_detail['order_line_montant_hors_taxes'] = str(
new_invoice_data_line['order_line_montant_hors_taxes'])
partner_invoice_line_data_detail['order_line_invoiced_amount'] = str(
new_invoice_data_line['order_line_montant_hors_taxes'])
partner_invoice_line_data_detail['order_line_qty'] = "1"
if ("order_line_tab_inscrit_id" in new_invoice_data_line.keys()):
del new_invoice_data_line['order_line_tab_inscrit_id']
partner_invoice_line_data_detail['tab_inscription_ids'] = [ObjectId(str(inscrit_data['_id']))]
partner_invoice_line_data_detail['order_line_comment'] = ""
partner_invoice_line_data_detail['invoice_header_id'] = str(inserted_invoice_id)
partner_invoice_line_data_detail['invoice_line_type'] = "facture"
partner_invoice_line_data_detail['invoice_header_ref_interne'] = str(invoice_ref_interne)
order_line_is_include_bpf = ""
if ("order_header_inclus_bpf" in order_to_invoice_data.keys()):
order_line_is_include_bpf = order_to_invoice_data['order_header_inclus_bpf']
partner_invoice_line_data_detail['order_line_is_include_bpf'] = order_line_is_include_bpf
partner_invoice_line_data_detail['update_by'] = str(my_partner['_id'])
partner_invoice_line_data_detail['valide'] = "1"
partner_invoice_line_data_detail['locked'] = "0"
partner_invoice_line_data_detail['partner_owner_recid'] = str(my_partner['recid'])
print(" #### partner_invoice_line_data = ", partner_invoice_line_data_detail)
inserted_detail_invoice_line_id = MYSY_GV.dbname['partner_invoice_line_detail'].insert_one(
partner_invoice_line_data_detail).inserted_id
else:
partner_invoice_line_data_detail = {}
partner_invoice_line_data_detail['order_line_inscription_id'] = ""
partner_invoice_line_data_detail['order_line_inscription_type_apprenant'] = str(
new_invoice_data_line['order_line_type_apprenant'])
partner_invoice_line_data_detail['order_line_inscription_modefinancement'] = ""
partner_invoice_line_data_detail['order_line_formation'] = str(
new_invoice_data_line['order_line_formation'])
"""
27/07/25 : aller recuperer le 'class_id'
"""
local_class_id = ""
if ("order_line_formation" in new_invoice_data_line.keys() and new_invoice_data_line[
'order_line_formation']):
class_data = MYSY_GV.dbname['myclass'].find_one(
{'internal_url': str(new_invoice_data_line['order_line_formation']),
'partner_owner_recid': str(my_partner['recid'])}, {'_id': 1})
if (class_data and '_id' in class_data.keys()):
local_class_id = str(class_data['_id'])
partner_invoice_line_data_detail['order_line_class_id'] = local_class_id
partner_invoice_line_data_detail['order_line_prix_unitaire'] = str(
new_invoice_data_line['order_line_prix_unitaire'])
partner_invoice_line_data_detail['order_line_montant_hors_taxes'] = str(
new_invoice_data_line['order_line_montant_hors_taxes'])
partner_invoice_line_data_detail['order_line_invoiced_amount'] = str(
new_invoice_data_line['order_line_montant_hors_taxes'])
partner_invoice_line_data_detail['order_line_qty'] = str(new_invoice_data_line['order_line_qty'])
if ("order_line_tab_inscrit_id" in new_invoice_data_line.keys()):
del new_invoice_data_line['order_line_tab_inscrit_id']
partner_invoice_line_data_detail['tab_inscription_ids'] = work_tab
partner_invoice_line_data_detail['order_line_comment'] = ""
partner_invoice_line_data_detail['invoice_header_id'] = str(inserted_invoice_id)
partner_invoice_line_data_detail['invoice_line_type'] = "facture"
partner_invoice_line_data_detail['invoice_header_ref_interne'] = str(invoice_ref_interne)
order_line_is_include_bpf = ""
if ("order_header_inclus_bpf" in order_to_invoice_data.keys()):
order_line_is_include_bpf = order_to_invoice_data['order_header_inclus_bpf']
partner_invoice_line_data_detail['order_line_is_include_bpf'] = order_line_is_include_bpf
partner_invoice_line_data_detail['update_by'] = str(my_partner['_id'])
partner_invoice_line_data_detail['valide'] = "1"
partner_invoice_line_data_detail['locked'] = "0"
partner_invoice_line_data_detail['partner_owner_recid'] = str(my_partner['recid'])
print(" #### partner_invoice_line_data = ", partner_invoice_line_data_detail)
inserted_detail_invoice_line_id = MYSY_GV.dbname['partner_invoice_line_detail'].insert_one(
partner_invoice_line_data_detail).inserted_id
# 3 - on met à jour les lignes de la commande, pr la mettre à facturé
qry = {'order_header_id': str(diction['order_id']),
'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner['recid'], 'valide': '1',
'locked': '0', 'order_header_type': 'devis'}
# print(" #### qry = ", qry)
order_updated = MYSY_GV.dbname['partner_order_line'].update_many(
{'order_header_id': str(diction['order_id']), 'order_header_ref_interne': str(diction['order_ref_interne']),
'partner_owner_recid': my_partner['recid'], 'valide': '1',
'locked': '0', 'order_line_type': 'devis'},
{'$set': {'order_line_status': '5'}}
)
if (order_updated.modified_count <= 0):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " WARNING - Impossible de mettre les lignes à facturer pour order_header_id = " + str(
str(diction['order_id'])))
"""
05/06/2024 Gestion E-Facture
Apres la creation de la facture, on va aller créer le document securisé
"""
e_Invoice_Diction = {}
e_Invoice_Diction['token'] = diction['token']
e_Invoice_Diction['invoice_id'] = str(inserted_invoice_id)
local_E_Invoice_status, local_E_Invoice_retval = Session_Formation.Invoice_Create_Secure_E_Document(
e_Invoice_Diction)
if (local_E_Invoice_status is False):
return True, "WARNING : La facture a été créée avec la réf. " + str(new_invoice_data_header[
'invoice_header_ref_interne']) + "; mais impossible de créer la e-Facture Sécurisée (1).", str(
new_invoice_data_header['invoice_header_ref_interne'])
"""
30/01/2026 -
Après avoir créer la facture, on va aller mettre à jour les EVENTUELLE Session concernée avec les clients concernés.
C'est a dire, si le client facturé à des apprenants dans la session, je vais aller dire qu'ils sont facturés
les lignes sont facturés, je vais juste le num de facture comme ca depuis la session, on vera qu'il y a 2 facturer.
"""
if ("order_header_client_id" in new_invoice_data_header.keys() and new_invoice_data_header[
'order_header_client_id']
and "invoice_header_ref_interne" in new_invoice_data_header.keys() and new_invoice_data_header[
'invoice_header_ref_interne']
and "invoice_date" in new_invoice_data_header.keys() and new_invoice_data_header['invoice_date']):
now = str(datetime.now())
update_data = {}
update_data['invoiced'] = "1"
update_data['invoiced_ref'] = str(new_invoice_data_header['invoice_header_ref_interne'])
update_data['invoiced_date'] = new_invoice_data_header['invoice_date']
update_data['update_date'] = str(now)
update_data['update_by'] = str(my_partner['_id'])
update = MYSY_GV.dbname['inscription'].update_many({'partner_owner_recid': str(my_partner['recid']),
'session_id': {'$in': tab_session_3001},
'facture_client_rattachement_id': str(
new_invoice_data_header['order_header_client_id']),
},
{'$set': update_data})
"""
Ajout l'action dans l'historique
"""
## Add to log history pour la facture
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = diction['token']
history_event_dict['related_collection'] = "partner_invoice_header"
history_event_dict['related_collection_recid'] = str(inserted_invoice_id)
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Creation facture"
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
## Add to log history pour la commande
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = diction['token']
history_event_dict['related_collection'] = "partner_order_header"
history_event_dict['related_collection_recid'] = str(diction['order_id'])
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Facturé. Ref. Facture :" + str(
new_invoice_data_header['invoice_header_ref_interne'])
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
return True, " Le devis a été correctement facturée", str(
new_invoice_data_header['invoice_header_ref_interne'])
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de facturer le devis ", False
"""
Recuperation d'une facture donnée
"""
def Get_Given_Partner_Invoice(diction):
try:
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 la liste des arguments ")
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
"""
Clés de mise à jour
"""
data_cle = {}
data_cle['partner_owner_recid'] = str(my_partner['recid'])
data_cle['_id'] = ObjectId(str(diction['_id']))
data_cle['valide'] = "1"
data_cle['locked'] = "0"
RetObject = []
val_tmp = 1
#print(" ### data_cle = ", data_cle)
for retval in MYSY_GV.dbname['partner_invoice_header'].find(data_cle):
user = retval
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
if ("invoice_header_origin" not in user.keys()):
user['invoice_header_origin'] = ""
if ("credit_note_ref" not in user.keys()):
user['credit_note_ref'] = ""
# Si le champ 'order_header_condition_paiement_id' alors on va chercher le code de la condition de paiement
paiement_ction_code = ""
if ('order_header_condition_paiement_id' in retval.keys() and retval[
'order_header_condition_paiement_id']):
paiement_ction_data = MYSY_GV.dbname['base_partner_paiement_condition'].find_one(
{'_id': ObjectId(str(retval['order_header_condition_paiement_id'])), 'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (paiement_ction_data and 'code' in paiement_ction_data.keys()):
paiement_ction_code = str(paiement_ction_data['code'])
user['order_header_paiement_condition_code'] = paiement_ction_code
# Si le champ 'order_header_client_id' alors on va chercher le nom du client
if ('order_header_client_id' in retval.keys()):
Client_data = MYSY_GV.dbname['partner_client'].find_one(
{'_id': ObjectId(str(retval['order_header_client_id'])), 'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (Client_data and 'nom' in Client_data.keys()):
user['order_header_client_nom'] = str(Client_data['nom'])
# Si le champ 'order_header_vendeur_id' alors on va chercher le nom et prenom du vendeur (employe)
if ('order_header_vendeur_id' in retval.keys() and retval['order_header_vendeur_id']):
Employee_data = MYSY_GV.dbname['ressource_humaine'].find_one(
{'_id': ObjectId(str(retval['order_header_vendeur_id'])), 'valide': '1', 'locked': '0',
'partner_recid': str(my_partner['recid'])})
order_header_vendeur_nom_prenom = ""
if (Employee_data and 'nom' in Employee_data.keys()):
order_header_vendeur_nom_prenom = str(Employee_data['nom'])
if (Employee_data and 'prenom' in Employee_data.keys()):
order_header_vendeur_nom_prenom = str(order_header_vendeur_nom_prenom) + " " + str(
Employee_data['prenom'])
user['order_header_vendeur_nom_prenom'] = str(order_header_vendeur_nom_prenom)
# Recuperation des ligne associées
retval_line_data = []
for retval_line in MYSY_GV.dbname['partner_invoice_line'].find({'invoice_header_id':str(retval['_id']), 'partner_owner_recid':str(my_partner['recid']),
'valide':'1', 'locked':'0'}):
retval_line_data.append(retval_line)
RetObject.append(mycommon.JSONEncoder().encode(user))
#print(" ### RetObject = ", RetObject)
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de récupérer les données de la commande "
"""
Recuperation des lignes d'une facture à partir de l'invoice_header_id, sans entete
"""
def Get_Given_Partner_Invoice_Lines(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'invoice_header_id']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ")
return False, " Les informations fournies sont incorrectes",
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', 'invoice_header_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 la liste des arguments ")
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
"""
Clés de mise à jour
"""
data_cle = {}
data_cle['partner_owner_recid'] = str(my_partner['recid'])
data_cle['invoice_header_id'] = str(diction['invoice_header_id'])
data_cle['valide'] = "1"
data_cle['locked'] = "0"
RetObject = []
val_tmp = 1
filt_class_partner_recid = {'partner_owner_recid': str(my_partner['recid'])}
filt_invoice_header_id = {'invoice_header_id': str(diction['invoice_header_id'])}
query = [{'$match': {'$and': [ filt_invoice_header_id,
{'partner_owner_recid': str(my_partner['recid'])}]}},
{'$lookup':
{
'from': 'myclass',
'localField': 'order_line_formation',
'foreignField': 'internal_url',
'pipeline': [{'$match': {'$and': [ filt_class_partner_recid]}},
{'$project': {'title': 1, 'domaine': 1, '_id':1,
'duration': 1,
'duration_unit': 1,'external_code':1}}],
'as': 'myclass_collection'
}
}
]
print("#### Get_Given_Partner_Invoice_Lines : query pip= ", query)
for retval in MYSY_GV.dbname['partner_invoice_line'].aggregate(query):
if ('myclass_collection' in retval.keys() and len(retval['myclass_collection']) > 0):
#print(" ### retval = ", retval)
user = {}
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
user['_id'] = retval['_id']
user['order_line_formation'] = retval['order_line_formation']
user['order_line_qty'] = retval['order_line_qty']
user['order_line_prix_unitaire'] = retval['order_line_prix_unitaire']
user['invoice_header_id'] = retval['invoice_header_id']
user['invoice_header_ref_interne'] = retval['invoice_header_ref_interne']
user['invoice_date'] = retval['invoice_date']
user['valide'] = retval['valide']
user['locked'] = retval['locked']
order_line_session_code = ""
order_line_session_id = ""
if( "order_line_session_id" in retval.keys() and retval['order_line_session_id']):
order_line_session_id = retval['order_line_session_id']
local_session_data = MYSY_GV.dbname['session_formation'].find_one({'_id':ObjectId(str(retval['order_line_session_id'])),
'partner_owner_recid': str(my_partner['recid'])}, {'_id':1, 'code_session':1})
if( local_session_data and "code_session" in local_session_data.keys()):
order_line_session_code = local_session_data['code_session']
user['order_line_session_code'] = order_line_session_code
user['order_line_session_id'] = order_line_session_id
if ("order_line_montant_reduction" in retval.keys()):
user['order_line_montant_reduction'] = retval['order_line_montant_reduction']
else:
user['order_line_montant_reduction'] = "0"
if ("order_line_type_article" in retval.keys()):
user['order_line_type_article'] = retval['order_line_type_article']
else:
user['order_line_type_article'] = ""
if ("order_line_type_apprenant" in retval.keys()):
user['order_line_type_apprenant'] = retval['order_line_type_apprenant']
else:
user['order_line_type_apprenant'] = ""
if ("order_line_montant_toutes_taxes" in retval.keys()):
user['order_line_montant_toutes_taxes'] = retval['order_line_montant_toutes_taxes']
else:
user['order_line_montant_toutes_taxes'] = "0"
if ("order_line_tax" in retval.keys()):
user['order_line_tax'] = retval['order_line_tax']
else:
user['order_line_tax'] = ""
if ("order_line_tax_amount" in retval.keys()):
user['order_line_tax_amount'] = retval['order_line_tax_amount']
else:
user['order_line_tax_amount'] = "0"
if ("order_line_type_reduction" in retval.keys()):
user['order_line_type_reduction'] = retval['order_line_type_reduction']
else:
user['order_line_montant_reduction'] = ""
if ("order_line_type_valeur" in retval.keys()):
user['order_line_type_valeur'] = retval['order_line_type_valeur']
else:
user['order_line_type_valeur'] = "0"
if ("order_line_montant_hors_taxes" in retval.keys()):
user['order_line_montant_hors_taxes'] = retval['order_line_montant_hors_taxes']
else:
user['order_line_montant_hors_taxes'] = "0"
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['update_by'] = str(my_partner['_id'])
user['partner_owner_recid'] = retval['partner_owner_recid']
user['invoice_line_type'] = retval['invoice_line_type']
if( "order_line_comment" in retval.keys()):
user['order_line_comment'] = retval['order_line_comment']
else:
user['order_line_comment'] = ""
user['title'] = retval['myclass_collection'][0]['title']
user['order_line_formation_external_code'] = retval['myclass_collection'][0]['external_code']
if( "domaine" in retval['myclass_collection'][0].keys() ):
user['domaine'] = retval['myclass_collection'][0]['domaine']
else:
user['domaine'] = ""
user['duration'] = retval['myclass_collection'][0]['duration']
user['duration_unit'] = retval['myclass_collection'][0]['duration_unit']
if (str(retval['myclass_collection'][0]['duration_unit']) == "heure"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " h"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "jour"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " j"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "semaine"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " s"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "mois"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " m"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "annee"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " a"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "user_rythme"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " u"
else:
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " ?"
"""
Il s'agit d'un formation, vu qu'on a un lien avec la collection "myclass", on force alors le 'order_line_type_article'
a 'formation'
"""
user['order_line_type_article'] = "formation"
"""
19/10/2025 - aller recuperer les données des inscrits en faisant un lien entre partner_invoice_line['tab_inscription_ids']
et partner_invoice_line_detail['order_line_inscription_id']
"""
tab_inscription = []
if( "tab_inscription_ids" in retval.keys()):
for inscription_id in retval['tab_inscription_ids']:
if (inscription_id):
invoice_inscription_id_data = MYSY_GV.dbname['partner_invoice_line_detail'].find_one(
{'order_line_inscription_id': str(inscription_id),
'valide': '1', 'locked': '0',
'partner_owner_recid': str(retval['partner_owner_recid']),
'invoice_header_ref_interne': str(retval['invoice_header_ref_interne'])
},
{'order_line_inscription_type_apprenant': 1,
'order_line_inscription_comment': 1,
'order_line_inscription_memo': 1,
'order_line_inscription_price': 1,
'order_line_inscription_modefinancement': 1,
'order_line_inscription_nom': 1,
'order_line_inscription_prenom': 1,
'order_line_inscription_email': 1,
'order_line_inscription_civilite': 1,
'tab_inscription_ids': 1,
})
tab_inscription.append(invoice_inscription_id_data)
user['inscription_data'] = tab_inscription
RetObject.append(mycommon.JSONEncoder().encode(user))
"""
Recuperation des produits et services
"""
query = [{'$match': {'$and': [ filt_invoice_header_id,
{'partner_owner_recid': str(my_partner['recid'])}]}},
{'$lookup': {
'from': 'partner_produit_service',
"let": {'order_line_formation': "$order_line_formation",
"partner_produit_service_partner_owner_recid": "$partner_owner_recid"
},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$valide", "1"]},
{'$eq': ["$_id", {'$convert': {
'input': "$$order_line_formation",
'to': "objectId",
'onError': {'error': 'true'},
'onNull': {'isnull': 'true'}
}}]},
{'$eq': ["$partner_owner_recid",
'$$partner_produit_service_partner_owner_recid']},
]
}
}
},
],
'as': 'collection_partner_produit_service'
}
},
]
#print("#### Get_Given_Partner_Invoice_Lines for PRODUCT & SERVICES : query pip= ", query)
for retval in MYSY_GV.dbname['partner_invoice_line'].aggregate(query):
if ('collection_partner_produit_service' in retval.keys() and len(retval['collection_partner_produit_service']) > 0):
user = {}
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
user['_id'] = retval['_id']
user['order_line_formation'] = retval['order_line_formation']
user['order_line_qty'] = retval['order_line_qty']
user['order_line_prix_unitaire'] = retval['order_line_prix_unitaire']
user['invoice_header_id'] = retval['invoice_header_id']
user['invoice_header_ref_interne'] = retval['invoice_header_ref_interne']
user['invoice_date'] = retval['invoice_date']
user['valide'] = retval['valide']
user['locked'] = retval['locked']
order_line_session_code = ""
order_line_session_id = ""
if ("order_line_session_id" in retval.keys() and retval['order_line_session_id']):
order_line_session_id = retval['order_line_session_id']
local_session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(retval['order_line_session_id'])),
'partner_owner_recid': str(my_partner['recid'])}, {'_id': 1, 'code_session': 1})
if (local_session_data and "code_session" in local_session_data.keys()):
order_line_session_code = local_session_data['code_session']
user['order_line_session_code'] = order_line_session_code
user['order_line_session_id'] = order_line_session_id
if ("order_line_montant_reduction" in retval.keys()):
user['order_line_montant_reduction'] = retval['order_line_montant_reduction']
else:
user['order_line_montant_reduction'] = "0"
if ("order_line_type_apprenant" in retval.keys()):
user['order_line_type_apprenant'] = retval['order_line_type_apprenant']
else:
user['order_line_type_apprenant'] = ""
if ("order_line_montant_toutes_taxes" in retval.keys()):
user['order_line_montant_toutes_taxes'] = retval['order_line_montant_toutes_taxes']
else:
user['order_line_montant_toutes_taxes'] = "0"
if ("order_line_tax" in retval.keys()):
user['order_line_tax'] = retval['order_line_tax']
else:
user['order_line_tax'] = ""
if ("order_line_tax_amount" in retval.keys()):
user['order_line_tax_amount'] = retval['order_line_tax_amount']
else:
user['order_line_tax_amount'] = "0"
if ("order_line_type_reduction" in retval.keys()):
user['order_line_type_reduction'] = retval['order_line_type_reduction']
else:
user['order_line_montant_reduction'] = ""
if ("order_line_type_valeur" in retval.keys()):
user['order_line_type_valeur'] = retval['order_line_type_valeur']
else:
user['order_line_type_valeur'] = "0"
if ("order_line_montant_hors_taxes" in retval.keys()):
user['order_line_montant_hors_taxes'] = retval['order_line_montant_hors_taxes']
else:
user['order_line_montant_hors_taxes'] = "0"
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['update_by'] = str(my_partner['_id'])
user['partner_owner_recid'] = retval['partner_owner_recid']
user['invoice_line_type'] = retval['invoice_line_type']
if ("order_line_comment" in retval.keys()):
user['order_line_comment'] = retval['order_line_comment']
else:
user['order_line_comment'] = ""
user['title'] = retval['collection_partner_produit_service'][0]['nom']
user['order_line_formation_external_code'] = retval['collection_partner_produit_service'][0]['code']
user['domaine'] = ""
user['duration'] = ""
user['duration_unit'] = ""
user['duration_concat'] = ""
"""
Il s'agit d'un produit, vu qu'on a un lien avec la collection "partner_produit_service", on force alors le 'order_line_type_article'
a 'produit'
"""
user['order_line_type_article'] = "produit"
RetObject.append(mycommon.JSONEncoder().encode(user))
#print(" ### Get_Given_Partner_Invoice_Lines for PRODUCT & SERVICES : RetObject = ", RetObject)
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de récupérer les lignes de la facture "
"""
Recuperation des lignes d'une commande à partir de l' invoice_header_ref_interne, sans entete
"""
def Get_Given_Partner_Invoice_Lines_From_Invoice_ref_interne(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'invoice_header_ref_interne']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ")
return False, " Les informations fournies sont incorrectes",
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', 'invoice_header_ref_interne']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
return False, " 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
"""
Clés de mise à jour
"""
data_cle = {}
data_cle['partner_owner_recid'] = str(my_partner['recid'])
data_cle['invoice_header_ref_interne'] = str(diction['invoice_header_ref_interne'])
data_cle['valide'] = "1"
data_cle['locked'] = "0"
RetObject = []
val_tmp = 1
filt_class_partner_recid = {'partner_owner_recid': str(my_partner['recid'])}
filt_invoice_header_id = {'invoice_header_id': str(diction['order_header_id'])}
query = [{'$match': {'$and': [filt_invoice_header_id,
{'partner_owner_recid': str(my_partner['recid'])}]}},
{'$lookup':
{
'from': 'myclass',
'localField': 'order_line_formation',
'foreignField': 'internal_url',
'pipeline': [{'$match': {'$and': [filt_class_partner_recid]}},
{'$project': {'title': 1, 'domaine': 1,
'duration': 1,
'duration_unit': 1, 'external_code': 1}}],
'as': 'myclass_collection'
}
}
]
print("#### Get_Given_Partner_Invoice_Lines : query pip= ", query)
for retval in MYSY_GV.dbname['partner_invoice_line'].aggregate(query):
if ('myclass_collection' in retval.keys() and len(retval['myclass_collection']) > 0):
user = {}
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
user['_id'] = retval['_id']
user['order_line_formation'] = retval['order_line_formation']
user['order_line_qty'] = retval['order_line_qty']
user['order_line_prix_unitaire'] = retval['order_line_prix_unitaire']
user['invoice_header_id'] = retval['invoice_header_id']
user['invoice_header_ref_interne'] = retval['invoice_header_ref_interne']
user['invoice_date'] = retval['invoice_date']
user['valide'] = retval['valide']
user['locked'] = retval['locked']
order_line_session_code = ""
order_line_session_id = ""
if ("order_line_session_id" in retval.keys() and retval['order_line_session_id']):
order_line_session_id = retval['order_line_session_id']
local_session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(retval['order_line_session_id'])),
'partner_owner_recid': str(my_partner['recid'])}, {'_id': 1, 'code_session': 1})
if (local_session_data and "code_session" in local_session_data.keys()):
order_line_session_code = local_session_data['code_session']
user['order_line_session_code'] = order_line_session_code
user['order_line_session_id'] = order_line_session_id
if ("order_line_montant_reduction" in retval.keys()):
user['order_line_montant_reduction'] = retval['order_line_montant_reduction']
else:
user['order_line_montant_reduction'] = "0"
if ("order_line_type_article" in retval.keys()):
user['order_line_type_article'] = retval['order_line_type_article']
else:
user['order_line_type_article'] = ""
if ("order_line_type_apprenant" in retval.keys()):
user['order_line_type_apprenant'] = retval['order_line_type_apprenant']
else:
user['order_line_type_apprenant'] = ""
if ("order_line_montant_toutes_taxes" in retval.keys()):
user['order_line_montant_toutes_taxes'] = retval['order_line_montant_toutes_taxes']
else:
user['order_line_montant_toutes_taxes'] = "0"
if ("order_line_tax" in retval.keys()):
user['order_line_tax'] = retval['order_line_tax']
else:
user['order_line_tax'] = ""
if ("order_line_tax_amount" in retval.keys()):
user['order_line_tax_amount'] = retval['order_line_tax_amount']
else:
user['order_line_tax_amount'] = "0"
if ("order_line_type_reduction" in retval.keys()):
user['order_line_type_reduction'] = retval['order_line_type_reduction']
else:
user['order_line_montant_reduction'] = ""
if ("order_line_type_valeur" in retval.keys()):
user['order_line_type_valeur'] = retval['order_line_type_valeur']
else:
user['order_line_type_valeur'] = "0"
if ("order_line_montant_hors_taxes" in retval.keys()):
user['order_line_montant_hors_taxes'] = retval['order_line_montant_hors_taxes']
else:
user['order_line_montant_hors_taxes'] = "0"
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['update_by'] = str(my_partner['_id'])
user['partner_owner_recid'] = retval['partner_owner_recid']
user['invoice_line_type'] = retval['invoice_line_type']
if ("order_line_comment" in retval.keys()):
user['order_line_comment'] = retval['order_line_comment']
else:
user['order_line_comment'] = ""
user['title'] = retval['myclass_collection'][0]['title']
user['order_line_formation_external_code'] = retval['myclass_collection'][0]['external_code']
if ("domaine" in retval['myclass_collection'][0].keys()):
user['domaine'] = retval['myclass_collection'][0]['domaine']
else:
user['domaine'] = ""
user['duration'] = retval['myclass_collection'][0]['duration']
user['duration_unit'] = retval['myclass_collection'][0]['duration_unit']
if (str(retval['myclass_collection'][0]['duration_unit']) == "heure"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " h"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "jour"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " j"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "semaine"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " s"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "mois"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " m"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "annee"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " a"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "user_rythme"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " u"
else:
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " ?"
"""
Il s'agit d'un formation, vu qu'on a un lien avec la collection "myclass", on force alors le 'order_line_type_article'
a 'formation'
"""
user['order_line_type_article'] = "formation"
"""
19/10/2025 - aller recuperer les données des inscrits en faisant un lien entre partner_invoice_line['tab_inscription_ids']
et partner_invoice_line_detail['order_line_inscription_id']
"""
tab_inscription = []
for inscription_id in retval['tab_inscription_ids']:
if (inscription_id):
invoice_inscription_id_data = MYSY_GV.dbname['partner_invoice_line_detail'].find_one(
{'order_line_inscription_id': str(inscription_id),
'valide': '1', 'locked': '0',
'partner_owner_recid': str(retval['partner_owner_recid']),
'invoice_header_ref_interne': str(retval['invoice_header_ref_interne'])
},
{'order_line_inscription_type_apprenant': 1,
'order_line_inscription_comment': 1,
'order_line_inscription_memo': 1,
'order_line_inscription_price': 1,
'order_line_inscription_modefinancement': 1,
'order_line_inscription_nom': 1,
'order_line_inscription_prenom': 1,
'order_line_inscription_email': 1,
'order_line_inscription_civilite': 1,
'tab_inscription_ids': 1,
})
tab_inscription.append(invoice_inscription_id_data)
user['inscription_data'] = tab_inscription
RetObject.append(mycommon.JSONEncoder().encode(user))
"""
Recuperation des produits et services
"""
query = [{'$match': {'$and': [filt_invoice_header_id,
{'partner_owner_recid': str(my_partner['recid'])}]}},
{'$lookup': {
'from': 'partner_produit_service',
"let": {'order_line_formation': "$order_line_formation",
"partner_produit_service_partner_owner_recid": "$partner_owner_recid"
},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$valide", "1"]},
{'$eq': ["$_id", {'$convert': {
'input': "$$order_line_formation",
'to': "objectId",
'onError': {'error': 'true'},
'onNull': {'isnull': 'true'}
}}]},
{'$eq': ["$partner_owner_recid",
'$$partner_produit_service_partner_owner_recid']},
]
}
}
},
],
'as': 'collection_partner_produit_service'
}
},
]
#print("#### Get_Given_Partner_Invoice_Lines for PRODUCT & SERVICES : query pip= ", query)
for retval in MYSY_GV.dbname['partner_invoice_line'].aggregate(query):
if ('collection_partner_produit_service' in retval.keys() and len(retval['collection_partner_produit_service']) > 0):
user = {}
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
user['_id'] = retval['_id']
user['order_line_formation'] = retval['order_line_formation']
user['order_line_qty'] = retval['order_line_qty']
user['order_line_prix_unitaire'] = retval['order_line_prix_unitaire']
user['invoice_header_id'] = retval['invoice_header_id']
user['invoice_header_ref_interne'] = retval['invoice_header_ref_interne']
user['invoice_date'] = retval['invoice_date']
user['valide'] = retval['valide']
user['locked'] = retval['locked']
order_line_session_code = ""
order_line_session_id = ""
if ("order_line_session_id" in retval.keys() and retval['order_line_session_id']):
order_line_session_id = retval['order_line_session_id']
local_session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(retval['order_line_session_id'])),
'partner_owner_recid': str(my_partner['recid'])}, {'_id': 1, 'code_session': 1})
if (local_session_data and "code_session" in local_session_data.keys()):
order_line_session_code = local_session_data['code_session']
user['order_line_session_code'] = order_line_session_code
user['order_line_session_id'] = order_line_session_id
if ("order_line_montant_reduction" in retval.keys()):
user['order_line_montant_reduction'] = retval['order_line_montant_reduction']
else:
user['order_line_montant_reduction'] = "0"
if ("order_line_type_apprenant" in retval.keys()):
user['order_line_type_apprenant'] = retval['order_line_type_apprenant']
else:
user['order_line_type_apprenant'] = ""
if ("order_line_montant_toutes_taxes" in retval.keys()):
user['order_line_montant_toutes_taxes'] = retval['order_line_montant_toutes_taxes']
else:
user['order_line_montant_toutes_taxes'] = "0"
if ("order_line_tax" in retval.keys()):
user['order_line_tax'] = retval['order_line_tax']
else:
user['order_line_tax'] = ""
if ("order_line_tax_amount" in retval.keys()):
user['order_line_tax_amount'] = retval['order_line_tax_amount']
else:
user['order_line_tax_amount'] = "0"
if ("order_line_type_reduction" in retval.keys()):
user['order_line_type_reduction'] = retval['order_line_type_reduction']
else:
user['order_line_montant_reduction'] = ""
if ("order_line_type_valeur" in retval.keys()):
user['order_line_type_valeur'] = retval['order_line_type_valeur']
else:
user['order_line_type_valeur'] = "0"
if ("order_line_montant_hors_taxes" in retval.keys()):
user['order_line_montant_hors_taxes'] = retval['order_line_montant_hors_taxes']
else:
user['order_line_montant_hors_taxes'] = "0"
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['update_by'] = str(my_partner['_id'])
user['partner_owner_recid'] = retval['partner_owner_recid']
user['invoice_line_type'] = retval['invoice_line_type']
if ("order_line_comment" in retval.keys()):
user['order_line_comment'] = retval['order_line_comment']
else:
user['order_line_comment'] = ""
user['title'] = retval['collection_partner_produit_service'][0]['nom']
user['order_line_formation_external_code'] = retval['collection_partner_produit_service'][0]['code']
user['domaine'] = ""
user['duration'] = ""
user['duration_unit'] = ""
user['duration_concat'] = ""
"""
Il s'agit d'un produit, vu qu'on a un lien avec la collection "partner_produit_service", on force alors le 'order_line_type_article'
a 'produit'
"""
user['order_line_type_article'] = "produit"
RetObject.append(mycommon.JSONEncoder().encode(user))
#print(" ### RetObject = ", RetObject)
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de récupérer les lignes de commande "
"""
Recuperation de la liste des factures d'un partner
"""
def Get_List_Partner_Invoice_no_filter(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', ]
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ")
return False, " Les informations fournies sont incorrectes",
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
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
find_qry = {'$and': [{'partner_owner_recid': str(my_partner['recid']), 'valide': '1', 'locked': '0'}, {}, ]}
new_myquery_find_invoice = [{'$match': find_qry},
{ '$sort': {'_id': -1}},
{"$addFields": {"partner_invoice_header_Id": {"$toString": "$_id"}}},
{'$lookup':
{
'from': 'partner_order_line',
'localField': "partner_invoice_header_Id",
'foreignField': 'invoice_header_id',
'pipeline': [{'$match': {'$and': [{}, {
'partner_owner_recid': str(my_partner['recid'])}, {'valide': '1'}]}}, ],
'as': 'partner_invoice_line_collection'
}
}
]
#print(" ### orders new_myquery_find_invoice = ", new_myquery_find_invoice)
RetObject = []
val_tmp = 0
somme_header_ca_ht = 0
nb_header_invoice = 0
for New_retVal in MYSY_GV.dbname['partner_invoice_header'].aggregate(new_myquery_find_invoice):
user = New_retVal
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
"""
recuperer le CA globale et le nombre de factures
"""
if ("total_header_hors_taxe_before_header_reduction" in New_retVal.keys()):
somme_header_ca_ht = somme_header_ca_ht + mycommon.tryFloat( str(New_retVal['total_header_hors_taxe_before_header_reduction']))
nb_header_invoice = nb_header_invoice + 1
# Convertir la date facture en jj/mm/aaaa
if( 'invoice_date' in New_retVal.keys()):
date_jjmmaaa = str(New_retVal['invoice_date'])[0:10]
#print(" ### date_jjmmaaa = ", date_jjmmaaa)
#date_jjmmaaa = datetime.strptime(date_jjmmaaa, '%d/%m/%Y')
#New_retVal['invoice_date'] = str(date_jjmmaaa)
# Si le champ 'order_header_condition_paiement_id' alors on va chercher le code de la condition de paiement
paiement_ction_code = ""
if ('order_header_condition_paiement_id' in New_retVal.keys() and New_retVal[
'order_header_condition_paiement_id']):
paiement_ction_data = MYSY_GV.dbname['base_partner_paiement_condition'].find_one(
{'_id': ObjectId(str(New_retVal['order_header_condition_paiement_id'])), 'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (paiement_ction_data and 'code' in paiement_ction_data.keys()):
paiement_ction_code = str(paiement_ction_data['code'])
user['order_header_paiement_condition_code'] = paiement_ction_code
# Si le champ 'order_header_client_id' alors on va chercher le nom du client
if( 'order_header_client_id' in New_retVal.keys()):
Client_data = MYSY_GV.dbname['partner_client'].find_one({'_id':ObjectId(str(New_retVal['order_header_client_id'])), 'valide':'1', 'locked':'0',
'partner_owner_recid':str(my_partner['recid'])})
if( Client_data and 'nom' in Client_data.keys() ):
user['order_header_client_nom'] = str(Client_data['nom'])
# Si le champ 'order_header_vendeur_id' alors on va chercher le nom et prenom du vendeur (employe)
if ('order_header_vendeur_id' in New_retVal.keys() and New_retVal['order_header_vendeur_id']):
Employee_data = MYSY_GV.dbname['ressource_humaine'].find_one(
{'_id': ObjectId(str(New_retVal['order_header_vendeur_id'])), 'valide': '1', 'locked': '0',
'partner_recid': str(my_partner['recid'])})
order_header_vendeur_nom_prenom = ""
if (Employee_data and 'nom' in Employee_data.keys()):
order_header_vendeur_nom_prenom = str(Employee_data['nom'])
if (Employee_data and 'prenom' in Employee_data.keys()):
order_header_vendeur_nom_prenom = str(order_header_vendeur_nom_prenom)+" "+str(Employee_data['prenom'])
user['order_header_vendeur_nom_prenom'] = str(order_header_vendeur_nom_prenom)
'''
"""
Recuperer le solde (montant restant à payer)
"""
local_diction = {'token':str(diction['token']), 'invoice_id':str(New_retVal['_id'])}
reste_to_paye = "0"
local_solde_status, local_solde_retval = invoice_paiement_mgt.Get_Invoice_Total_Amount_Payed_And_Remaining_Amount(local_diction)
if( local_solde_status ):
sold_data = ast.literal_eval(local_solde_retval[0])
reste_to_paye = sold_data['remaining_amount']
user['reste_to_paye'] = reste_to_paye
'''
if( "credit_note_ref" not in New_retVal.keys() ):
user['credit_note_ref'] = ""
if ("invoice_header_origin" not in New_retVal.keys()):
user['invoice_header_origin'] = ""
if ("reste_to_paye" not in New_retVal.keys()):
user['reste_to_paye'] = str(user['total_header_toutes_taxes'])
RetObject.append(mycommon.JSONEncoder().encode(user))
total_data = []
node = {}
node['somme_header_ca_ht'] = str(somme_header_ca_ht)
node['nb_header_invoice'] = str(nb_header_invoice)
total_data.append(node)
total_data = mycommon.JSONEncoder().encode(total_data)
#print(" ### RetObject = ", RetObject)
return True, RetObject, total_data
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 "
"""
Recuperation de la liste des factures avec des filtres.
les filtres acceptés sont :
- ref_interne_cmd (commande)
- ref_interne_invoice
- ref_externe
- invoice_date entre date_debut et date_fin
- nom_client
- session_id (aller chercher à ligne de facture)
- date échéance (invoice_date_echeance)
"""
def Get_List_Partner_Invoice_with_filter(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés. les filtres accepté sont :
- ref_interne,
"""
field_list = ['token', 'date_facture_debut', 'date_facture_fin', 'client_nom', 'ref_interne_cmd',
'ref_interne_invoice', 'ref_externe', 'formation', 'order_header_client_id',
'session_code', 'solde', 'solde_operateur', 'date_echeance', 'echeance_operateur',
'montant_ttc', 'montant_ttc_operateur']
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", False
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
return False, " Les informations fournies sont incorrectes", False
"""
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, False
filt_client_nom = {}
sub_filt_client_nom = {}
Lists_partner_client_id = []
if ("client_nom" in diction.keys() and diction['client_nom']):
sub_filt_client_nom = {'nom': {'$regex': mycommon.regex_replace_cartere(str(diction['client_nom'])), "$options": "i"}, 'partner_owner_recid':str(my_partner['recid']), 'valide':'1', 'locked':'0'}
# Recuperation des '_id' des clients dont le nom match en regexp
#print(" ### sub_filt_client_nom = ", sub_filt_client_nom)
for List_Client_Data in MYSY_GV.dbname['partner_client'].find(sub_filt_client_nom, {'_id':1}):
Lists_partner_client_id.append(str(List_Client_Data['_id']))
filt_client_nom = {'order_header_client_id': {'$in': Lists_partner_client_id, }}
#print(' ### filt_client_nom = ', filt_client_nom)
filt_formation_external_code = {}
sub_filt_formation_external_code = {}
Lists_partner_formation_internal_url = []
if ("formation" in diction.keys() and diction['formation']):
sub_filt_formation_external_code = {'external_code': {'$regex': str(diction['formation']), "$options": "i"},
'partner_owner_recid': str(my_partner['recid']), 'valide': '1', 'locked': '0'}
# Recuperation des '_id' des formation dont le nom match en regexp
#print(" ### sub_filt_formation_external_code = ", sub_filt_formation_external_code)
for Lists_partner_formation_Data in MYSY_GV.dbname['myclass'].find(sub_filt_formation_external_code, {'internal_url': 1}):
Lists_partner_formation_internal_url.append(str(Lists_partner_formation_Data['internal_url']))
filt_formation_external_code = {'order_line_formation': {'$in': Lists_partner_formation_internal_url }}
filt_session_code = {}
sub_filt_session_code = {}
Lists_session_id = []
if ("session_code" in diction.keys() and diction['session_code']):
sub_filt_session_code = {'code_session': {'$regex': mycommon.regex_replace_cartere(str(diction['session_code'])), "$options": "i"},
'partner_owner_recid': str(my_partner['recid']), 'valide': '1'}
# Recuperation des '_id' des formation dont le nom match en regexp
# print(" ### sub_filt_formation_external_code = ", sub_filt_formation_external_code)
for Lists_session_Data in MYSY_GV.dbname['session_formation'].find(sub_filt_session_code,
{'_id': 1}):
Lists_session_id.append(str(Lists_session_Data['_id']))
filt_session_code = {'order_line_session_id': {'$in': Lists_session_id}}
filt_date_echeance_ISODATE = ""
filt_date_echeance = ""
if ("date_echeance" in diction.keys() and diction['date_echeance']):
filt_date_echeance = str(diction['date_echeance'])[0:10]
local_status = mycommon.CheckisDate(filt_date_echeance)
if (local_status is False):
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le filtre : 'date d'échéance' n'est pas au format jj/mm/aaaa.")
return False, " Le filtre : 'date d'échéance' n'est pas au format jj/mm/aaaa."
filt_date_echeance_ISODATE = datetime.strptime(str(filt_date_echeance), '%d/%m/%Y')
filt_creation_date_from_ISODATE = ""
filt_creation_date_from = ""
if ("creation_date_from" in diction.keys() and diction['creation_date_from']):
filt_creation_date_from = str(diction['creation_date_from'])[0:10]
local_status = mycommon.CheckisDate(filt_creation_date_from)
if (local_status is False):
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le filtre : 'date création du' n'est pas au format jj/mm/aaaa.")
return False, " Le filtre : 'date création du' n'est pas au format jj/mm/aaaa."
filt_creation_date_from_ISODATE = datetime.strptime(str(filt_creation_date_from), '%d/%m/%Y')
filt_creation_date_to_ISODATE = ""
filt_creation_date_to = ""
if ("creation_date_to" in diction.keys() and diction['creation_date_to']):
filt_creation_date_to = str(diction['creation_date_to'])[0:10]
local_status = mycommon.CheckisDate(filt_creation_date_to)
if (local_status is False):
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le filtre : 'date création du' n'est pas au format jj/mm/aaaa.")
return False, " Le filtre : 'date création du' n'est pas au format jj/mm/aaaa."
filt_creation_date_to_ISODATE = datetime.strptime(str(filt_creation_date_to), '%d/%m/%Y')
mytoday = datetime.today().strftime("%d/%m/%Y")
mytoday_datetime = datetime.strptime(str(mytoday).strip(), '%d/%m/%Y')
filt_client_id = {}
if ("order_header_client_id" in diction.keys() and diction['order_header_client_id']):
filt_client_id = {'order_header_client_id': str(diction['order_header_client_id'])}
filt_ref_interne_cmd = {}
if ("ref_interne_cmd" in diction.keys() and diction['ref_interne_cmd'] ):
filt_ref_interne_cmd = {
'order_header_ref_interne': {'$regex': mycommon.regex_replace_cartere(str(diction['ref_interne_cmd'])), "$options": "i"}}
filt_ref_interne_invoice = {}
if ("ref_interne_invoice" in diction.keys() and diction['ref_interne_invoice']):
filt_ref_interne_cmd = {
'invoice_header_ref_interne': {'$regex': mycommon.regex_replace_cartere(str(diction['ref_interne_invoice'])), "$options": "i"}}
filt_ref_externe = {}
if ("ref_externe" in diction.keys() and diction['ref_externe']):
filt_ref_externe = {
'order_header_ref_client': {'$regex': mycommon.regex_replace_cartere(str(diction['ref_externe'])), "$options": "i"}}
filt_montant_ttc = {}
if ("montant_ttc" in diction.keys() and diction['montant_ttc'] and "montant_ttc_operateur" in diction.keys() and diction['montant_ttc_operateur']):
local_status, local_retval = mycommon.IsFloat(str(diction['montant_ttc']).strip())
if( local_status is False):
return False, " Le filtre montant TTC invalide ", False
filter_value_montant_ttc_float = local_retval
if (diction['montant_ttc_operateur'] == "egale"):
filt_montant_ttc = {'mysy_total_header_toutes_taxes': filter_value_montant_ttc_float}
elif (diction['montant_ttc_operateur'] == "inf_egale"):
filt_montant_ttc = {'mysy_total_header_toutes_taxes': {'$lte': filter_value_montant_ttc_float}}
elif (diction['montant_ttc_operateur'] == "sup_egale"):
filt_montant_ttc = {'mysy_total_header_toutes_taxes': {'$gte': filter_value_montant_ttc_float}}
find_qry = {'$and': [{'partner_owner_recid': str(my_partner['recid']), 'valide': '1', 'locked': '0'}, filt_client_nom, filt_ref_interne_cmd,
filt_ref_interne_invoice, filt_ref_externe, filt_client_id, filt_montant_ttc]}
new_myquery_find_order = [{"$addFields":
{
"partner_invoice_header_Id": {"$toString": "$_id"},
"mysy_total_header_toutes_taxes": {"$convert": {
'input': "$total_header_toutes_taxes",
'to': "double",
'onError': {'error': 0},
'onNull': {'isnull': 0}
}
}
},
},
{'$match': find_qry},
{'$lookup':
{
'from': 'partner_invoice_line',
'localField': "partner_invoice_header_Id",
'foreignField': 'invoice_header_id',
'pipeline': [{'$match': {'$and': [filt_formation_external_code, filt_session_code, {
'partner_owner_recid': str(my_partner['recid'])}, {'valide': '1'}]}}, ],
'as': 'partner_invoice_line_collection'
}
},
{
'$sort': {'_id':-1, }
},
]
if(filt_date_echeance_ISODATE ):
sub_qry_echeance_operator = {}
if( diction['echeance_operateur'] == "egale"):
sub_qry_echeance_operator = { 'mysy_invoice_du_date': filt_date_echeance_ISODATE }
elif (diction['echeance_operateur'] == "inf_egale"):
sub_qry_echeance_operator = {'mysy_invoice_du_date': { '$lte': filt_date_echeance_ISODATE}}
elif (diction['echeance_operateur'] == "sup_egale"):
sub_qry_echeance_operator = {'mysy_invoice_du_date': {'$gte': filt_date_echeance_ISODATE}}
find_qry = {'$and': [{'partner_owner_recid': str(my_partner['recid']), 'valide': '1', 'locked': '0', },
sub_qry_echeance_operator,
filt_client_nom, filt_ref_interne_cmd, filt_ref_interne_invoice, filt_ref_externe,
filt_client_id]}
new_myquery_find_order = [
{"$addFields":
{
"partner_invoice_header_Id": {"$toString": "$_id"},
"mysy_invoice_du_date": {
'$dateFromString': {
'dateString': '$invoice_date_echeance',
'format': "%d/%m/%Y"
}
},
"mysy_invoice_date": {
'$dateFromString': {
'dateString': {"$substr": ["$invoice_date", 0, 10]},
'format': "%d/%m/%Y"
}
}
},
},
{'$match': find_qry},
{'$lookup':
{
'from': 'partner_invoice_line',
'localField': "partner_invoice_header_Id",
'foreignField': 'invoice_header_id',
'pipeline': [{'$match': {
'$and': [filt_formation_external_code, filt_session_code, {
'partner_owner_recid': str(my_partner['recid'])},
{'valide': '1'}]}}, ],
'as': 'partner_invoice_line_collection'
}
},
{
'$sort': {'_id': -1, }
},
]
print(" ### Get_List_Partner_Order_with_filter orders new_myquery_find_order = ", new_myquery_find_order)
RetObject = []
val_tmp = 0
filter_date_debut = ""
if ("date_facture_debut" in diction.keys()):
if diction['date_facture_debut']:
filter_date_debut = str(diction['date_facture_debut'])[0:10]
local_status = mycommon.CheckisDate(filter_date_debut)
if (local_status is False):
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'", False
filter_date_fin = ""
if ("date_facture_fin" in diction.keys()):
if diction['date_facture_fin']:
filter_date_fin = str(diction['date_facture_fin'])[0:10]
local_status = mycommon.CheckisDate(filter_date_fin)
if (local_status is False):
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'", False
somme_header_ca_ht = 0
nb_header_invoice = 0
for New_retVal in MYSY_GV.dbname['partner_invoice_header'].aggregate(new_myquery_find_order):
"""
recuperer le CA globale et le nombre de factures
"""
if("total_header_hors_taxe_before_header_reduction" in New_retVal.keys() ):
somme_header_ca_ht = somme_header_ca_ht + mycommon.tryFloat(str(New_retVal['total_header_hors_taxe_before_header_reduction']))
nb_header_invoice = nb_header_invoice + 1
if ('partner_invoice_line_collection' in New_retVal.keys() and len( New_retVal['partner_invoice_line_collection']) > 0):
user = New_retVal
# Si le champ 'order_header_condition_paiement_id' alors on va chercher le code de la condition de paiement
paiement_ction_code = ""
if ('order_header_condition_paiement_id' in New_retVal.keys() and New_retVal[
'order_header_condition_paiement_id']):
paiement_ction_data = MYSY_GV.dbname['base_partner_paiement_condition'].find_one(
{'_id': ObjectId(str(New_retVal['order_header_condition_paiement_id'])), 'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (paiement_ction_data and 'code' in paiement_ction_data.keys()):
paiement_ction_code = str(paiement_ction_data['code'])
user['order_header_paiement_condition_code'] = paiement_ction_code
# Si le champ 'order_header_client_id' alors on va chercher le nom du client
if ('order_header_client_id' in New_retVal.keys()):
Client_data = MYSY_GV.dbname['partner_client'].find_one(
{'_id': ObjectId(str(New_retVal['order_header_client_id'])), 'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (Client_data and 'nom' in Client_data.keys()):
user['order_header_client_nom'] = str(Client_data['nom'])
# Si le champ 'order_header_vendeur_id' alors on va chercher le nom et prenom du vendeur (employe)
if ('order_header_vendeur_id' in New_retVal.keys() and New_retVal['order_header_vendeur_id'] ):
Employee_data = MYSY_GV.dbname['ressource_humaine'].find_one(
{'_id': ObjectId(str(New_retVal['order_header_vendeur_id'])), 'valide': '1', 'locked': '0',
'partner_recid': str(my_partner['recid'])})
order_header_vendeur_nom_prenom = ""
if (Employee_data and 'nom' in Employee_data.keys()):
order_header_vendeur_nom_prenom = str(Employee_data['nom'])
if (Employee_data and 'prenom' in Employee_data.keys()):
order_header_vendeur_nom_prenom = str(order_header_vendeur_nom_prenom) + " " + str(
Employee_data['prenom'])
user['order_header_vendeur_nom_prenom'] = str(order_header_vendeur_nom_prenom)
"""
Recuperer le solde (montant restant à payer)
"""
local_diction = {'token': str(diction['token']), 'invoice_id': str(New_retVal['_id'])}
reste_to_paye = "0"
local_solde_status, local_solde_retval = invoice_paiement_mgt.Get_Invoice_Total_Amount_Payed_And_Remaining_Amount(
local_diction)
if (local_solde_status):
sold_data = ast.literal_eval(local_solde_retval[0])
reste_to_paye = sold_data['remaining_amount']
user['reste_to_paye'] = reste_to_paye
if ("credit_note_ref" not in New_retVal.keys()):
user['credit_note_ref'] = ""
if ("invoice_header_origin" not in New_retVal.keys()):
user['invoice_header_origin'] = ""
if( filter_date_debut and filter_date_fin ):
if ( datetime.strptime(str(New_retVal['invoice_date'])[0:10], '%d/%m/%Y') >= datetime.strptime(str(filter_date_debut)[0:10], '%d/%m/%Y') and
datetime.strptime(str(New_retVal['invoice_date'])[0:10], '%d/%m/%Y') <= datetime.strptime(str(filter_date_fin)[0:10], '%d/%m/%Y') ):
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
RetObject.append(mycommon.JSONEncoder().encode(user))
elif ( filter_date_debut ):
if ( datetime.strptime(str(New_retVal['invoice_date'])[0:10], '%d/%m/%Y') >= datetime.strptime(str(filter_date_debut)[0:10], '%d/%m/%Y') ):
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
RetObject.append(mycommon.JSONEncoder().encode(user))
elif ( filter_date_fin ):
if ( datetime.strptime(str(New_retVal['invoice_date'])[0:10], '%d/%m/%Y') <= datetime.strptime(str(filter_date_fin)[0:10], '%d/%m/%Y') ):
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
RetObject.append(mycommon.JSONEncoder().encode(user))
else:
if ("solde" in diction.keys() and diction['solde'] and "solde_operateur" in diction.keys() and diction['solde_operateur']):
if( diction['solde_operateur'] == "egale"):
if( tryFloat(diction['solde']) == tryFloat(reste_to_paye)):
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
RetObject.append(mycommon.JSONEncoder().encode(user))
elif( diction['solde_operateur'] == "inf_egale"):
if ( tryFloat(reste_to_paye) <= tryFloat(diction['solde'])):
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
RetObject.append(mycommon.JSONEncoder().encode(user))
elif (diction['solde_operateur'] == "sup_egale"):
if ( tryFloat(reste_to_paye) >= tryFloat(diction['solde']) ):
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
RetObject.append(mycommon.JSONEncoder().encode(user))
else:
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
RetObject.append(mycommon.JSONEncoder().encode(user))
total_data = []
node = {}
node['somme_header_ca_ht'] = str(somme_header_ca_ht)
node['nb_header_invoice'] = str(nb_header_invoice)
total_data.append(node)
total_data = mycommon.JSONEncoder().encode(total_data)
#print(" #### nb_result = ", val_tmp)
return True, RetObject, total_data
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 ", False
"""
Cette fonction permet de récupérer une ligne de detail d'une facture donnée
c'est a dire, une ligne de la collection 'partner_invoice_line'
"""
def Get_Given_Line_Of_Partner_Invoice_Lines(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'invoice_line_id', 'invoice_header_ref_interne']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé ")
return False, " Les informations fournies sont incorrectes",
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', 'invoice_line_id', 'invoice_header_ref_interne']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
return False, " 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
"""
Clés de mise à jour
"""
data_cle = {}
data_cle['partner_owner_recid'] = str(my_partner['recid'])
data_cle['invoice_line_id'] = str(diction['invoice_line_id'])
data_cle['invoice_header_ref_interne'] = str(diction['invoice_header_ref_interne'])
data_cle['valide'] = "1"
data_cle['locked'] = "0"
RetObject = []
val_tmp = 1
filt_class_partner_recid = {'partner_owner_recid': str(my_partner['recid'])}
filt_invoice_line_id = {'_id': ObjectId(str(diction['invoice_line_id']))}
filt_invoice_line_header_ref_interne = {'invoice_header_ref_interne': str(diction['invoice_header_ref_interne'])}
query = [{'$match': {'$and': [ filt_invoice_line_id, filt_invoice_line_header_ref_interne,
{'partner_owner_recid': str(my_partner['recid'])}]}},
{'$lookup':
{
'from': 'myclass',
'localField': 'order_line_formation',
'foreignField': 'internal_url',
'pipeline': [{'$match': {'$and': [ filt_class_partner_recid]}},
{'$project': {'title': 1, 'domaine': 1,
'duration': 1,
'duration_unit': 1,
'external_code':1}}],
'as': 'myclass_collection'
}
}
]
print("#### Get_Given_Partner_Invoice_Lines : query pip= ", query)
for retval in MYSY_GV.dbname['partner_invoice_line'].aggregate(query):
if ('myclass_collection' in retval.keys() and len(retval['myclass_collection']) > 0):
user = {}
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
user['_id'] = retval['_id']
user['order_line_formation'] = retval['order_line_formation']
user['order_line_qty'] = retval['order_line_qty']
user['order_line_prix_unitaire'] = retval['order_line_prix_unitaire']
user['order_header_id'] = retval['order_header_id']
user['order_header_ref_interne'] = retval['order_header_ref_interne']
user['invoice_header_ref_interne'] = retval['invoice_header_ref_interne']
user['invoice_line_type'] = retval['invoice_line_type']
user['invoice_date'] = retval['invoice_date']
user['invoice_header_id'] = retval['invoice_header_id']
order_line_session_code = ""
order_line_session_id = ""
if ("order_line_session_id" in retval.keys() and retval['order_line_session_id']):
order_line_session_id = retval['order_line_session_id']
local_session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(retval['order_line_session_id'])),
'partner_owner_recid': str(my_partner['recid'])}, {'_id': 1, 'code_session': 1})
if (local_session_data and "code_session" in local_session_data.keys()):
order_line_session_code = local_session_data['code_session']
user['order_line_session_code'] = order_line_session_code
user['order_line_session_id'] = order_line_session_id
if ("order_line_montant_reduction" in retval.keys()):
user['order_line_montant_reduction'] = retval['order_line_montant_reduction']
else:
user['order_line_montant_reduction'] = "0"
if ("order_line_type_article" in retval.keys()):
user['order_line_type_article'] = retval['order_line_type_article']
else:
user['order_line_type_article'] = ""
if ("order_line_type_apprenant" in retval.keys()):
user['order_line_type_apprenant'] = retval['order_line_type_apprenant']
else:
user['order_line_type_apprenant'] = ""
if ("order_line_montant_toutes_taxes" in retval.keys()):
user['order_line_montant_toutes_taxes'] = retval['order_line_montant_toutes_taxes']
else:
user['order_line_montant_toutes_taxes'] = "0"
if ("order_line_tax" in retval.keys()):
user['order_line_tax'] = retval['order_line_tax']
else:
user['order_line_tax'] = ""
if ("order_line_tax_amount" in retval.keys()):
user['order_line_tax_amount'] = retval['order_line_tax_amount']
else:
user['order_line_tax_amount'] = "0"
if ("order_line_type_reduction" in retval.keys()):
user['order_line_type_reduction'] = retval['order_line_type_reduction']
else:
user['order_line_montant_reduction'] = ""
if ("order_line_type_valeur" in retval.keys()):
user['order_line_type_valeur'] = retval['order_line_type_valeur']
else:
user['order_line_type_valeur'] = "0"
if ("order_line_montant_hors_taxes" in retval.keys()):
user['order_line_montant_hors_taxes'] = retval['order_line_montant_hors_taxes']
else:
user['order_line_montant_hors_taxes'] = "0"
user['valide'] = retval['valide']
user['locked'] = retval['locked']
if( "date_update" in retval.keys() ):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['update_by'] = str(my_partner['_id'])
user['partner_owner_recid'] = retval['partner_owner_recid']
if( "order_line_comment" in retval.keys()):
user['order_line_comment'] = retval['order_line_comment']
else:
user['order_line_comment'] = ""
user['title'] = retval['myclass_collection'][0]['title']
user['order_line_formation_external_code'] = retval['myclass_collection'][0]['external_code']
if ("domaine" in retval['myclass_collection'][0].keys()):
user['domaine'] = retval['myclass_collection'][0]['domaine']
else:
user['domaine'] = ""
user['duration'] = retval['myclass_collection'][0]['duration']
user['duration_unit'] = retval['myclass_collection'][0]['duration_unit']
if (str(retval['myclass_collection'][0]['duration_unit']) == "heure"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " h"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "jour"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " j"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "semaine"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " s"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "mois"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " m"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "annee"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " a"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "user_rythme"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " u"
else:
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " ?"
RetObject.append(mycommon.JSONEncoder().encode(user))
"""
Recuperation des produits et services
"""
query = [{'$match': {'$and': [ filt_invoice_line_id, filt_invoice_line_header_ref_interne,
{'partner_owner_recid': str(my_partner['recid'])}]}},
{'$lookup': {
'from': 'partner_produit_service',
"let": {'order_line_formation': "$order_line_formation",
"partner_produit_service_partner_owner_recid": "$partner_owner_recid"
},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$valide", "1"]},
{'$eq': ["$_id", {'$convert': {
'input': "$$order_line_formation",
'to': "objectId",
'onError': {'error': 'true'},
'onNull': {'isnull': 'true'}
}}]},
{'$eq': ["$partner_owner_recid",
'$$partner_produit_service_partner_owner_recid']},
]
}
}
},
],
'as': 'collection_partner_produit_service'
}
},
]
#print("#### Get_Given_Partner_Invoice_Lines for PRODUCT & SERVICES : query pip= ", query)
for retval in MYSY_GV.dbname['partner_invoice_line'].aggregate(query):
if ('collection_partner_produit_service' in retval.keys() and len(retval['collection_partner_produit_service']) > 0):
user = {}
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
user['_id'] = retval['_id']
user['order_line_formation'] = retval['order_line_formation']
user['order_line_qty'] = retval['order_line_qty']
user['order_line_prix_unitaire'] = retval['order_line_prix_unitaire']
user['invoice_header_id'] = retval['invoice_header_id']
user['invoice_header_ref_interne'] = retval['invoice_header_ref_interne']
user['invoice_date'] = retval['invoice_date']
user['valide'] = retval['valide']
user['locked'] = retval['locked']
order_line_session_code = ""
order_line_session_id = ""
if ("order_line_session_id" in retval.keys() and retval['order_line_session_id']):
order_line_session_id = retval['order_line_session_id']
local_session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(retval['order_line_session_id'])),
'partner_owner_recid': str(my_partner['recid'])}, {'_id': 1, 'code_session': 1})
if (local_session_data and "code_session" in local_session_data.keys()):
order_line_session_code = local_session_data['code_session']
user['order_line_session_code'] = order_line_session_code
user['order_line_session_id'] = order_line_session_id
if ("order_line_montant_reduction" in retval.keys()):
user['order_line_montant_reduction'] = retval['order_line_montant_reduction']
else:
user['order_line_montant_reduction'] = "0"
if ("order_line_type_apprenant" in retval.keys()):
user['order_line_type_apprenant'] = retval['order_line_type_apprenant']
else:
user['order_line_type_apprenant'] = ""
if ("order_line_montant_toutes_taxes" in retval.keys()):
user['order_line_montant_toutes_taxes'] = retval['order_line_montant_toutes_taxes']
else:
user['order_line_montant_toutes_taxes'] = "0"
if ("order_line_tax" in retval.keys()):
user['order_line_tax'] = retval['order_line_tax']
else:
user['order_line_tax'] = ""
if ("order_line_tax_amount" in retval.keys()):
user['order_line_tax_amount'] = retval['order_line_tax_amount']
else:
user['order_line_tax_amount'] = "0"
if ("order_line_type_reduction" in retval.keys()):
user['order_line_type_reduction'] = retval['order_line_type_reduction']
else:
user['order_line_montant_reduction'] = ""
if ("order_line_type_valeur" in retval.keys()):
user['order_line_type_valeur'] = retval['order_line_type_valeur']
else:
user['order_line_type_valeur'] = "0"
if ("order_line_montant_hors_taxes" in retval.keys()):
user['order_line_montant_hors_taxes'] = retval['order_line_montant_hors_taxes']
else:
user['order_line_montant_hors_taxes'] = "0"
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['update_by'] = str(my_partner['_id'])
user['partner_owner_recid'] = retval['partner_owner_recid']
user['invoice_line_type'] = retval['invoice_line_type']
if ("order_line_comment" in retval.keys()):
user['order_line_comment'] = retval['order_line_comment']
else:
user['order_line_comment'] = ""
user['title'] = retval['collection_partner_produit_service'][0]['nom']
user['order_line_formation_external_code'] = retval['collection_partner_produit_service'][0]['code']
user['domaine'] = ""
user['duration'] = ""
user['duration_unit'] = ""
user['duration_concat'] = ""
"""
Il s'agit d'un produit, vu qu'on a un lien avec la collection "partner_produit_service", on force alors le 'order_line_type_article'
a 'produit'
"""
user['order_line_type_article'] = "produit"
RetObject.append(mycommon.JSONEncoder().encode(user))
#print(" ### RetObject = ", RetObject)
return True, RetObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de récupérer les lignes de facture "
"""
Impression PDF d'une facture
Important : : update du 05/06/2024 :
Si la facture a un document sécurisée (e_Invoice) associé dans la colonne :
'e_document_signe_id', alors on va aller recuperer le document securisé associé
06/12/25 - Important :
Si invoice_regeneration = "1", alors on imprime une facture à la volée, on ne va pas chercher la facture originale.
Dans le modele de facture, on va mettre une condiction dans le template:
- si regelement existe alors on va afficher les reglement
"""
def GerneratePDF_Partner_Invoice(diction):
try:
field_list = ['invoice_id', 'token', 'invoice_regeneration' ]
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]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
return False, " Les informations fournies sont incorrectes"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['invoice_id', 'token', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
return False, "Les informations fournies sont incorrectes"
query_get_data = {}
mytoken = ""
if ("token" in diction.keys()):
if diction['token']:
mytoken = diction['token']
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
if (local_status is not True):
return local_status, my_partner
# Verification de la validité de la facture
qry = {'_id': ObjectId(str(diction['invoice_id'])), 'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
#print(" ### qry = ", qry)
is_invoice_Existe_Count = MYSY_GV.dbname['partner_invoice_header'].count_documents(
{'_id': ObjectId(str(diction['invoice_id'])),
'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (is_invoice_Existe_Count != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La facture n'est pas valide ")
return False, " La facture n'est pas valide",
Order_header_data = MYSY_GV.dbname['partner_invoice_header'].find_one({'_id': ObjectId(str(diction['invoice_id'])),
'valide': '1', 'locked': '0',
'partner_owner_recid': str(
my_partner['recid'])})
invoice_regeneration = "0"
if( "invoice_regeneration" in diction.keys() and diction['invoice_regeneration'] == "1"):
invoice_regeneration = "1"
"""
06/12/205 -
Si invoice_regeneration == "1", on alors on va regenerer la facture sur le modele de document
"""
if( invoice_regeneration != "1" and "e_document_signe_id" in Order_header_data.keys() and Order_header_data['e_document_signe_id']):
# On retourne la e_Invoice securisée
print(" #### RECUPERATION DU FICHIER SECURISE ")
qry = {'_id':ObjectId(str(Order_header_data['e_document_signe_id'])),
'valide':'1',
'locked':'0',
'statut':'1',
'related_collection':'partner_invoice_header',
'related_collection_id':str(Order_header_data['_id']),
'partner_owner_recid':str(my_partner['recid'])}
e_Invoice_Secure_Data = MYSY_GV.dbname['e_document_signe'].find_one({'_id':ObjectId(str(Order_header_data['e_document_signe_id'])),
'valide':'1',
'locked':'0',
'statut':'1',
'related_collection':'partner_invoice_header',
'related_collection_id':str(Order_header_data['_id']),
'partner_owner_recid':str(my_partner['recid'])})
if(e_Invoice_Secure_Data is None ):
mycommon.myprint(str(inspect.stack()[0][
3]) + " Le document sécurisé associé à la facture est invalide 'e_document_signe_id' = "+str(Order_header_data['e_document_signe_id']))
return False, " Le document sécurisé associé à la facture est invalide "
orig_file_name = "Partner_Invoice_" + str(Order_header_data['invoice_header_ref_interne']) + ".pdf"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)
# open output file for writing (truncated binary)
with open(outputFilename, 'w+b') as resultFile:
encoded = base64.b64encode(e_Invoice_Secure_Data['document_data_signed'])
decode_data = e_Invoice_Secure_Data['document_data_signed'].decode()
bytes = base64.b64decode(decode_data, validate=True)
resultFile.write(bytes)
# close output file
resultFile.close()
# print(" ### outputFilename = "+str(outputFilename))
if os.path.exists(outputFilename):
# print(" ### ok os.path.exists(outputFilename) "+str(outputFilename))
return True, send_file(outputFilename, as_attachment=True)
return True, " le fichier securisé recuperé "
else:
partner_document_INVOICE_data_qry = {'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'ref_interne': 'PART_INVOICE', 'type_doc':'pdf'}
#print(" ### partner_document_INVOICE_data_qry = ", partner_document_INVOICE_data_qry)
partner_document_INVOICE_data = MYSY_GV.dbname['courrier_template'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'ref_interne': 'PART_INVOICE', 'type_doc':'pdf'})
if (partner_document_INVOICE_data is None):
# Il n'existe pas de personnalisation de la preinscription pour ce partenaire, on va aller récupérer la presinscription pa defaut
partner_document_INVOICE_data = MYSY_GV.dbname['courrier_template'].find_one(
{'partner_owner_recid': 'default',
'valide': '1', 'locked': '0', 'ref_interne': 'PART_INVOICE', 'type_doc':'pdf'})
if (partner_document_INVOICE_data is None):
mycommon.myprint(
str(inspect.stack()[0][
3]) + "Aucun document paramétré ")
return False, "Aucun document paramétré "
if ("contenu_doc" not in partner_document_INVOICE_data or len(
str(partner_document_INVOICE_data['contenu_doc'])) <= 0):
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le paramétrage du document est invalide")
return False, " Le paramétrage du document est invalide "
# Recuperation des données du client
if ("order_header_client_id" in Order_header_data.keys()):
Order_header_client_data = MYSY_GV.dbname['partner_client'].find_one(
{'_id': ObjectId(str(Order_header_data['order_header_client_id'])),
'partner_owner_recid': str(my_partner['recid']), 'valide': '1', 'locked': '0'})
if (Order_header_client_data is None):
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le client est invalide")
return False, " Le client est invalide"
### Ajout des données du client sur l'entete de la commande, exemple : le nom, email, etc
if("raison_sociale" in Order_header_client_data.keys() ):
Order_header_data['client_raison_sociale'] = Order_header_client_data['raison_sociale']
if ("nom" in Order_header_client_data.keys()):
Order_header_data['client_nom'] = Order_header_client_data['nom']
if ("email" in Order_header_client_data.keys()):
Order_header_data['client_email'] = Order_header_client_data['email']
# Ajout d'un parametre pour le data time du jour de l'edition (c'est une data static qui peut servir pour l'horodatage
Order_header_data['current_date_time'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S") )
# Recuperation des details de lignes de : partner_invoice_line
filt_class_partner_recid = {'partner_owner_recid': str(my_partner['recid'])}
filt_order_header_order_id = {'invoice_header_id': str(diction['invoice_id'])}
query = [{'$match': {'$and': [filt_order_header_order_id,
{'partner_owner_recid': str(my_partner['recid'])}]}},
{'$lookup':
{
'from': 'myclass',
'localField': 'order_line_formation',
'foreignField': 'internal_url',
'pipeline': [{'$match': {'$and': [filt_class_partner_recid]}},
{'$project': {'title': 1, 'domaine': 1, '_id':1,
'duration': 1,
'duration_unit': 1,
'external_code':1}}],
'as': 'myclass_collection'
}
}
]
#print("#### Get_Given_Partner_Order_Lines_From_order_ref_interne : query pip= ", query)
val_tmp = 0
Order_header_lines_data = []
for retval in MYSY_GV.dbname['partner_invoice_line'].aggregate(query):
if ('myclass_collection' in retval.keys() and len(retval['myclass_collection']) > 0):
user = {}
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
user['_id'] = retval['_id']
user['order_line_formation'] = retval['order_line_formation']
user['order_line_class_id'] = str(retval['myclass_collection'][0]['_id'])
user['order_line_qty'] = retval['order_line_qty']
user['order_line_prix_unitaire'] = retval['order_line_prix_unitaire']
user['order_header_id'] = retval['order_header_id']
user['order_header_ref_interne'] = retval['order_header_ref_interne']
user['invoice_header_ref_interne'] = retval['invoice_header_ref_interne']
user['invoice_line_type'] = retval['invoice_line_type']
user['invoice_date'] = retval['invoice_date']
user['valide'] = retval['valide']
user['locked'] = retval['locked']
order_line_session_code = ""
order_line_session_id = ""
if ("order_line_session_id" in retval.keys() and retval['order_line_session_id']):
order_line_session_id = retval['order_line_session_id']
local_session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(retval['order_line_session_id'])),
'partner_owner_recid': str(my_partner['recid'])}, {'_id': 1, 'code_session': 1})
if (local_session_data and "code_session" in local_session_data.keys()):
order_line_session_code = local_session_data['code_session']
user['order_line_session_code'] = order_line_session_code
user['order_line_session_id'] = order_line_session_id
if ("order_line_montant_reduction" in retval.keys()):
user['order_line_montant_reduction'] = retval['order_line_montant_reduction']
else:
user['order_line_montant_reduction'] = "0"
if ("order_line_type_article" in retval.keys()):
user['order_line_type_article'] = retval['order_line_type_article']
else:
user['order_line_type_article'] = ""
"""
Si on a une session, on va aller chercher les info de la session
"""
session_date_debut = ""
session_date_fin = ""
if( "order_line_session_id" in retval.keys() and retval['order_line_session_id']):
session_data = MYSY_GV.dbname['session_formation'].find_one({'_id':ObjectId(str(retval['order_line_session_id'])),
'partner_owner_recid':str(retval['partner_owner_recid'])},
)
if( session_data and "date_debut" in session_data.keys() and "date_fin" in session_data.keys() ):
session_date_debut = str(session_data['date_debut'])
session_date_fin = str(session_data['date_fin'])
user['session_date_debut'] = str(session_date_debut)
user['session_date_fin'] = str(session_date_fin)
if ("order_line_type_apprenant" in retval.keys()):
user['order_line_type_apprenant'] = retval['order_line_type_apprenant']
else:
user['order_line_type_apprenant'] = ""
if ("order_line_montant_toutes_taxes" in retval.keys()):
user['order_line_montant_toutes_taxes'] = retval['order_line_montant_toutes_taxes']
else:
user['order_line_montant_toutes_taxes'] = "0"
if ("order_line_tax" in retval.keys()):
user['order_line_tax'] = retval['order_line_tax']
else:
user['order_line_tax'] = ""
if ("order_line_tax_amount" in retval.keys()):
user['order_line_tax_amount'] = retval['order_line_tax_amount']
else:
user['order_line_tax_amount'] = "0"
if ("order_line_type_reduction" in retval.keys()):
user['order_line_type_reduction'] = retval['order_line_type_reduction']
else:
user['order_line_montant_reduction'] = ""
if ("order_line_type_valeur" in retval.keys()):
user['order_line_type_valeur'] = retval['order_line_type_valeur']
else:
user['order_line_type_valeur'] = "0"
if ("order_line_montant_hors_taxes" in retval.keys()):
user['order_line_montant_hors_taxes'] = retval['order_line_montant_hors_taxes']
else:
user['order_line_montant_hors_taxes'] = "0"
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['update_by'] = str(my_partner['_id'])
user['partner_owner_recid'] = retval['partner_owner_recid']
if ("order_line_comment" in retval.keys()):
user['order_line_comment'] = retval['order_line_comment']
else:
user['order_line_comment'] = ""
user['title'] = retval['myclass_collection'][0]['title']
user['order_line_formation_external_code'] = retval['myclass_collection'][0]['external_code']
if ("domaine" in retval['myclass_collection'][0].keys()):
user['domaine'] = retval['myclass_collection'][0]['domaine']
else:
user['domaine'] = ""
user['duration'] = retval['myclass_collection'][0]['duration']
user['duration_unit'] = retval['myclass_collection'][0]['duration_unit']
if (str(retval['myclass_collection'][0]['duration_unit']) == "heure"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " h"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "jour"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " j"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "semaine"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " s"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "mois"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " m"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "annee"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " a"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "user_rythme"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " u"
else:
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " ?"
"""
Il s'agit d'un formation, vu qu'on a un lien avec la collection "myclass", on force alors le 'order_line_type_article'
a 'formation'
"""
user['order_line_type_article'] = "formation"
"""
19/10/2025 - aller recuperer les données des inscrits en faisant un lien entre partner_invoice_line['tab_inscription_ids']
et partner_invoice_line_detail['order_line_inscription_id']
"""
tab_inscription = []
if ("tab_inscription_ids" in retval.keys()):
for inscription_id in retval['tab_inscription_ids']:
if( inscription_id ):
invoice_inscription_id_data = MYSY_GV.dbname['partner_invoice_line_detail'].find_one(
{'order_line_inscription_id': str(inscription_id),
'valide': '1', 'locked': '0',
'partner_owner_recid': str(retval['partner_owner_recid']),
'invoice_header_ref_interne': str(retval['invoice_header_ref_interne'])
},
{'order_line_inscription_type_apprenant': 1,
'order_line_inscription_comment': 1,
'order_line_inscription_memo': 1,
'order_line_inscription_price': 1,
'order_line_inscription_modefinancement': 1,
'order_line_inscription_nom': 1,
'order_line_inscription_prenom': 1,
'order_line_inscription_email': 1,
'order_line_inscription_civilite': 1,
'tab_inscription_ids': 1,
})
tab_inscription.append(invoice_inscription_id_data)
user['inscription_data'] = tab_inscription
Order_header_lines_data.append(user)
"""
Recuperation des produits et services
"""
query = query = [{'$match': {'$and': [filt_order_header_order_id,
{'partner_owner_recid': str(my_partner['recid'])}]}},
{'$lookup': {
'from': 'partner_produit_service',
"let": {'order_line_formation': "$order_line_formation",
"partner_produit_service_partner_owner_recid": "$partner_owner_recid"
},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$valide", "1"]},
{'$eq': ["$_id", {'$convert': {
'input': "$$order_line_formation",
'to': "objectId",
'onError': {'error': 'true'},
'onNull': {'isnull': 'true'}
}}]},
{'$eq': ["$partner_owner_recid",
'$$partner_produit_service_partner_owner_recid']},
]
}
}
},
],
'as': 'collection_partner_produit_service'
}
},
]
#print("#### Get_Given_Partner_Invoice_Lines for PRODUCT & SERVICES : query pip= ", query)
for retval in MYSY_GV.dbname['partner_invoice_line'].aggregate(query):
if ('collection_partner_produit_service' in retval.keys() and len(retval['collection_partner_produit_service']) > 0):
user = {}
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
user['_id'] = retval['_id']
user['order_line_formation'] = retval['order_line_formation']
user['order_line_qty'] = retval['order_line_qty']
user['order_line_prix_unitaire'] = retval['order_line_prix_unitaire']
user['invoice_header_id'] = retval['invoice_header_id']
user['invoice_header_ref_interne'] = retval['invoice_header_ref_interne']
user['invoice_date'] = retval['invoice_date']
user['valide'] = retval['valide']
user['locked'] = retval['locked']
order_line_session_code = ""
order_line_session_id = ""
if ("order_line_session_id" in retval.keys() and retval['order_line_session_id']):
order_line_session_id = retval['order_line_session_id']
local_session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(retval['order_line_session_id'])),
'partner_owner_recid': str(my_partner['recid'])}, {'_id': 1, 'code_session': 1})
if (local_session_data and "code_session" in local_session_data.keys()):
order_line_session_code = local_session_data['code_session']
user['order_line_session_code'] = order_line_session_code
user['order_line_session_id'] = order_line_session_id
if ("order_line_montant_reduction" in retval.keys()):
user['order_line_montant_reduction'] = retval['order_line_montant_reduction']
else:
user['order_line_montant_reduction'] = "0"
if ("order_line_type_apprenant" in retval.keys()):
user['order_line_type_apprenant'] = retval['order_line_type_apprenant']
else:
user['order_line_type_apprenant'] = ""
if ("order_line_montant_toutes_taxes" in retval.keys()):
user['order_line_montant_toutes_taxes'] = retval['order_line_montant_toutes_taxes']
else:
user['order_line_montant_toutes_taxes'] = "0"
if ("order_line_tax" in retval.keys()):
user['order_line_tax'] = retval['order_line_tax']
else:
user['order_line_tax'] = ""
if ("order_line_tax_amount" in retval.keys()):
user['order_line_tax_amount'] = retval['order_line_tax_amount']
else:
user['order_line_tax_amount'] = "0"
if ("order_line_type_reduction" in retval.keys()):
user['order_line_type_reduction'] = retval['order_line_type_reduction']
else:
user['order_line_montant_reduction'] = ""
if ("order_line_type_valeur" in retval.keys()):
user['order_line_type_valeur'] = retval['order_line_type_valeur']
else:
user['order_line_type_valeur'] = "0"
if ("order_line_montant_hors_taxes" in retval.keys()):
user['order_line_montant_hors_taxes'] = retval['order_line_montant_hors_taxes']
else:
user['order_line_montant_hors_taxes'] = "0"
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['update_by'] = str(my_partner['_id'])
user['partner_owner_recid'] = retval['partner_owner_recid']
user['invoice_line_type'] = retval['invoice_line_type']
if ("order_line_comment" in retval.keys()):
user['order_line_comment'] = retval['order_line_comment']
else:
user['order_line_comment'] = ""
user['title'] = retval['collection_partner_produit_service'][0]['nom']
user['order_line_formation_external_code'] = retval['collection_partner_produit_service'][0]['code']
user['domaine'] = ""
user['duration'] = ""
user['duration_unit'] = ""
user['duration_concat'] = ""
"""
Il s'agit d'un produit, vu qu'on a un lien avec la collection "partner_produit_service", on force alors le 'order_line_type_article'
a 'produit'
"""
user['order_line_type_article'] = "produit"
Order_header_lines_data.append(user)
if (len(Order_header_lines_data) <= 0):
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Aucune ligne de détail pour cette facture ")
return False, " Aucune ligne de détail pour cette facture "
#print(" ### Order_header_lines_data = ", Order_header_lines_data)
"""
Recuperation des reglements (paiements) effectués sur cette facture
"""
invoice_paiement_data = {}
local_paiement_diction = {'token': str(diction['token']), 'invoice_id': str(diction['invoice_id'])}
invoice_paiement_status, invoice_paiement_retval = invoice_paiement_mgt.Get_Invoice_Internal_Liste_Payement_And_Total_Amount( local_paiement_diction)
if( invoice_paiement_status is True):
invoice_paiement_data = invoice_paiement_retval
contenu_doc_Template = jinja2.Template(str(partner_document_INVOICE_data['contenu_doc']))
#print(" #### partner_document_INVOICE_data = ", str(partner_document_INVOICE_data['contenu_doc']))
#sourceHtml = contenu_doc_Template.render(params=Order_header_data)
#print(" ### Order_header_data = ", Order_header_data)
"""
Recuperation du dictionnaire des info
"""
tab_client = []
tab_client.append(ObjectId(str(Order_header_client_data['_id'])))
new_diction = {}
new_diction['token'] = diction['token']
new_diction['list_stagiaire_id'] = []
new_diction['list_session_id'] = []
new_diction['list_class_id'] = []
new_diction['list_client_id'] = tab_client
new_diction['list_apprenant_id'] = []
local_status, local_retval = mycommon.Get_Dictionnary_data_For_Template(new_diction)
if (local_status is False):
return local_status, local_retval
convention_dictionnary_data = local_retval
company_data = {
"params": convention_dictionnary_data,
}
convention_dictionnary_data['order_header'] = Order_header_data
convention_dictionnary_data['order_lines'] = Order_header_lines_data
convention_dictionnary_data['invoice_paiement_data'] = invoice_paiement_data
# read css file
css_file = "./css_document/elyos_css.css"
from xhtml2pdf.default import DEFAULT_CSS
if css_file is not None:
with open(css_file) as f:
DEFAULT_CSS += f.read()
#sourceHtml = contenu_doc_Template.render(params=Order_header_data, param_order_lines=Order_header_lines_data, company_data=company_data)
#sourceHtml = contenu_doc_Template.render(params_order_header=Order_header_data, params_order_lines=Order_header_lines_data, params=company_data['params'])
sourceHtml = contenu_doc_Template.render(params=company_data['params'])
orig_file_name = "Partner_Invoice_"+str(Order_header_data['invoice_header_ref_interne'])+".pdf"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) +"/"+ str(orig_file_name)
# open output file for writing (truncated binary)
resultFile = open(outputFilename, "w+b")
# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
src=sourceHtml, # the HTML to convert
dest=resultFile,
default_css=DEFAULT_CSS) # file handle to receive result
# close output file
resultFile.close()
# print(" ### outputFilename = "+str(outputFilename))
if os.path.exists(outputFilename):
# print(" ### ok os.path.exists(outputFilename) "+str(outputFilename))
return True, send_file(outputFilename, as_attachment=True)
# return True on success and False on errors
print(pisaStatus.err, type(pisaStatus.err))
return True, " le fichier generé "
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
"""
Envoie de la facture par email
06/12/25 - Important :
Si invoice_regeneration = "1", alors on imprime une facture à la volée, on ne va pas chercher la facture originale.
Dans le modele de facture, on va mettre une condiction dans le template:
- si regelement existe alors on va afficher les reglement
"""
def Send_Partner_Invoice_By_Email(tab_files, Folder, diction):
try:
field_list = ['invoice_id', 'token', 'invoice_regeneration' ]
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]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
return False, "Les informations fournies sont incorrectes"
"""
Verification de la liste des champs obligatoires
"""
field_list_obligatoire = ['invoice_id', 'token', ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
return False, " Les informations fournies sont incorrectes "
query_get_data = {}
mytoken = ""
if ("token" in diction.keys()):
if diction['token']:
mytoken = diction['token']
local_status, my_partner = mycommon.Check_Connexion_And_Return_Partner_Data(diction)
if (local_status is not True):
return local_status, my_partner
# Verification de la validité de la facture
qry = {'_id': ObjectId(str(diction['invoice_id'])), 'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
#print(" ### qry = ", qry)
is_Invoice_Existe_Count = MYSY_GV.dbname['partner_invoice_header'].count_documents(
{'_id': ObjectId(str(diction['invoice_id'])),
'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (is_Invoice_Existe_Count != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La facture n'est pas valide is_Invoice_Existe_Count = "+str(is_Invoice_Existe_Count))
return False, " La facture n'est pas valide",
Order_header_data = MYSY_GV.dbname['partner_invoice_header'].find_one({'_id': ObjectId(str(diction['invoice_id'])),
'valide': '1', 'locked': '0',
'partner_owner_recid': str(
my_partner['recid'])})
invoice_regeneration = "0"
if( "invoice_regeneration" in diction.keys() and diction['invoice_regeneration'] == "1"):
invoice_regeneration = "1"
partner_document_INVOICE_data_qry = {'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'ref_interne': 'PART_INVOICE', 'type_doc':'email'}
print(" ### partner_document_CONF_ORDER_data_qry = ", partner_document_INVOICE_data_qry)
partner_document_INVOICE_data = MYSY_GV.dbname['courrier_template'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'ref_interne': 'PART_INVOICE', 'type_doc':'email'})
if (partner_document_INVOICE_data is None):
# Il n'existe pas de personnalisation de la preinscription pour ce partenaire, on va aller récupérer la presinscription pa defaut
partner_document_INVOICE_data = MYSY_GV.dbname['courrier_template'].find_one(
{'partner_owner_recid': 'default',
'valide': '1', 'locked': '0', 'ref_interne': 'PART_INVOICE', 'type_doc':'email'})
if (partner_document_INVOICE_data is None):
mycommon.myprint(
str(inspect.stack()[0][
3]) + "Aucun document paramétré ")
return False, "Aucun document paramétré "
if ("contenu_doc" not in partner_document_INVOICE_data or len(
str(partner_document_INVOICE_data['contenu_doc'])) <= 0):
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le paramétrage du document est invalide")
return False, " Le paramétrage du document est invalide "
# Recuperation des données du client
if( "order_header_client_id" in Order_header_data.keys() ):
Order_header_client_data = MYSY_GV.dbname['partner_client'].find_one({'_id':ObjectId(str(Order_header_data['order_header_client_id'])),
'partner_owner_recid':str(my_partner['recid']), 'valide':'1', 'locked':'0'})
if( Order_header_client_data is None):
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Le client est invalide")
return False, " Le client est invalide"
### Ajout des données du client sur l'entete de la commande, exemple : le nom, email, etc
if ("raison_sociale" in Order_header_client_data.keys()):
Order_header_data['client_raison_sociale'] = Order_header_client_data['raison_sociale']
if ("nom" in Order_header_client_data.keys()):
Order_header_data['client_nom'] = Order_header_client_data['nom']
if ("email" in Order_header_client_data.keys()):
Order_header_data['client_email'] = Order_header_client_data['email']
# Ajout d'un parametre pour le data time du jour de l'edition (c'est une data static qui peut servir pour l'horodatage
Order_header_data['current_date_time'] = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
# Recuperation des details de lignes de : partner_order_line
filt_class_partner_recid = {'partner_owner_recid': str(my_partner['recid'])}
filt_order_header_order_id= {'invoice_header_id': str(diction['invoice_id'])}
query = [{'$match': {'$and': [filt_order_header_order_id,
{'partner_owner_recid': str(my_partner['recid'])}]}},
{'$lookup':
{
'from': 'myclass',
'localField': 'order_line_formation',
'foreignField': 'internal_url',
'pipeline': [{'$match': {'$and': [filt_class_partner_recid]}},
{'$project': {'title': 1, 'domaine': 1, '_id':1,
'duration': 1,
'duration_unit': 1,
'external_code':1}}],
'as': 'myclass_collection'
}
}
]
#print("#### Get_Given_Partner_Order_Lines_From_order_ref_interne : query pip= ", query)
val_tmp = 0
Order_header_lines_data = []
for retval in MYSY_GV.dbname['partner_invoice_line'].aggregate(query):
if ('myclass_collection' in retval.keys() and len(retval['myclass_collection']) > 0):
user = {}
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
user['_id'] = retval['_id']
user['order_line_formation'] = retval['order_line_formation']
user['order_line_class_id'] = str(retval['myclass_collection'][0]['_id'])
user['order_line_qty'] = retval['order_line_qty']
user['order_line_prix_unitaire'] = retval['order_line_prix_unitaire']
user['order_header_id'] = retval['order_header_id']
user['order_header_ref_interne'] = retval['order_header_ref_interne']
user['invoice_header_ref_interne'] = retval['invoice_header_ref_interne']
user['invoice_line_type'] = retval['invoice_line_type']
user['invoice_date'] = retval['invoice_date']
user['invoice_header_id'] = retval['invoice_header_id']
user['valide'] = retval['valide']
user['locked'] = retval['locked']
order_line_session_code = ""
order_line_session_id = ""
if ("order_line_session_id" in retval.keys() and retval['order_line_session_id']):
order_line_session_id = retval['order_line_session_id']
local_session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(retval['order_line_session_id'])),
'partner_owner_recid': str(my_partner['recid'])}, {'_id': 1, 'code_session': 1})
if (local_session_data and "code_session" in local_session_data.keys()):
order_line_session_code = local_session_data['code_session']
user['order_line_session_code'] = order_line_session_code
user['order_line_session_id'] = order_line_session_id
if ("order_line_montant_reduction" in retval.keys()):
user['order_line_montant_reduction'] = retval['order_line_montant_reduction']
else:
user['order_line_montant_reduction'] = "0"
if ("order_line_type_article" in retval.keys()):
user['order_line_type_article'] = retval['order_line_type_article']
else:
user['order_line_type_article'] = ""
"""
Si on a une session, on va aller chercher les info de la session
"""
session_date_debut = ""
session_date_fin = ""
if ("order_line_session_id" in retval.keys() and retval['order_line_session_id']):
session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(retval['order_line_session_id'])),
'partner_owner_recid': str(retval['partner_owner_recid'])},
)
if (session_data and "date_debut" in session_data.keys() and "date_fin" in session_data.keys()):
session_date_debut = str(session_data['date_debut'])
session_date_fin = str(session_data['date_fin'])
user['session_date_debut'] = str(session_date_debut)
user['session_date_fin'] = str(session_date_fin)
if ("order_line_type_apprenant" in retval.keys()):
user['order_line_type_apprenant'] = retval['order_line_type_apprenant']
else:
user['order_line_type_apprenant'] = ""
if ("order_line_montant_toutes_taxes" in retval.keys()):
user['order_line_montant_toutes_taxes'] = retval['order_line_montant_toutes_taxes']
else:
user['order_line_montant_toutes_taxes'] = "0"
if ("order_line_tax" in retval.keys()):
user['order_line_tax'] = retval['order_line_tax']
else:
user['order_line_tax'] = ""
if ("order_line_tax_amount" in retval.keys()):
user['order_line_tax_amount'] = retval['order_line_tax_amount']
else:
user['order_line_tax_amount'] = "0"
if ("order_line_type_reduction" in retval.keys()):
user['order_line_type_reduction'] = retval['order_line_type_reduction']
else:
user['order_line_montant_reduction'] = ""
if ("order_line_type_valeur" in retval.keys()):
user['order_line_type_valeur'] = retval['order_line_type_valeur']
else:
user['order_line_type_valeur'] = "0"
if ("order_line_montant_hors_taxes" in retval.keys()):
user['order_line_montant_hors_taxes'] = retval['order_line_montant_hors_taxes']
else:
user['order_line_montant_hors_taxes'] = "0"
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['update_by'] = str(my_partner['_id'])
user['partner_owner_recid'] = retval['partner_owner_recid']
if ("order_line_comment" in retval.keys()):
user['order_line_comment'] = retval['order_line_comment']
else:
user['order_line_comment'] = ""
user['title'] = retval['myclass_collection'][0]['title']
user['order_line_formation_external_code'] = retval['myclass_collection'][0]['external_code']
if ("domaine" in retval['myclass_collection'][0].keys()):
user['domaine'] = retval['myclass_collection'][0]['domaine']
else:
user['domaine'] = ""
user['duration'] = retval['myclass_collection'][0]['duration']
user['duration_unit'] = retval['myclass_collection'][0]['duration_unit']
if (str(retval['myclass_collection'][0]['duration_unit']) == "heure"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " h"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "jour"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " j"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "semaine"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " s"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "mois"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " m"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "annee"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " a"
elif (str(retval['myclass_collection'][0]['duration_unit']) == "user_rythme"):
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " u"
else:
user['duration_concat'] = str(retval['myclass_collection'][0]['duration']) + " ?"
"""
Il s'agit d'un formation, vu qu'on a un lien avec la collection "myclass", on force alors le 'order_line_type_article'
a 'formation'
"""
user['order_line_type_article'] = "formation"
"""
19/10/2025 - aller recuperer les données des inscrits en faisant un lien entre partner_invoice_line['tab_inscription_ids']
et partner_invoice_line_detail['order_line_inscription_id']
"""
tab_inscription = []
if( "tab_inscription_ids" in retval.keys() ):
for inscription_id in retval['tab_inscription_ids']:
if( inscription_id):
invoice_inscription_id_data = MYSY_GV.dbname['partner_invoice_line_detail'].find_one(
{'order_line_inscription_id': str(inscription_id),
'valide': '1', 'locked': '0',
'partner_owner_recid': str(retval['partner_owner_recid']),
'invoice_header_ref_interne': str(retval['invoice_header_ref_interne'])
},
{'order_line_inscription_type_apprenant': 1,
'order_line_inscription_comment': 1,
'order_line_inscription_memo': 1,
'order_line_inscription_price': 1,
'order_line_inscription_modefinancement': 1,
'order_line_inscription_nom': 1,
'order_line_inscription_prenom': 1,
'order_line_inscription_email': 1,
'order_line_inscription_civilite': 1,
'tab_inscription_ids': 1,
})
tab_inscription.append(invoice_inscription_id_data)
user['inscription_data'] = tab_inscription
Order_header_lines_data.append(user)
"""
Recuperation des produits et services
"""
query = [{'$match': {'$and': [filt_order_header_order_id,
{'partner_owner_recid': str(my_partner['recid'])}]}},
{'$lookup': {
'from': 'partner_produit_service',
"let": {'order_line_formation': "$order_line_formation",
"partner_produit_service_partner_owner_recid": "$partner_owner_recid"
},
'pipeline': [
{'$match':
{'$expr':
{'$and':
[
{'$eq': ["$valide", "1"]},
{'$eq': ["$_id", {'$convert': {
'input': "$$order_line_formation",
'to': "objectId",
'onError': {'error': 'true'},
'onNull': {'isnull': 'true'}
}}]},
{'$eq': ["$partner_owner_recid",
'$$partner_produit_service_partner_owner_recid']},
]
}
}
},
],
'as': 'collection_partner_produit_service'
}
},
]
#print("#### Get_Given_Partner_Invoice_Lines for PRODUCT & SERVICES : query pip= ", query)
for retval in MYSY_GV.dbname['partner_invoice_line'].aggregate(query):
if ('collection_partner_produit_service' in retval.keys() and len(retval['collection_partner_produit_service']) > 0):
user = {}
user['id'] = str(val_tmp)
val_tmp = val_tmp + 1
user['_id'] = retval['_id']
user['order_line_formation'] = retval['order_line_formation']
user['order_line_qty'] = retval['order_line_qty']
user['order_line_prix_unitaire'] = retval['order_line_prix_unitaire']
user['invoice_header_id'] = retval['invoice_header_id']
user['invoice_header_ref_interne'] = retval['invoice_header_ref_interne']
user['invoice_date'] = retval['invoice_date']
user['valide'] = retval['valide']
user['locked'] = retval['locked']
order_line_session_code = ""
order_line_session_id = ""
if ("order_line_session_id" in retval.keys() and retval['order_line_session_id']):
order_line_session_id = retval['order_line_session_id']
local_session_data = MYSY_GV.dbname['session_formation'].find_one(
{'_id': ObjectId(str(retval['order_line_session_id'])),
'partner_owner_recid': str(my_partner['recid'])}, {'_id': 1, 'code_session': 1})
if (local_session_data and "code_session" in local_session_data.keys()):
order_line_session_code = local_session_data['code_session']
user['order_line_session_code'] = order_line_session_code
user['order_line_session_id'] = order_line_session_id
if ("order_line_montant_reduction" in retval.keys()):
user['order_line_montant_reduction'] = retval['order_line_montant_reduction']
else:
user['order_line_montant_reduction'] = "0"
if ("order_line_type_apprenant" in retval.keys()):
user['order_line_type_apprenant'] = retval['order_line_type_apprenant']
else:
user['order_line_type_apprenant'] = ""
if ("order_line_montant_toutes_taxes" in retval.keys()):
user['order_line_montant_toutes_taxes'] = retval['order_line_montant_toutes_taxes']
else:
user['order_line_montant_toutes_taxes'] = "0"
if ("order_line_tax" in retval.keys()):
user['order_line_tax'] = retval['order_line_tax']
else:
user['order_line_tax'] = ""
if ("order_line_tax_amount" in retval.keys()):
user['order_line_tax_amount'] = retval['order_line_tax_amount']
else:
user['order_line_tax_amount'] = "0"
if ("order_line_type_reduction" in retval.keys()):
user['order_line_type_reduction'] = retval['order_line_type_reduction']
else:
user['order_line_montant_reduction'] = ""
if ("order_line_type_valeur" in retval.keys()):
user['order_line_type_valeur'] = retval['order_line_type_valeur']
else:
user['order_line_type_valeur'] = "0"
if ("order_line_montant_hors_taxes" in retval.keys()):
user['order_line_montant_hors_taxes'] = retval['order_line_montant_hors_taxes']
else:
user['order_line_montant_hors_taxes'] = "0"
if ("date_update" in retval.keys()):
user['update_date'] = retval['date_update']
if ("update_date" in retval.keys()):
user['update_date'] = retval['update_date']
user['update_by'] = str(my_partner['_id'])
user['partner_owner_recid'] = retval['partner_owner_recid']
user['invoice_line_type'] = retval['invoice_line_type']
if ("order_line_comment" in retval.keys()):
user['order_line_comment'] = retval['order_line_comment']
else:
user['order_line_comment'] = ""
user['title'] = retval['collection_partner_produit_service'][0]['nom']
user['order_line_formation_external_code'] = retval['collection_partner_produit_service'][0]['code']
user['domaine'] = ""
user['duration'] = ""
user['duration_unit'] = ""
user['duration_concat'] = ""
"""
Il s'agit d'un produit, vu qu'on a un lien avec la collection "partner_produit_service", on force alors le 'order_line_type_article'
a 'produit'
"""
user['order_line_type_article'] = "produit"
Order_header_lines_data.append(user)
if(len(Order_header_lines_data) <= 0 ):
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Aucune ligne de détail pour cette facture ")
return False, " Aucune ligne de détail pour cette facture "
# Sauvegarde des fichiers joints depuis le front
tab_saved_file_full_path = []
for file in tab_files:
status, saved_file_full_path = mycommon.Upload_Save_PDF_IMG_File(file, Folder)
if (status is False):
return status, saved_file_full_path
tab_saved_file_full_path.append(saved_file_full_path)
# Traitement de l'eventuel fichier joint
tab_files_to_attache_to_mail = []
for saved_file in tab_saved_file_full_path:
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(saved_file, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(os.path.basename(saved_file)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
print(" ## tab_files_to_attache_to_mail 01 = ", tab_files_to_attache_to_mail)
# Recuperation des données du partenaire associé à l'utilisateur connecté
local_status, local_retval = mycommon.Get_Connected_User_Partner_Data_From_RecID(my_partner['recid'])
if (local_status is False):
return local_status, local_retval
local_company_data = local_retval
"""
Recuperation des reglements (paiements) effectués sur cette facture
"""
invoice_paiement_data = {}
local_paiement_diction = {'token': str(diction['token']), 'invoice_id': str(diction['invoice_id'])}
invoice_paiement_status, invoice_paiement_retval = invoice_paiement_mgt.Get_Invoice_Internal_Liste_Payement_And_Total_Amount(
local_paiement_diction)
if (invoice_paiement_status is True):
invoice_paiement_data = invoice_paiement_retval
"""
Recuperation du dictionnaire des info
"""
tab_client = []
tab_client.append(ObjectId(str(Order_header_client_data['_id'])))
new_diction = {}
new_diction['token'] = diction['token']
new_diction['list_stagiaire_id'] = []
new_diction['list_session_id'] = []
new_diction['list_class_id'] = []
new_diction['list_client_id'] = tab_client
new_diction['list_apprenant_id'] = []
local_status, local_retval = mycommon.Get_Dictionnary_data_For_Template(new_diction)
if (local_status is False):
return local_status, local_retval
if ("company_data" in local_retval.keys() and "societe_nom" in local_retval['company_data'].keys()):
company_name = local_retval['company_data']['societe_nom']
convention_dictionnary_data = local_retval
company_data = {
"params": convention_dictionnary_data,
}
body = {
"params": convention_dictionnary_data,
}
convention_dictionnary_data['order_header'] = Order_header_data
convention_dictionnary_data['order_lines'] = Order_header_lines_data
convention_dictionnary_data['invoice_paiement_data'] = invoice_paiement_data
#print(" ############ convention_dictionnary_data = ", convention_dictionnary_data)
# Recuperation de la version PDF de la facture déjà enregistrée
Invoice_header_data = MYSY_GV.dbname['partner_invoice_header'].find_one(
{'_id': ObjectId(str(diction['invoice_id'])),
'valide': '1', 'locked': '0',
'partner_owner_recid': str(
my_partner['recid'])})
# Verifier s'il s'agit d'un document à envoyer avec une version de pièce jointe.
if ("joint_pdf" in partner_document_INVOICE_data.keys() and str(
partner_document_INVOICE_data['joint_pdf']) == "1"):
# Si on a un document sécurisé associé, alors on va le chercher, si non on le crée à la volée
"""
06/12/205 -
Si invoice_regeneration == "1", on alors on va regenerer la facture sur le modele de document
"""
if ( invoice_regeneration != "1" and "e_document_signe_id" in Invoice_header_data.keys() and Invoice_header_data['e_document_signe_id']):
# On retourne la e_Invoice securisée
print(" #### RECUPERATION DU FICHIER SECURISE ")
qry = {'_id': ObjectId(str(Invoice_header_data['e_document_signe_id'])),
'valide': '1',
'locked': '0',
'statut': '1',
'related_collection': 'partner_invoice_header',
'related_collection_id': str(Invoice_header_data['_id']),
'partner_owner_recid': str(my_partner['recid'])}
e_Invoice_Secure_Data = MYSY_GV.dbname['e_document_signe'].find_one(
{'_id': ObjectId(str(Invoice_header_data['e_document_signe_id'])),
'valide': '1',
'locked': '0',
'statut': '1',
'related_collection': 'partner_invoice_header',
'related_collection_id': str(Order_header_data['_id']),
'partner_owner_recid': str(my_partner['recid'])})
if (e_Invoice_Secure_Data is None):
mycommon.myprint(str(inspect.stack()[0][
3]) + " Le document sécurisé associé à la facture est invalide 'e_document_signe_id' = " + str(
Order_header_data['e_document_signe_id']))
return False, " Le document sécurisé associé à la facture est invalide "
orig_file_name = "Partner_Invoice_" + str(Invoice_header_data['invoice_header_ref_interne']) + ".pdf"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)
# open output file for writing (truncated binary)
with open(outputFilename, 'w+b') as resultFile:
encoded = base64.b64encode(e_Invoice_Secure_Data['document_data_signed'])
decode_data = e_Invoice_Secure_Data['document_data_signed'].decode()
bytes = base64.b64decode(decode_data, validate=True)
resultFile.write(bytes)
# close output file
resultFile.close()
# Attachement du fichier joint
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(outputFilename, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(
os.path.basename(outputFilename)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
else:
# Il n'y pas de fichier joint sécurisé, il faut donc en créer un à la volée
"""
1 - Creation du PDF
"""
contenu_doc_Template = jinja2.Template(str(partner_document_INVOICE_data['contenu_doc']))
contenuHtml = contenu_doc_Template.render(params=body["params"])
todays_date = str(date.today().strftime("%d/%m/%Y"))
ts = datetime.now().timestamp()
ts = str(ts).replace(".", "").replace(",", "")[-5:]
orig_file_name = str(Invoice_header_data['invoice_header_type']) + "_" + str(my_partner['recid'])[
0:5] + "_" + str(ts) + ".pdf"
outputFilename = str(MYSY_GV.TEMPORARY_DIRECTORY) + "/" + str(orig_file_name)
# open output file for writing (truncated binary)
resultFile = open(outputFilename, "w+b")
# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
src=contenuHtml, # the HTML to convert
dest=resultFile) # file handle to receive result
# close output file
resultFile.close()
# Attachement du fichier joint
file_to_attache_to_mail = MIMEBase('application', "octet-stream")
file_to_attache_to_mail.set_payload(open(outputFilename, "rb").read())
encoders.encode_base64(file_to_attache_to_mail)
file_to_attache_to_mail.add_header('Content-Disposition',
'attachment; filename="{0}"'.format(os.path.basename(outputFilename)))
new_node = {"attached_file": file_to_attache_to_mail}
tab_files_to_attache_to_mail.append(new_node)
corps_mail_doc_Template = jinja2.Template(str(partner_document_INVOICE_data['corps_mail']))
sujet_doc_Template_subject = jinja2.Template(str(partner_document_INVOICE_data['sujet']))
sourceHtml = corps_mail_doc_Template.render(params=body['params'], )
sujetHtml = sujet_doc_Template_subject.render(params=body['params'], )
html_mime = MIMEText(sourceHtml, 'html')
else:
mycommon.myprint(str(inspect.stack()[0][
3]) + " Le paramétrage du modèle de courrier 'PART_ORDER' ne comporte pas de 'joint_pdf' ")
return False, " Le paramétrage du modèle de courrier 'PART_ORDER' ne comporte pas de 'joint_pdf'. Merci d'activier les pièces jointes dans le paramétrage "
""" ORIG "" "
#print(" #### Order_header_data = ", Order_header_data)
#sourceHtml = contenu_doc_Template.render(params=Order_header_data, param_order_lines=Order_header_lines_data, company_data=company_data)
contenu_doc_Template = jinja2.Template(str(partner_document_INVOICE_data['contenu_doc']))
#contenuHtml = contenu_doc_Template.render(params_order_header=Order_header_data,params_order_lines=Order_header_lines_data, params=company_data['params'])
contenuHtml = contenu_doc_Template.render(params=company_data['params'])
contenu_doc_Template_subject = jinja2.Template(str(partner_document_INVOICE_data['sujet']))
#sujetHtml = contenu_doc_Template_subject.render(params_order_header=Order_header_data)
sujetHtml = contenu_doc_Template_subject.render(params=company_data['params'])
#print(" #### sourceHtml = ", sourceHtml)
"" " FIN ORIG """
"""
Recuperation des parametre SMTP du partner si le client a decidé d'utiliser son propre smpt
"""
partner_own_smtp_value = "0"
partner_own_smtp = MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'partner_smtp',
'valide': '1',
'locked': '0'})
if( partner_own_smtp and "config_value" in partner_own_smtp.keys()):
partner_own_smtp_value = partner_own_smtp['config_value']
if( str(partner_own_smtp_value) == "1"):
partner_SMTP_COUNT_password = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_user_pwd',
'valide': '1',
'locked': '0'}, {'config_value':1} )['config_value'])
partner_SMTP_COUNT_smtpsrv = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_server',
'valide': '1',
'locked': '0'}, {'config_value':1})['config_value'])
partner_SMTP_COUNT_user = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_user',
'valide': '1',
'locked': '0'}, {'config_value':1})['config_value'])
partner_SMTP_COUNT_From_User = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_count_from_name',
'valide': '1',
'locked': '0'}, {'config_value':1})['config_value'])
partner_SMTP_COUNT_port = str(MYSY_GV.dbname['base_partner_setup'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'config_name': 'smtp_count_port',
'valide': '1',
'locked': '0'}, {'config_value':1})['config_value'])
if (str(partner_own_smtp_value) == "1"):
print("debut envoi mail de test ")
# Creation de l'email à enoyer
msg = MIMEMultipart("alternative")
msg.attach(html_mime)
smtpserver = smtplib.SMTP(partner_SMTP_COUNT_smtpsrv, partner_SMTP_COUNT_port)
client_main_mail_tmp = ""
if ("order_header_email_client" in Order_header_data.keys() and Order_header_data[
'order_header_email_client']):
client_main_mail_tmp = str(Order_header_data['order_header_email_client'])
if (mycommon.isEmailValide(client_main_mail_tmp) is True):
msg['To'] = client_main_mail_tmp
else:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - L'adresse email sur la commande n'est pas valide ")
return False, " L'adresse email sur la commande n'est pas valide "
else:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Aucune adresse email sur la commande ")
return False, " Aucune adresse email sur la commande "
msg['From'] = partner_SMTP_COUNT_From_User
msg['Bcc'] = 'contact@mysy-training.com'
msg['Subject'] = sujetHtml
# Attacher l'eventuelle pièces jointes
for myfile in tab_files_to_attache_to_mail:
msg.attach(myfile['attached_file'])
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.login(partner_SMTP_COUNT_user, partner_SMTP_COUNT_password)
val = smtpserver.send_message(msg)
smtpserver.close()
print(" Email envoyé " + str(val))
else:
print("debut envoi mail de test ")
# Creation de l'email à enoyer
msg = MIMEMultipart("alternative")
msg.attach(html_mime)
smtpserver = smtplib.SMTP(MYSY_GV.O365_SMTP_COUNT_smtpsrv, MYSY_GV.O365_SMTP_COUNT_port)
client_main_mail_tmp = ""
if ("order_header_email_client" in Order_header_data.keys() and Order_header_data[
'order_header_email_client']):
client_main_mail_tmp = str(Order_header_data['order_header_email_client'])
if (mycommon.isEmailValide(client_main_mail_tmp) is True):
msg['To'] = client_main_mail_tmp
else:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - L'adresse email sur la commande n'est pas valide ")
return False, " L'adresse email sur la commande n'est pas valide "
else:
mycommon.myprint(str(inspect.stack()[0][
3]) + " - Aucune adresse email sur la commande ")
return False, " Aucune adresse email sur la commande "
#msg['From'] = MYSY_GV.O365_SMTP_COUNT_From_User
if (company_name):
msg['From'] = str(company_name) + " <" + str(MYSY_GV.O365_SMTP_COUNT_From_User) + ">"
else:
msg['From'] = str(MYSY_GV.O365_SMTP_COUNT_From_User)
msg['Bcc'] = 'contact@mysy-training.com'
msg['Subject'] = sujetHtml
# Attacher l'eventuelle pièces jointes
for myfile in tab_files_to_attache_to_mail:
msg.attach(myfile['attached_file'])
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.login(MYSY_GV.O365_SMTP_COUNT_user, MYSY_GV.O365_SMTP_COUNT_password)
val = smtpserver.send_message(msg)
smtpserver.close()
print(" Email envoyé " + str(val))
"""
Ajout l'action dans l'historique
"""
## Add to log history
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = diction['token']
history_event_dict['related_collection'] = "partner_invoice_header"
history_event_dict['related_collection_recid'] = str(diction['invoice_id'])
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Envoyé par email à : '"+str(client_main_mail_tmp)+"' "
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
return True, "Facture a été envoyée par email à : '"+str(client_main_mail_tmp)+"' "
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
print(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible d'envoyer la facture par email"
"""
Important : 26/04/2024
La fonction de creation d'une facture va computer la commande associée, puis copier les ligne
or quand on fait une facturation a partir d'une session, il n'y pas de 'commande', donc pas de computation.
Il faut donc créer une fonction de computation de la factures apres sa creation
"""
def Compute_Invoice_Order_Data(diction):
try:
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 la liste des arguments ")
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
# Recuperation de la valeur de la TVA (taux tva)
partner_taux_tva = 20
if ("invoice_taux_vat" in my_partner.keys()):
IsInt_status, IsInt_retval = mycommon.IsInt(str(my_partner['invoice_taux_vat']))
if (IsInt_status is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La valeur '" + str(
my_partner['invoice_taux_vat']) + "' n'est pas un taux de TVA correcte ")
return False, " La valeur '" + str(
my_partner['invoice_taux_vat']) + "' n'est pas un taux de TVA correcte ",
partner_taux_tva = IsInt_retval
print(" ### COMPUTE : le taux de TVA = ", str(partner_taux_tva))
# Verification de la validité de la facture
qry = {'_id': ObjectId(str(diction['_id'])), 'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
print(" ### qry = ", qry)
is_Invoice_Existe_Count = MYSY_GV.dbname['partner_invoice_header'].count_documents(
{'_id': ObjectId(str(diction['_id'])),
'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (is_Invoice_Existe_Count != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant de la facture n'est pas valide ")
return False, " L'identifiant de la facture n'est pas valide ",
Invoice_Data = MYSY_GV.dbname['partner_invoice_header'].find_one({'_id': ObjectId(str(diction['_id'])),
'valide': '1', 'locked': '0',
'partner_owner_recid':str(my_partner['recid'])})
"""
Verifier que la facture a des lignes valides, si non refuser
"""
is_Invoice_Line_Existe_Count = MYSY_GV.dbname['partner_invoice_line'].count_documents(
{'invoice_header_id': (str(diction['_id'])),
'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (is_Invoice_Line_Existe_Count <= 0):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Il n'existe aucune ligne de facture pour cette facture_id : "+str(diction['_id']))
return False, " Il n'existe aucune ligne de facture pour cette facture_id : "+str(diction['_id'])
"""
Algo :
1 - récupérer toutes les lignes valides, créer des sous totaux
2 - Appliquer les eventuels reductions d'entete
"""
nb_line = 0
line_sum_invoice_line_tax_amount = 0
line_sum_invoice_line_montant_reduction = 0
line_sum_invoice_line_montant_hors_taxes_before_reduction = 0
line_sum_invoice_line_montant_hors_taxes_after_reduction = 0
line_sum_invoice_line_montant_toutes_taxes = 0
for local_retval in MYSY_GV.dbname['partner_invoice_line'].find( {'invoice_header_id': (str(diction['_id'])), 'valide': '1', 'locked': '0','partner_owner_recid': str(my_partner['recid'])}):
print(" ------------------- Pour la ligne numero : ", nb_line)
ligne_montant_reduction = 0
if ("order_line_montant_reduction" in local_retval.keys()):
line_sum_invoice_line_montant_reduction = line_sum_invoice_line_montant_reduction + mycommon.tryFloat(
local_retval['order_line_montant_reduction'])
ligne_montant_reduction = mycommon.tryFloat(local_retval['order_line_montant_reduction'])
"""
print(" #### invoice_line_montant_reduction = ",
str(mycommon.tryFloat(local_retval['order_line_montant_reduction'])))
"""
if ("order_line_tax_amount" in local_retval.keys()):
line_sum_invoice_line_tax_amount = line_sum_invoice_line_tax_amount + mycommon.tryFloat(
local_retval['order_line_tax_amount'])
#print(" #### invoice_line_tax_amount = ", str(mycommon.tryFloat(local_retval['order_line_tax_amount'])))
if ("order_line_montant_hors_taxes" in local_retval.keys()):
line_sum_invoice_line_montant_hors_taxes_before_reduction = line_sum_invoice_line_montant_hors_taxes_before_reduction + mycommon.tryFloat(
local_retval['order_line_montant_hors_taxes'])
"""
print(" #### invoice_line_montant_hors_taxes = ",
str(mycommon.tryFloat(local_retval['order_line_montant_hors_taxes'])))
"""
invoice_line_montant_hors_taxes_APRES_REDUCTION = mycommon.tryFloat(
local_retval['order_line_montant_hors_taxes']) - ligne_montant_reduction
#print(" #### invoice_line_montant_hors_taxes_APRES_REDUCTION = ", str(invoice_line_montant_hors_taxes_APRES_REDUCTION))
if ("order_line_montant_toutes_taxes" in local_retval.keys()):
line_sum_invoice_line_montant_toutes_taxes = line_sum_invoice_line_montant_toutes_taxes + mycommon.tryFloat(local_retval['order_line_montant_toutes_taxes'])
#print(" #### invoice_line_montant_toutes_taxes = ", str(mycommon.tryFloat(local_retval['order_line_montant_toutes_taxes'])))
print(" ----------- FIN DES LIGNES ")
nb_line = nb_line + 1
line_sum_invoice_line_montant_hors_taxes_after_reduction = line_sum_invoice_line_montant_hors_taxes_before_reduction - line_sum_invoice_line_montant_reduction
"""print(" ###### Apres compute des lignes : NB_LINE = ", nb_line)
print(" ###### line_sum_order_line_montant_reduction = ", line_sum_order_line_montant_reduction)
print(" ###### line_sum_order_line_tax_amount = ", line_sum_order_line_tax_amount)
print(" ###### line_sum_order_line_montant_hors_taxes_before_reduction = ", line_sum_order_line_montant_hors_taxes_before_reduction)
print(" ###### line_sum_order_line_montant_hors_taxes_after_reduction = ", line_sum_order_line_montant_hors_taxes_after_reduction)
print(" ###### line_sum_order_line_montant_toutes_taxes = ", line_sum_order_line_montant_toutes_taxes)
"""
header_reduction_type = ""
header_reduction_type_value = ""
if ("order_header_type_reduction" in Invoice_Data.keys()):
header_reduction_type = Invoice_Data['order_header_type_reduction']
if ("order_header_type_reduction_valeur" in Invoice_Data.keys()):
header_reduction_type_value = Invoice_Data['order_header_type_reduction_valeur']
"""print(" ### les reduction d'entete ")
print(" ###### header_reduction_type = ", header_reduction_type)
print(" ###### header_reduction_type_value = ", header_reduction_type_value)
"""
global_invoice_taxe_amount = 0
global_invoice_amount_ht_before_header_reduction = line_sum_invoice_line_montant_hors_taxes_after_reduction
global_invoice_amount_ht_after_header_reduction = 0
header_reduction_type_value_total_amount = 0
if (str(header_reduction_type) == "fixe"):
header_reduction_type_value_total_amount = mycommon.tryFloat(header_reduction_type_value)
global_order_amount_ht_after_header_reduction = line_sum_invoice_line_montant_hors_taxes_after_reduction - mycommon.tryFloat(
header_reduction_type_value)
"""print(" GRRRR 022 header_reduction_type_value_total_amount = ",
header_reduction_type_value_total_amount)
print(" GRRRR 022 global_order_amount_ht_after_header_reduction = ",
global_order_amount_ht_after_header_reduction)
"""
elif (str(header_reduction_type) == "percent"):
"""
print(" GRRRR line_sum_order_line_montant_hors_taxes_after_reduction = ",
line_sum_invoice_line_montant_hors_taxes_after_reduction)
print(" GRRRR mycommon.tryFloat(header_reduction_type_value)/100 = ",
line_sum_invoice_line_montant_hors_taxes_after_reduction * mycommon.tryFloat(
header_reduction_type_value) / 100)
print(" GRRRR mycommon.tryFloat(header_reduction_type_value)/100 = ",
(line_sum_invoice_line_montant_hors_taxes_after_reduction - (
line_sum_invoice_line_montant_hors_taxes_after_reduction * mycommon.tryFloat(
header_reduction_type_value) / 100)))
"""
header_reduction_type_value_total_amount = line_sum_invoice_line_montant_hors_taxes_after_reduction * mycommon.tryFloat(
header_reduction_type_value) / 100
global_order_amount_ht_after_header_reduction = line_sum_invoice_line_montant_hors_taxes_after_reduction - ((
line_sum_invoice_line_montant_hors_taxes_after_reduction * mycommon.tryFloat(
header_reduction_type_value) / 100))
"""
print(" GRRRR global_order_amount_ht_after_header_reduction = ",
global_order_amount_ht_after_header_reduction)
"""
else:
header_reduction_type_value_total_amount = 0
global_order_amount_ht_before_header_reduction = line_sum_invoice_line_montant_hors_taxes_after_reduction
global_order_amount_ht_after_header_reduction = line_sum_invoice_line_montant_hors_taxes_after_reduction
global_order_amount_ttc = global_order_amount_ht_after_header_reduction + line_sum_invoice_line_tax_amount
"""print(" ###### header_reduction_type_value_total_amount = ", header_reduction_type_value_total_amount)
print(" ###### global_order_amount_ht_before_header_reduction = ", line_sum_order_line_montant_hors_taxes_after_reduction)
print(" ###### global_order_amount_ht_after_header_reduction = ", global_order_amount_ht_after_header_reduction)
print(" ###### global_order_amount_ttc = ", global_order_amount_ttc)
"""
"""
Tous les calculs, ok, on met à l'entete de de l'order
"""
header_computed_data = {}
header_computed_data['total_lines_montant_reduction'] = str(round(line_sum_invoice_line_montant_reduction, 3))
header_computed_data['total_lines_hors_taxe_before_lines_reduction'] = str(
round(line_sum_invoice_line_montant_hors_taxes_before_reduction, 3))
header_computed_data['total_lines_hors_taxe_after_lines_reduction'] = str(
round(line_sum_invoice_line_montant_hors_taxes_after_reduction, 3))
header_computed_data['order_header_montant_reduction'] = str(round(header_reduction_type_value_total_amount, 3))
header_computed_data['total_header_hors_taxe_before_header_reduction'] = str(
round(line_sum_invoice_line_montant_hors_taxes_after_reduction, 3))
header_computed_data['total_header_hors_taxe_after_header_reduction'] = str(
round(global_order_amount_ht_after_header_reduction, 3))
header_computed_data['order_header_tax'] = "TVA " + str(partner_taux_tva) + "%"
header_computed_data['order_header_tax_amount'] = str(round(line_sum_invoice_line_tax_amount, 3))
header_computed_data['total_header_toutes_taxes'] = str(round(global_order_amount_ttc, 3))
header_computed_data['update_date'] = str(datetime.now())
header_computed_data['update_by'] = str(my_partner['recid'])
print(" ### header_computed_data = ", header_computed_data)
local_retval = MYSY_GV.dbname['partner_invoice_header'].find_one_and_update({'_id': ObjectId(str(diction['_id'])),
'valide': '1', 'locked': '0',
'partner_owner_recid': str(
my_partner['recid'])},
{"$set": header_computed_data
},
upsert=False,
return_document=ReturnDocument.AFTER
)
if (local_retval is None):
mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible de finaliser la mise à jour")
return False, " Impossible de finaliser la mise à jour "
return True, 'La facture a été correctement recalculé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 recalculer les totaux de la facture "
"""
Cette fonction permets ajouter / mettre à jour une annotation
sur une facture
"""
def Add_Update_Invoice_Annotation(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', '_id', 'annotation']
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', 'annotation']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
return False, " 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 que la factre est valide
"""
is_valide_invoice_cout = MYSY_GV.dbname['partner_invoice_header'].count_documents({'_id':ObjectId(str(diction['_id'])),
'partner_owner_recid':my_partner['recid'],
'valide':'1',
'locked':'0'})
if( is_valide_invoice_cout <= 0 ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant de la facture est invalide ")
return False, " L'identifiant de la facture est invalide ",
update_data = {}
update_data['update_date'] = str(datetime.now())
update_data['update_by'] = str(my_partner['_id'])
update_data['partner_owner_recid'] = str(my_partner['recid'])
result = MYSY_GV.dbname['partner_invoice_header'].find_one_and_update(
{'_id': ObjectId(str(diction['_id'])),
'valide': '1',
'locked': '0',
'partner_owner_recid': str(my_partner['recid'])},
{"$set": {"annotation":str(diction['annotation'])}},
upsert=False,
return_document=ReturnDocument.AFTER
)
"""
Ajout l'action dans l'historique
"""
## Add to log history
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = diction['token']
history_event_dict['related_collection'] = "partner_invoice_header"
history_event_dict['related_collection_recid'] = str(diction['_id'])
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Annotation Mise à jour "
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
return True, 'La note a été mise à jour'
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de mettre à jour la note"
"""
Cette fontion permet de créer un avoir sur la facture.
On par d'annulation totale, donc pas partiel
Important : : On créer une souche spéciale pour les avoirs
apres la creation de l'avoir, on va ajouter sur la facture
la reference de l'avoir associé.
A l'annulation de la facture, si la facture est liée à un inscrit
sur une session, on aller remettre la session à 'non facture'
"""
def Create_Invoice_Avoir_Total(diction):
try:
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", False
"""
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 la liste des arguments ")
return False, " Les informations fournies sont incorrectes", False
"""
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, False
"""
Verifier que la facture est valide et s'assurer qu'il n'y pas un avoir (on est en mode avoir TOTAL).
Colonne : 'credit_note_ref'
"""
is_valide_invoice_cout = MYSY_GV.dbname['partner_invoice_header'].count_documents({'_id':ObjectId(str(diction['_id'])),
'partner_owner_recid':my_partner['recid'],
'valide':'1',
'locked':'0',
'credit_note_ref': {'$exists': False},
})
if( is_valide_invoice_cout <= 0 ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant de la facture est invalide ")
return False, " L'identifiant de la facture est invalide Ou le document a déjà une avoir ", False
# Récuperation de la sequence de l'objet "partner_credit_note" dans la collection : "mysy_sequence"
retval_sequence_credit_note = MYSY_GV.dbname['mysy_sequence'].find_one(
{'related_mysy_object': 'partner_credit_note',
'valide': '1', 'partner_owner_recid': str(
my_partner['recid'])})
if (retval_sequence_credit_note is None):
# Il n'y pas de sequence pour le partenaire, on va aller chercher la sequence par defaut
retval_sequence_credit_note = MYSY_GV.dbname['mysy_sequence'].find_one(
{'related_mysy_object': 'partner_credit_note',
'valide': '1', 'partner_owner_recid': 'default'})
if (retval_sequence_credit_note is None or "current_val" not in retval_sequence_credit_note.keys()):
# Il n'y aucune sequence meme par defaut.
mycommon.myprint(" Aucune sequence de type 'partner_credit_note' n'est configurée dans le système ")
return False, " Aucune sequence de type 'partner_credit_note' n'est configurée dans le système ", False
current_seq_value = str(retval_sequence_credit_note['current_val'])
new_sequence_value = int(mycommon.tryInt(current_seq_value)) + 1
new_sequance_data_to_update = {'current_val': new_sequence_value}
ret_val2 = MYSY_GV.dbname['mysy_sequence'].find_one_and_update(
{'_id': ObjectId(str(retval_sequence_credit_note['_id'])), 'valide': '1'},
{"$set": new_sequance_data_to_update},
return_document=ReturnDocument.AFTER,
upsert=False,
)
credit_notes_reference = retval_sequence_credit_note['prefixe'] + str(current_seq_value)
invoice_date_time = str(datetime.now().strftime("%d/%m/%Y"))
local_credit_note = None
liste_credit_node = []
for local_invoice in MYSY_GV.dbname['partner_invoice_header'].find({'_id':ObjectId(str(diction['_id'])),
'partner_owner_recid':my_partner['recid'],
'valide':'1',
'locked':'0'}):
local_credit_note = local_invoice
list_champs_a_inverser = ['total_header_hors_taxe_before_header_reduction', 'total_header_toutes_taxes',
'total_lines_hors_taxe_after_lines_reduction', 'total_lines_hors_taxe_before_lines_reduction', 'total_lines_montant_reduction']
for tmp in list_champs_a_inverser :
if( tmp in local_credit_note.keys() and local_credit_note[tmp] ):
inversed_tmp = mycommon.tryFloat(str(local_credit_note[tmp]).strip()) * (-1)
local_credit_note[tmp] = inversed_tmp
local_credit_note['invoice_header_origin'] = local_invoice['invoice_header_ref_interne']
local_credit_note['invoice_header_ref_interne'] = credit_notes_reference
local_credit_note['invoice_header_type'] = "avoir"
local_credit_note['invoice_date'] = invoice_date_time
local_credit_note['update_date'] = str(datetime.now())
local_credit_note['update_by'] = str(my_partner['_id'])
local_credit_note['partner_owner_recid'] = str(my_partner['recid'])
if( "_id" in local_credit_note.keys() ):
del local_credit_note['_id']
if( "e_document_signe_id" in local_credit_note.keys()):
del local_credit_note['e_document_signe_id']
"""
Insertion de l'avoir
"""
#print(" ### creadit note = ", local_credit_note)
"""
Verifier qu'il n'y pas dans la base un document avec le meme refrence
pour ce partenaire
"""
is_document_exist_count = MYSY_GV.dbname['partner_invoice_header'].count_documents({"invoice_header_ref_interne":credit_notes_reference,
"partner_owner_recid":my_partner['recid']})
if( is_document_exist_count > 0 ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " Il existe déjà un document avec la même reference : "+str(credit_notes_reference))
return False, " Il existe déjà un document avec la même reference : "+str(credit_notes_reference), False
inserted_id = MYSY_GV.dbname['partner_invoice_header'].insert_one(local_credit_note).inserted_id
if (not inserted_id):
mycommon.myprint(
" Impossible de créer l'avoir (2) ")
return False, "Impossible de créer l'avoir (2) "
liste_credit_node.append(credit_notes_reference)
invoice_header_inserted_id = inserted_id
"""
Mettre à jour la facture avec la reference de l'avoir
"""
result = MYSY_GV.dbname['partner_invoice_header'].find_one_and_update(
{'_id': ObjectId(str(diction['_id'])),
'partner_owner_recid': my_partner['recid'],
'valide': '1',
'locked': '0'},
{"$set": {"credit_note_ref":credit_notes_reference}},
upsert=False,
return_document=ReturnDocument.AFTER
)
"""
On a finit de créer l'entete, on va aller créer les lignes, partner_invoice_line
"""
for local_invoice_line in MYSY_GV.dbname['partner_invoice_line'].find({'invoice_header_id': str(diction['_id']),
'partner_owner_recid': my_partner['recid'],
'valide': '1',
'locked': '0'}):
local_credit_note_line = local_invoice_line
list_champs_a_inverser = ['order_line_qty', 'order_line_tax_amount',
'order_line_montant_toutes_taxes',
'order_line_montant_hors_taxes',
]
for tmp in list_champs_a_inverser:
if (tmp in local_credit_note_line.keys() and local_credit_note_line[tmp]):
inversed_tmp = mycommon.tryFloat(str(local_credit_note_line[tmp]).strip()) * (-1)
local_credit_note_line[tmp] = str(inversed_tmp)
local_credit_note_line['invoice_header_ref_interne_origin'] = local_invoice['invoice_header_ref_interne']
local_credit_note_line['invoice_header_ref_interne'] = credit_notes_reference
local_credit_note_line['invoice_header_id'] = str(invoice_header_inserted_id)
local_credit_note_line['invoice_line_type'] = "avoir"
local_credit_note_line['invoice_date'] = invoice_date_time
local_credit_note_line['update_date'] = str(datetime.now())
local_credit_note_line['update_by'] = str(my_partner['_id'])
local_credit_note_line['partner_owner_recid'] = str(my_partner['recid'])
if ("_id" in local_credit_note_line.keys()):
del local_credit_note_line['_id']
inserted_id = MYSY_GV.dbname['partner_invoice_line'].insert_one(local_credit_note_line).inserted_id
if (not inserted_id):
mycommon.myprint( " WARNING : Impossible d'inserer la ligne d'avoir pour l'avoir "+str(credit_notes_reference))
"""
On a finit de créer l'entete, on va aller créer les lignes: partner_invoice_line_detail
"""
for local_invoice_line_detail in MYSY_GV.dbname['partner_invoice_line_detail'].find({'invoice_header_id': str(diction['_id']),
'partner_owner_recid': my_partner[
'recid'],
'valide': '1',
'locked': '0'}):
local_credit_note_line_detail = local_invoice_line_detail
list_champs_a_inverser = ['order_line_qty', 'order_line_montant_hors_taxes',
'order_line_invoiced_amount',
]
for tmp in list_champs_a_inverser:
if (tmp in local_credit_note_line_detail.keys() and local_credit_note_line_detail[tmp]):
inversed_tmp = mycommon.tryFloat(str(local_credit_note_line_detail[tmp]).strip()) * (-1)
local_credit_note_line_detail[tmp] = str(inversed_tmp)
local_credit_note_line_detail['invoice_header_ref_interne_origin'] = local_invoice['invoice_header_ref_interne']
local_credit_note_line_detail['invoice_header_ref_interne'] = credit_notes_reference
local_credit_note_line_detail['invoice_header_id'] = str(invoice_header_inserted_id)
local_credit_note_line_detail['invoice_line_type'] = "avoir"
local_credit_note_line_detail['invoice_date'] = invoice_date_time
local_credit_note_line_detail['update_date'] = str(datetime.now())
local_credit_note_line_detail['update_by'] = str(my_partner['_id'])
local_credit_note_line_detail['partner_owner_recid'] = str(my_partner['recid'])
if ("_id" in local_credit_note_line_detail.keys()):
del local_credit_note_line_detail['_id']
inserted_id = MYSY_GV.dbname['partner_invoice_line_detail'].insert_one(local_credit_note_line_detail).inserted_id
if (not inserted_id):
mycommon.myprint(
" WARNING : Impossible d'inserer la ligne d'avoir pour l'avoir " + str(credit_notes_reference))
"""
Apres avoir créer l'avoir, il faut aller voir s'il la facture est liée à une inscription
si c'est le cas, on remettre le statut de ligne d'inscription à non-facture (invoiced).
mais on laisse volontaire la ref de facture, on l'efface pas la ref de la facture.
on va juste ajouter l'avoir
"""
is_valide_invoice_data = MYSY_GV.dbname['partner_invoice_header'].find_one({'_id':ObjectId(str(diction['_id'])),
'partner_owner_recid':my_partner['recid'],
'valide':'1',
'locked':'0', }, {'invoice_header_ref_interne':1})
inscription_data = MYSY_GV.dbname['inscription'].find_one({'invoiced_ref': {'$regex': str(is_valide_invoice_data['invoice_header_ref_interne'])},
'valide':'1',
'partner_owner_recid':str(my_partner['recid'])})
if(inscription_data ):
current_invoiced_ref = ""
local_invoiced = ""
if( "invoiced_ref" in inscription_data.keys() ):
current_invoiced_ref = inscription_data['invoiced_ref']
if ("invoiced" in inscription_data.keys()):
local_invoiced = inscription_data['invoiced']
new_data = {}
new_data['invoiced_ref'] = current_invoiced_ref+", "+str(credit_notes_reference)
new_data['invoiced'] = "0"
print( {'_id': ObjectId(str(inscription_data['_id'])), 'valide': '1',
'partner_owner_recid': str(my_partner['recid'])
} )
ret_val2 = MYSY_GV.dbname['inscription'].find_one_and_update(
{'_id': ObjectId(str(inscription_data['_id'])), 'valide': '1',
'partner_owner_recid': str(my_partner['recid'])
},
{"$set": new_data},
return_document=ReturnDocument.AFTER,
upsert=False,
)
#icici : on met à jour la staturation de la session (si elle est partiel ou non facturer)
nb_line_inscritpion_invoiced = MYSY_GV.dbname['inscription'].count_documents(
{'session_id': str(ret_val2['session_id']), 'valide': '1',
'partner_owner_recid': str(my_partner['recid']),
'invoiced':'1'
})
if( nb_line_inscritpion_invoiced > 0 ):
# On au moins un ligne qui est facturé, alors on mets la session à :"facturation" partielle
session_update = MYSY_GV.dbname['session_formation'].find_one_and_update(
{'_id': ObjectId(str(ret_val2['session_id'])),
'partner_owner_recid': str(my_partner['recid'])
},
{"$set": {'invoiced_statut':'1'}},
return_document=ReturnDocument.AFTER,
upsert=False,
)
else:
# Aucune ligne d'inscription n'est facturée, alors on mets la session à :"facturation" NOOO
session_update = MYSY_GV.dbname['session_formation'].find_one_and_update(
{'_id': ObjectId(str(ret_val2['session_id'])),
'partner_owner_recid': str(my_partner['recid'])
},
{"$set": {'invoiced_statut': '0'}},
return_document=ReturnDocument.AFTER,
upsert=False,
)
"""
Creation des log historique pour :
- la facture et
- l'avoir
"""
## Add to log history pour l'annulation de l'avoir
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = str(token)
history_event_dict['related_collection'] = "partner_invoice_header"
history_event_dict['related_collection_recid'] = str(diction['_id'])
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Avoir : annulation facture. Ref Avoir : '"+str(credit_notes_reference)+"' "
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
## Add to log history pour l'avoir (nouveau document)
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = str(token)
history_event_dict['related_collection'] = "partner_invoice_header"
history_event_dict['related_collection_recid'] = str(invoice_header_inserted_id)
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Creation Avoir "
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
return True, "L'avoir a été créé avec la référence "+str(liste_credit_node), liste_credit_node
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 l'avoir ", False
"""
Cette fonction permet de créer une facture depuis l'ecran des factures
"""
def Add_Partner_Draft_Invoice(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', "order_header_client_id", "order_header_ref_interne", "order_header_email_client", "order_header_origin",
"order_header_condition_paiement_id",
"order_header_ref_client", "order_header_vendeur_id", "order_header_date_cmd",
"order_header_date_expiration", "order_header_adr_fact_adresse", "order_header_adr_fact_code_postal",
"order_header_adr_fact_ville", "order_header_adr_fact_pays", "order_header_adr_liv_adresse",
"order_header_adr_liv_code_postal", "order_header_adr_liv_ville", "order_header_adr_liv_pays",
"order_header_montant_reduction", "order_header_tax", "order_header_tax_amount",
"total_header_hors_taxe_after_header_reduction", "total_header_hors_taxe_before_header_reduction",
"total_header_toutes_taxes", "total_lines_hors_taxe_after_lines_reduction",
"total_lines_hors_taxe_before_lines_reduction", "total_lines_montant_reduction", "invoice_header_ref_interne",
"invoice_header_type", "invoice_date", "invoice_date_echeance",
"order_header_condition_paiement_code", "order_header_condition_paiement_description",
"order_header_type_client_id", "order_header_type_financeur_id", "order_header_is_financeur",
"order_header_is_client", "order_header_is_fournisseur", "order_header_is_company",
"order_header_type_pouvoir_public_id", "order_header_is_include_bpf", "order_header_comment",
"invoice_lines", "order_header_description", "invoice_header_comment", "order_header_lieu_formation",
"order_header_condition_paiement_id", "order_header_inclus_bpf", "invoice_header_description"]
"""
Important : A noter que "invoice_lines" est tableau [] qui peut contenir les keys suivantes : 'order_line_formation', 'order_line_qty', 'order_line_prix_unitaire', 'order_line_tax', 'order_line_type_reduction', 'order_line_type_valeur', 'order_line_montant_reduction'
ainsi, invoice_lines sera du style invoice_lines[ {order_line_formation:'xxx', order_line_qty:'2', etc }, {order_line_formation:'yyy', order_line_qty:'7', etc }, ....{}}
"""
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", False
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', "order_header_client_id", "order_header_date_cmd"]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
return False, " Les informations fournies sont incorrectes", False
"""
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, False
# Recuperation des champs
data = {}
# Initialisation des champs non envoyés à vide
for val in field_list:
if val not in diction.keys():
data[str(val)] = ""
data['partner_owner_recid'] = my_partner['recid']
data['invoice_header_type'] = "brouillon"
order_header_client_id = ""
if ("order_header_client_id" in diction.keys()):
if diction['order_header_client_id']:
order_header_client_id = diction['order_header_client_id']
# Verifier que le client existe bien pour ce partner
is_client_exist_count = MYSY_GV.dbname['partner_client'].count_documents(
{'_id': ObjectId(str(order_header_client_id)), 'valide': '1',
'locked': '0', 'partner_owner_recid': str(my_partner['recid'])})
if (is_client_exist_count != 1):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Le client est invalide ")
return False, " - Le client est invalide ", False
data['order_header_client_id'] = diction['order_header_client_id']
is_client_data = MYSY_GV.dbname['partner_client'].find_one(
{'_id': ObjectId(str(order_header_client_id)), 'valide': '1',
'locked': '0', 'partner_owner_recid': str(my_partner['recid'])})
data['order_header_email_client'] = is_client_data['email']
data['order_header_adr_fact_adresse'] = is_client_data['invoice_adresse']
data['order_header_adr_fact_code_postal'] = is_client_data['invoice_code_postal']
data['order_header_adr_fact_ville'] = is_client_data['invoice_ville']
data['order_header_adr_fact_pays'] = is_client_data['invoice_pays']
data['order_header_adr_liv_adresse'] = is_client_data['adr_adresse']
data['order_header_adr_liv_code_postal'] = is_client_data['adr_code_postal']
data['order_header_adr_liv_ville'] = is_client_data['adr_ville']
data['order_header_adr_liv_pays'] = is_client_data['adr_pays']
data['order_header_condition_paiement_id'] = is_client_data['invoice_condition_paiement_id']
invoice_header_description = ""
if ("order_header_description" in diction.keys()):
if diction['order_header_description']:
invoice_header_description = diction['order_header_description']
if (len(str(invoice_header_description)) > 500):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_description' fait plus de 500 caractères ")
return False, " - Le champ 'Description' fait plus de 500 caractères ", False
data['order_header_description'] = diction['order_header_description']
order_header_comment = ""
if ("order_header_comment" in diction.keys()):
if diction['order_header_comment']:
order_header_comment = diction['order_header_comment']
if (len(str(order_header_comment)) > 500):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_comment' fait plus de 500 caractères ")
return False, " - Le champ 'Commentaire' fait plus de 500 caractères ", False
data['order_header_comment'] = diction['order_header_comment']
invoice_header_comment = ""
if ("invoice_header_comment" in diction.keys()):
if diction['invoice_header_comment']:
invoice_header_comment = diction['invoice_header_comment']
if (len(str(invoice_header_comment)) > 500):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'invoice_header_comment' fait plus de 500 caractères ")
return False, " - Le champ 'Commentaire' fait plus de 500 caractères ", False
data['invoice_header_comment'] = diction['invoice_header_comment']
order_header_lieu_formation = ""
if ("order_header_lieu_formation" in diction.keys()):
if diction['order_header_lieu_formation']:
invoice_header_lieu_formation = diction['order_header_lieu_formation']
if (len(str(order_header_lieu_formation)) > 1000):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_lieu_formation' fait plus de 500 caractères ")
return False, " - Le champ 'Lieu de formation' fait plus de 1000 caractères ", False
data['order_header_lieu_formation'] = diction['order_header_lieu_formation']
order_header_condition_paiement_id = ""
if ("order_header_condition_paiement_id" in diction.keys()):
if diction['order_header_condition_paiement_id']:
order_header_condition_paiement_id = diction['order_header_condition_paiement_id']
if (len(str(order_header_condition_paiement_id)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_condition_paiement_id' fait plus de 255 caractères ")
return False, " - Le champ 'Condition de paiement' fait plus de 255 caractères ", False
data['order_header_condition_paiement_id'] = order_header_condition_paiement_id
order_header_condition_paiement_code = ""
if ("order_header_condition_paiement_code" in diction.keys()):
if diction['order_header_condition_paiement_code']:
order_header_condition_paiement_code = diction['order_header_condition_paiement_code']
if (len(str(order_header_condition_paiement_code)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_condition_paiement_code' fait plus de 255 caractères ")
return False, " - Le champ 'Condition de paiement' fait plus de 255 caractères ", False
data['order_header_condition_paiement_code'] = order_header_condition_paiement_code
order_header_inclus_bpf = ""
if ("order_header_inclus_bpf" in diction.keys()):
if diction['order_header_inclus_bpf']:
order_header_inclus_bpf = str(diction['order_header_inclus_bpf']).strip()
if (order_header_inclus_bpf not in ['0', '1', '']):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'inclus BPF' n'est pas valide ")
return False, " -Le champ 'inclus BPF' n'est pas valide ", False
data['order_header_inclus_bpf'] = order_header_inclus_bpf
order_header_ref_client = ""
if ("order_header_ref_client" in diction.keys()):
if diction['order_header_ref_client']:
order_header_ref_client = diction['order_header_ref_client']
if (len(str(order_header_ref_client)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_ref_client' fait plus de 255 caractères ")
return False, " - Le champ 'ref_externe' fait plus de 255 caractères ", False
data['order_header_ref_client'] = diction['order_header_ref_client']
order_header_date_cmd = ""
if ("order_header_date_cmd" in diction.keys()):
if diction['order_header_date_cmd']:
order_header_date_cmd = str(diction['order_header_date_cmd'])[0:10]
local_status = mycommon.CheckisDate(order_header_date_cmd)
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La date order_header_date_cmd n'est pas au format 'jj/mm/aaaa' ")
return False, "La date d'ordre n'est pas au format 'jj/mm/aaaa'", False
data['order_header_date_cmd'] = str(diction['order_header_date_cmd'])[0:10]
else:
# par defaut la date de la commande est la date du jour
data['order_header_date_cmd'] = datetime.today().strftime("%d/%m/%Y")
else:
data['order_header_date_cmd'] = datetime.today().strftime("%d/%m/%Y")
## Recuperation de l'adresse de facturation
if ("order_header_adr_fact_adresse" in diction.keys()):
if diction['order_header_adr_fact_adresse']:
order_header_adr_fact_adresse = diction['order_header_adr_fact_adresse']
if (len(str(order_header_adr_fact_adresse)) > 500):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_fact_adresse' fait plus de 500 caractères ")
return False, " - Le champ 'adresse de facturation' fait plus de 500 caractères ", False
data['order_header_adr_fact_adresse'] = diction['order_header_adr_fact_adresse']
order_header_adr_fact_code_postal = ""
if ("order_header_adr_fact_code_postal" in diction.keys()):
if diction['order_header_adr_fact_code_postal']:
order_header_adr_fact_code_postal = diction['order_header_adr_fact_code_postal']
if (len(str(order_header_adr_fact_code_postal)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_fact_code_postal' fait plus de 255 caractères ")
return False, " - Le champ 'order_header_adr_fact_code_postal' fait plus de 255 caractères ", False
data['order_header_adr_fact_code_postal'] = diction['order_header_adr_fact_code_postal']
order_header_adr_fact_ville = ""
if ("order_header_adr_fact_ville" in diction.keys()):
if diction['order_header_adr_fact_ville']:
order_header_adr_fact_ville = diction['order_header_adr_fact_ville']
if (len(str(order_header_adr_fact_ville)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_fact_ville' fait plus de 255 caractères ")
return False, " - Le champ 'order_header_adr_fact_ville' fait plus de 255 caractères ", False
data['order_header_adr_fact_ville'] = diction['order_header_adr_fact_ville']
order_header_adr_fact_pays = ""
if ("order_header_adr_fact_pays" in diction.keys()):
if diction['order_header_adr_fact_pays']:
order_header_adr_fact_pays = diction['order_header_adr_fact_pays']
if (len(str(order_header_adr_fact_pays)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_fact_pays' fait plus de 255 caractères ")
return False, " - Le champ 'order_header_adr_fact_pays' fait plus de 255 caractères ", False
data['order_header_adr_fact_pays'] = diction['order_header_adr_fact_pays']
## Recuperation de l'adresse d'exécution de la formation
order_header_adr_liv_adresse = ""
if ("order_header_adr_liv_adresse" in diction.keys()):
if diction['order_header_adr_liv_adresse']:
order_header_adr_liv_adresse = diction['order_header_adr_liv_adresse']
if (len(str(order_header_adr_liv_adresse)) > 500):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_liv_adresse' fait plus de 500 caractères ")
return False, " - Le champ 'order_header_adr_liv_adresse' fait plus de 500 caractères ", False
data['order_header_adr_liv_adresse'] = diction['order_header_adr_liv_adresse']
order_header_adr_liv_code_postal = ""
if ("order_header_adr_liv_code_postal" in diction.keys()):
if diction['order_header_adr_liv_code_postal']:
order_header_adr_liv_code_postal = diction['order_header_adr_liv_code_postal']
if (len(str(order_header_adr_liv_code_postal)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_liv_code_postal' fait plus de 255 caractères ")
return False, " - Le champ 'order_header_adr_liv_code_postal' fait plus de 255 caractères ", False
data['order_header_adr_liv_code_postal'] = diction['order_header_adr_liv_code_postal']
order_header_adr_liv_ville = ""
if ("order_header_adr_liv_ville" in diction.keys()):
if diction['order_header_adr_liv_ville']:
order_header_adr_liv_ville = diction['order_header_adr_liv_ville']
if (len(str(order_header_adr_liv_ville)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_liv_ville' fait plus de 255 caractères ")
return False, " - Le champ 'order_header_adr_liv_ville' fait plus de 255 caractères ", False
data['order_header_adr_liv_ville'] = diction['order_header_adr_liv_ville']
order_header_adr_liv_pays = ""
if ("order_header_adr_liv_pays" in diction.keys()):
if diction['order_header_adr_liv_pays']:
order_header_adr_liv_pays = diction['order_header_adr_liv_pays']
if (len(str(order_header_adr_liv_pays)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_liv_pays' fait plus de 255 caractères ")
return False, " - Le champ 'order_header_adr_liv_pays' fait plus de 255 caractères ", False
data['order_header_adr_liv_pays'] = diction['order_header_adr_liv_pays']
if ("invoice_date" in diction.keys() and diction['invoice_date']):
invoice_date = str(diction['invoice_date'])[0:10]
local_status = mycommon.CheckisDate(invoice_date)
if (local_status is False):
mycommon.myprint(str(
inspect.stack()[0][3]) + " La date de facturation n'est pas au format jj/mm/aaaa.")
return False, "La date de facturation n'est pas au format jj/mm/aaaa."
data['invoice_date'] = diction['invoice_date']
else:
invoice_date_time = str(datetime.now().strftime("%d/%m/%Y"))
data['invoice_date'] = invoice_date_time
"""
Recuperation des lignes de commande
"""
data_invoice_lines = []
if ("invoice_lines" in diction.keys()):
# JSON.loads prends les variable entre double quote. on va donc remplacer les eventuels simple quote par des doubles quotes
data_invoice_lines = json.loads(str(diction['invoice_lines']).replace("'", '"'))
for order_line in data_invoice_lines:
# Verifier les champs acceptés et champs obligatoires pour une ligne de commande
"""
Verification des input acceptés
"""
field_list = ['order_line_formation', 'order_line_qty', 'order_line_prix_unitaire',
'order_line_tax', 'order_line_type_reduction', 'order_line_type_valeur',
'order_line_montant_reduction']
print(" ### order_line = ", order_line)
incom_keys = order_line.keys()
for val in incom_keys:
if val not in field_list:
mycommon.myprint(str(
inspect.stack()[0][3]) + " Line de commande : Le champ '" + val + "' n'est pas autorisé")
return False, " Line de commande : Les informations fournies sont incorrectes", False
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['order_line_formation', "order_line_qty", "order_line_prix_unitaire"]
for val in field_list_obligatoire:
if val not in order_line:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Line de commande : La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
return False, " Line de commande : Les informations fournies sont incorrectes", False
"""
Important : : A present que tous les controles sont ok, on va proceder à la creation dans les table.
"""
### 1 - Creation de l'entete
"""
Important : Update du 24/09/2023 :
Si on ne trouve pas une sequence propre au partenaire (partner_owner_recid), alors on va chercher
la sequence par defaut dont partner_owner_recid = 'default'
"""
# Rcuperation de la sequence de l'objet "partner_order_header" dans la collection : "mysy_sequence"
retval_sequence_order = MYSY_GV.dbname['mysy_sequence'].find_one({'related_mysy_object': 'partner_draft_invoice_header',
'valide': '1', 'partner_owner_recid': str(
my_partner['recid'])})
if (retval_sequence_order is None):
# Il n'y pas de sequence pour le partenaire, on va aller chercher la sequence par defaut
retval_sequence_order = MYSY_GV.dbname['mysy_sequence'].find_one(
{'related_mysy_object': 'partner_draft_invoice_header',
'valide': '1', 'partner_owner_recid': 'default'})
if (retval_sequence_order is None or "current_val" not in retval_sequence_order.keys()):
# Il n'y aucune sequence meme par defaut.
mycommon.myprint(" Impossible de récupérer la sequence 'partner_draft_invoice_header' ")
return False, "Impossible de récupérer la sequence 'partner_draft_invoice_header'", False
current_seq_value = str(retval_sequence_order['current_val'])
new_sequence_value = int(mycommon.tryInt(current_seq_value)) + 1
# Important : Affectation de la reference interne de la commande
data['invoice_header_ref_interne'] = retval_sequence_order['prefixe'] + str(current_seq_value)
print(" #### diction['invoice_header_ref_interne'] = ", str(data['invoice_header_ref_interne']))
## Verifier qu'il n'y pas une facture avec la meme reference interne
existe_invoice_ref_interne_count = MYSY_GV.dbname['partner_order_header'].count_documents(
{'invoice_header_ref_interne': str(data['invoice_header_ref_interne'])})
if (existe_invoice_ref_interne_count > 0):
mycommon.myprint(
" Il existe déjà une facture avec la même reference interne " + str(data['invoice_header_ref_interne']))
return False, " Il existe déjà une facture avec la même reference interne " + str(
data['invoice_header_ref_interne']) + " ", False
now = str(datetime.now())
data['valide'] = '1'
data['locked'] = '0'
data['status'] = '0'
data['creation_by'] = str(my_partner['_id'])
data['creation_date'] = now
print(" ### add_partner_order data = ", data)
inserted_id = ""
inserted_id = MYSY_GV.dbname['partner_invoice_header'].insert_one(data).inserted_id
if (not inserted_id):
mycommon.myprint(
" Impossible de créer l'entête de la facture ")
return False, "Impossible de créer l'entête de la facture ", False
new_sequance_data_to_update = {'current_val': new_sequence_value}
ret_val2 = MYSY_GV.dbname['mysy_sequence'].find_one_and_update(
{'_id': ObjectId(str(retval_sequence_order['_id'])), 'valide': '1'},
{"$set": new_sequance_data_to_update},
return_document=ReturnDocument.AFTER,
upsert=False,
)
tmp_val = str(inserted_id)
print(" ### inserted_id = ", str(tmp_val))
### 2 - Creation des lignes
data_invoice_lines = []
if ("invoice_lines" in diction.keys()):
# JSON.loads prends les variable entre double quote. on va donc remplacer les eventuels simple quote par des doubles quotes
data_invoice_lines = json.loads(str(diction['invoice_lines']).replace("'", '"'))
for order_line in data_invoice_lines:
order_line['invoice_header_id'] = str(tmp_val)
order_line['invoice_header_ref_interne'] = str(data['invoice_header_ref_interne'])
order_line['valide'] = '1'
order_line['locked'] = '0'
order_line['update_date'] = str(datetime.now())
order_line['partner_owner_recid'] = my_partner['recid']
order_line['order_line_type'] = "facture"
order_line['order_line_status'] = data['invoice_header_status']
order_line['creation_by'] = str(my_partner['_id'])
order_line['creation_date'] = now
inserted_line_id = ""
inserted_line_id = MYSY_GV.dbname['partner_invoice_line'].insert_one(order_line).inserted_id
if (not inserted_line_id):
mycommon.myprint(
" Impossible de créer la ligne la facture ")
return False, " Impossible de créer la ligne la facture ", False
# Gestion de l'historique
# pour la collection 'partner_order_header'
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
# print(" ####### laaaa diction = ", diction)
history_event_dict = {}
history_event_dict['token'] = token
history_event_dict['related_collection'] = "partner_invoice_header"
history_event_dict['related_collection_recid'] = str(tmp_val)
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Creation "
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(
history_event_dict))
return True, " La facture a été correctement créée", str(data['invoice_header_ref_interne'])
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de créer la facture ", False
"""
Cette fonction met à jour une facture
/!\ ceci tant qu'elle est au statut 'draft'
"""
def Update_Partner_Draft_Invoice(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = field_list = ['token', "order_header_client_id", "order_header_ref_interne", "order_header_email_client", "order_header_origin",
"order_header_condition_paiement_id",
"order_header_ref_client", "order_header_vendeur_id", "order_header_date_cmd",
"order_header_date_expiration", "order_header_adr_fact_adresse", "order_header_adr_fact_code_postal",
"order_header_adr_fact_ville", "order_header_adr_fact_pays", "order_header_adr_liv_adresse",
"order_header_adr_liv_code_postal", "order_header_adr_liv_ville", "order_header_adr_liv_pays",
"order_header_montant_reduction", "order_header_tax", "order_header_tax_amount",
"total_header_hors_taxe_after_header_reduction", "total_header_hors_taxe_before_header_reduction",
"total_header_toutes_taxes", "total_lines_hors_taxe_after_lines_reduction",
"total_lines_hors_taxe_before_lines_reduction", "total_lines_montant_reduction", "invoice_header_ref_interne",
"invoice_header_type", "invoice_date", "invoice_date_echeance",
"order_header_condition_paiement_code", "order_header_condition_paiement_description",
"order_header_type_client_id", "order_header_type_financeur_id", "order_header_is_financeur",
"order_header_is_client", "order_header_is_fournisseur", "order_header_is_company",
"order_header_type_pouvoir_public_id", "order_header_is_include_bpf", "order_header_comment",
"invoice_lines", "order_header_description", "invoice_header_comment", "order_header_lieu_formation",
"order_header_inclus_bpf", "invoice_header_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', "order_header_client_id", 'invoice_header_id', 'invoice_header_ref_interne',
'invoice_header_type']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
return False, " 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
invoice_header_id = ""
if ("invoice_header_id" in diction.keys()):
if diction['invoice_header_id']:
invoice_header_id = diction['invoice_header_id']
"""
# Verifier que la commande existe et qu'elle est modifiable.
Pour les ligne, on fait pareil, on ne peut modifier que celles qui sont modifiable.
Conditions pour modifier entete :
1 - statut est : 0 => Brouillon
Pour un debut pas de facturation partielle. c'est tout ou rien.
"""
my_invoice_data_count = MYSY_GV.dbname['partner_invoice_header'].count_documents(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'status': '0',
'_id': ObjectId(str(invoice_header_id))})
if (my_invoice_data_count != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - L'identifiant de la facture est invalide ")
return False, " L'identifiant de la facture est invalide",
"""
Recuperation et stockage des données de l'entete avant mise à jour
"""
my_invoice_data_previous_information = MYSY_GV.dbname['partner_invoice_header'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'status': '0',
'_id': ObjectId(str(invoice_header_id))})
# Recuperation des champs
data = {}
data['partner_owner_recid'] = my_partner['recid']
order_header_client_id = ""
if ("order_header_client_id" in diction.keys()):
if diction['order_header_client_id']:
order_header_client_id = diction['order_header_client_id']
# Verifier que le client existe bien pour ce partner
is_client_exist_count = MYSY_GV.dbname['partner_client'].count_documents(
{'_id': ObjectId(str(order_header_client_id)), 'valide': '1',
'locked': '0', 'partner_owner_recid': str(my_partner['recid'])})
if (is_client_exist_count != 1):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Le client est invalide ")
return False, " - Le client est invalide ", False
data['order_header_client_id'] = diction['order_header_client_id']
is_client_data = MYSY_GV.dbname['partner_client'].find_one(
{'_id': ObjectId(str(order_header_client_id)), 'valide': '1',
'locked': '0', 'partner_owner_recid': str(my_partner['recid'])})
data['order_header_email_client'] = is_client_data['email']
data['order_header_adr_fact_adresse'] = is_client_data['invoice_adresse']
data['order_header_adr_fact_code_postal'] = is_client_data['invoice_code_postal']
data['order_header_adr_fact_ville'] = is_client_data['invoice_ville']
data['order_header_adr_fact_pays'] = is_client_data['invoice_pays']
data['order_header_adr_liv_adresse'] = is_client_data['adr_adresse']
data['order_header_adr_liv_code_postal'] = is_client_data['adr_code_postal']
data['order_header_adr_liv_ville'] = is_client_data['adr_ville']
data['order_header_adr_liv_pays'] = is_client_data['adr_pays']
data['order_header_condition_paiement_id'] = is_client_data['invoice_condition_paiement_id']
invoice_header_description = ""
if ("order_header_description" in diction.keys()):
if diction['order_header_description']:
invoice_header_description = diction['order_header_description']
if (len(str(invoice_header_description)) > 500):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_description' fait plus de 500 caractères ")
return False, " - Le champ 'Description' fait plus de 500 caractères ", False
data['order_header_description'] = diction['order_header_description']
order_header_comment = ""
if ("order_header_comment" in diction.keys()):
if diction['order_header_comment']:
order_header_comment = diction['order_header_comment']
if (len(str(invoice_header_description)) > 500):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_comment' fait plus de 500 caractères ")
return False, " - Le champ 'Commentaire' fait plus de 500 caractères ", False
data['order_header_comment'] = diction['order_header_comment']
invoice_header_comment = ""
if ("invoice_header_comment" in diction.keys()):
if diction['invoice_header_comment']:
invoice_header_comment = diction['invoice_header_comment']
if (len(str(invoice_header_comment)) > 500):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'invoice_header_comment' fait plus de 500 caractères ")
return False, " - Le champ 'Commentaire' fait plus de 500 caractères ", False
data['invoice_header_comment'] = diction['invoice_header_comment']
order_header_lieu_formation = ""
if ("order_header_lieu_formation" in diction.keys()):
if diction['order_header_lieu_formation']:
invoice_header_lieu_formation = diction['order_header_lieu_formation']
if (len(str(order_header_lieu_formation)) > 1000):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_lieu_formation' fait plus de 500 caractères ")
return False, " - Le champ 'Lieu de formation' fait plus de 1000 caractères ", False
data['order_header_lieu_formation'] = diction['order_header_lieu_formation']
order_header_condition_paiement_id = ""
if ("order_header_condition_paiement_id" in diction.keys()):
if diction['order_header_condition_paiement_id']:
order_header_condition_paiement_id = diction['order_header_condition_paiement_id']
if (len(str(order_header_condition_paiement_id)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_condition_paiement_id' fait plus de 255 caractères ")
return False, " - Le champ 'Condition de paiement' fait plus de 255 caractères ", False
data['order_header_condition_paiement_id'] = order_header_condition_paiement_id
print("### data['order_header_condition_paiement_id'] = ", data['order_header_condition_paiement_id'])
order_header_condition_paiement_code = ""
if ("order_header_condition_paiement_code" in diction.keys()):
if diction['order_header_condition_paiement_code']:
order_header_condition_paiement_code = diction['order_header_condition_paiement_code']
if (len(str(order_header_condition_paiement_code)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_condition_paiement_code' fait plus de 255 caractères ")
return False, " - Le champ 'Condition de paiement' fait plus de 255 caractères ", False
data['order_header_condition_paiement_code'] = order_header_condition_paiement_code
print("### data['order_header_condition_paiement_code'] = ", data['order_header_condition_paiement_code'])
order_header_inclus_bpf = ""
if ("order_header_inclus_bpf" in diction.keys()):
if diction['order_header_inclus_bpf']:
order_header_inclus_bpf = str(diction['order_header_inclus_bpf']).strip()
if (order_header_inclus_bpf not in ['0', '1', '']):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'inclus BPF' n'est pas valide ")
return False, " -Le champ 'inclus BPF' n'est pas valide ", False
data['order_header_inclus_bpf'] = order_header_inclus_bpf
order_header_ref_client = ""
if ("order_header_ref_client" in diction.keys()):
if diction['order_header_ref_client']:
order_header_ref_client = diction['order_header_ref_client']
if (len(str(order_header_ref_client)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_ref_client' fait plus de 255 caractères ")
return False, " - Le champ 'ref_externe' fait plus de 255 caractères ", False
data['order_header_ref_client'] = diction['order_header_ref_client']
order_header_date_cmd = ""
if ("order_header_date_cmd" in diction.keys()):
if diction['order_header_date_cmd']:
order_header_date_cmd = str(diction['order_header_date_cmd'])[0:10]
local_status = mycommon.CheckisDate(order_header_date_cmd)
if (local_status is False):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " La date order_header_date_cmd n'est pas au format 'jj/mm/aaaa' ")
return False, "La date d'ordre n'est pas au format 'jj/mm/aaaa'", False
data['order_header_date_cmd'] = str(diction['order_header_date_cmd'])[0:10]
else:
# par defaut la date de la commande est la date du jour
data['order_header_date_cmd'] = datetime.today().strftime("%d/%m/%Y")
else:
data['order_header_date_cmd'] = datetime.today().strftime("%d/%m/%Y")
## Recuperation de l'adresse de facturation
if ("order_header_adr_fact_adresse" in diction.keys()):
if diction['order_header_adr_fact_adresse']:
order_header_adr_fact_adresse = diction['order_header_adr_fact_adresse']
if (len(str(order_header_adr_fact_adresse)) > 500):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_fact_adresse' fait plus de 500 caractères ")
return False, " - Le champ 'adresse de facturation' fait plus de 500 caractères ", False
data['order_header_adr_fact_adresse'] = diction['order_header_adr_fact_adresse']
order_header_adr_fact_code_postal = ""
if ("order_header_adr_fact_code_postal" in diction.keys()):
if diction['order_header_adr_fact_code_postal']:
order_header_adr_fact_code_postal = diction['order_header_adr_fact_code_postal']
if (len(str(order_header_adr_fact_code_postal)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_fact_code_postal' fait plus de 255 caractères ")
return False, " - Le champ 'order_header_adr_fact_code_postal' fait plus de 255 caractères ", False
data['order_header_adr_fact_code_postal'] = diction['order_header_adr_fact_code_postal']
order_header_adr_fact_ville = ""
if ("order_header_adr_fact_ville" in diction.keys()):
if diction['order_header_adr_fact_ville']:
order_header_adr_fact_ville = diction['order_header_adr_fact_ville']
if (len(str(order_header_adr_fact_ville)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_fact_ville' fait plus de 255 caractères ")
return False, " - Le champ 'order_header_adr_fact_ville' fait plus de 255 caractères ", False
data['order_header_adr_fact_ville'] = diction['order_header_adr_fact_ville']
order_header_adr_fact_pays = ""
if ("order_header_adr_fact_pays" in diction.keys()):
if diction['order_header_adr_fact_pays']:
order_header_adr_fact_pays = diction['order_header_adr_fact_pays']
if (len(str(order_header_adr_fact_pays)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_fact_pays' fait plus de 255 caractères ")
return False, " - Le champ 'order_header_adr_fact_pays' fait plus de 255 caractères ", False
data['order_header_adr_fact_pays'] = diction['order_header_adr_fact_pays']
## Recuperation de l'adresse d'exécution de la formation
order_header_adr_liv_adresse = ""
if ("order_header_adr_liv_adresse" in diction.keys()):
if diction['order_header_adr_liv_adresse']:
order_header_adr_liv_adresse = diction['order_header_adr_liv_adresse']
if (len(str(order_header_adr_liv_adresse)) > 500):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_liv_adresse' fait plus de 500 caractères ")
return False, " - Le champ 'order_header_adr_liv_adresse' fait plus de 500 caractères ", False
data['order_header_adr_liv_adresse'] = diction['order_header_adr_liv_adresse']
order_header_adr_liv_code_postal = ""
if ("order_header_adr_liv_code_postal" in diction.keys()):
if diction['order_header_adr_liv_code_postal']:
order_header_adr_liv_code_postal = diction['order_header_adr_liv_code_postal']
if (len(str(order_header_adr_liv_code_postal)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_liv_code_postal' fait plus de 255 caractères ")
return False, " - Le champ 'order_header_adr_liv_code_postal' fait plus de 255 caractères ", False
data['order_header_adr_liv_code_postal'] = diction['order_header_adr_liv_code_postal']
order_header_adr_liv_ville = ""
if ("order_header_adr_liv_ville" in diction.keys()):
if diction['order_header_adr_liv_ville']:
order_header_adr_liv_ville = diction['order_header_adr_liv_ville']
if (len(str(order_header_adr_liv_ville)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_liv_ville' fait plus de 255 caractères ")
return False, " - Le champ 'order_header_adr_liv_ville' fait plus de 255 caractères ", False
data['order_header_adr_liv_ville'] = diction['order_header_adr_liv_ville']
order_header_adr_liv_pays = ""
if ("order_header_adr_liv_pays" in diction.keys()):
if diction['order_header_adr_liv_pays']:
order_header_adr_liv_pays = diction['order_header_adr_liv_pays']
if (len(str(order_header_adr_liv_pays)) > 255):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_header_adr_liv_pays' fait plus de 255 caractères ")
return False, " - Le champ 'order_header_adr_liv_pays' fait plus de 255 caractères ", False
data['order_header_adr_liv_pays'] = diction['order_header_adr_liv_pays']
"""
Important : : A present que tous les controles sont ok, on va proceder à la creation dans les table.
"""
### 1 - Mise à jour de l'entete
now = str(datetime.now())
data['update_date'] = now
data['update_by'] = str(my_partner['_id'])
print(" ### Update_partner_order data = ", data)
inserted_data = MYSY_GV.dbname['partner_invoice_header'].find_one_and_update(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'status': '0',
'_id': ObjectId(str(invoice_header_id))},
{"$set": data},
return_document=ReturnDocument.AFTER,
upsert=False,
)
if (inserted_data is None):
mycommon.myprint(
" Impossible de mettre à jour l'entête de facture ")
return False, "Impossible de mettre à jour l'entête de facture "
# Gestion de l'historique
# pour la collection 'partner_order_header'
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
# print(" ####### laaaa diction = ", diction)
history_event_dict = {}
history_event_dict['token'] = token
history_event_dict['related_collection'] = "partner_invoice_header"
history_event_dict['related_collection_recid'] = str(diction['invoice_header_id'])
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Mise à jour "
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(
history_event_dict))
return True, " La commande a été correctement mise à 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 mettre à jour la facture "
"""
Annuler un facture qui est statut 'draft
"""
def Cancel_Partner_Draft_Invoice(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'invoice_header_id', ]
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé")
return False, " Les informations fournies sont incorrectes",
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', 'invoice_header_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 la liste des arguments ")
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
invoice_header_id = ""
if ("invoice_header_id" in diction.keys()):
if diction['invoice_header_id']:
invoice_header_id = diction['invoice_header_id']
"""
# Verifier que la commande existe et qu'elle est modifiable.
Pour les ligne, on fait pareil, on ne peut modifier que celles qui sont modifiable.
Conditions pour modifier entete :
1 - statut est : 0 => Brouillon
Pour un debut pas de facturation partielle. c'est tout ou rien.
"""
my_invoice_data_count = MYSY_GV.dbname['partner_invoice_header'].count_documents(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'status': '0',
'_id': ObjectId(str(invoice_header_id))})
if (my_invoice_data_count != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - L'identifiant de la facture est invalide ")
return False, " L'identifiant de la facture est invalide",
### 1 - Mise à jour de l'entete
now = str(datetime.now())
data = {}
data['status'] = "-1"
data['update_date'] = now
data['update_by'] = str(my_partner['_id'])
print(" ### Update_partner_order data = ", data)
inserted_data = MYSY_GV.dbname['partner_invoice_header'].find_one_and_update(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'status': '0',
'_id': ObjectId(str(invoice_header_id))},
{"$set": data},
return_document=ReturnDocument.AFTER,
upsert=False,
)
if (inserted_data is None):
mycommon.myprint(
" Impossible de mettre à jour l'entête de facture ")
return False, "Impossible de mettre à jour l'entête de facture "
"""
Annuler les ignes aussi
"""
inserted_data = MYSY_GV.dbname['partner_invoice_header'].find_one_and_update(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'status': '0',
'invoice_header_id': str(invoice_header_id)},
{"$set": data},
return_document=ReturnDocument.AFTER,
upsert=False,
)
# Gestion de l'historique
# pour la collection 'partner_order_header'
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
# print(" ####### laaaa diction = ", diction)
history_event_dict = {}
history_event_dict['token'] = token
history_event_dict['related_collection'] = "partner_invoice_header"
history_event_dict['related_collection_recid'] = str(diction['invoice_header_id'])
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Annulation "
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(
history_event_dict))
return True, " La facture a été correctement mise à 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 mettre à jour la facture "
"""
Suppression d'une facture qui est statut 'draft'
"""
def Delete_Partner_Draft_Invoice(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'invoice_header_id', ]
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé")
return False, " Les informations fournies sont incorrectes",
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', 'invoice_header_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 la liste des arguments ")
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
invoice_header_id = ""
if ("invoice_header_id" in diction.keys()):
if diction['invoice_header_id']:
invoice_header_id = diction['invoice_header_id']
"""
# Verifier que la commande existe et qu'elle est modifiable.
Pour les ligne, on fait pareil, on ne peut modifier que celles qui sont modifiable.
Conditions pour modifier entete :
1 - statut est : 0 => Brouillon
Pour un debut pas de facturation partielle. c'est tout ou rien.
"""
my_invoice_data_count = MYSY_GV.dbname['partner_invoice_header'].count_documents(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'status': '0',
'_id': ObjectId(str(invoice_header_id))})
if (my_invoice_data_count != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - L'identifiant de la facture est invalide ")
return False, " L'identifiant de la facture est invalide",
my_invoice_data_previous_data = MYSY_GV.dbname['partner_invoice_header'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'status': '0',
'_id': ObjectId(str(invoice_header_id))})
invoice_to_delete_id = str(my_invoice_data_previous_data['_id'])
invoice_to_delete_invoice_header_ref_interne = str(my_invoice_data_previous_data['invoice_header_ref_interne'])
### 1 - Mise à jour de l'entete
now = str(datetime.now())
data = {}
data['status'] = "-1"
data['update_date'] = now
data['update_by'] = str(my_partner['_id'])
print(" ### Update_partner_order data = ", data)
inserted_data = MYSY_GV.dbname['partner_invoice_header'].delete(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'status': '0',
'_id': ObjectId(str(invoice_header_id))},
)
if (inserted_data is None):
mycommon.myprint(
" Impossible de mettre à jour l'entête de facture ")
return False, "Impossible de mettre à jour l'entête de facture "
"""
Annuler les ignes aussi
"""
inserted_data = MYSY_GV.dbname['partner_invoice_header'].delete(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'status': '0',
'invoice_header_id': str(invoice_header_id)}
)
# Gestion de l'historique
# pour la collection 'partner_order_header'
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
# print(" ####### laaaa diction = ", diction)
history_event_dict = {}
history_event_dict['token'] = token
history_event_dict['related_collection'] = "partner_invoice_header"
history_event_dict['related_collection_recid'] = str(invoice_to_delete_id)
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Suppression de la facture (draft) "+str(invoice_to_delete_id)+ " - "+str(invoice_to_delete_invoice_header_ref_interne)
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(
history_event_dict))
return True, " Le brouillon de facture a été correctement supprimée"
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de supprimer le brouillon de facture"
"""
Fonction ajoute des lignes à une facture qui existe et qui est au statut : draft
Clé :
- invoice_header_id
- invoice_header_ref_interne
- partner_owner_recid
"""
def Add_Update_Partner_Draft_Invoice_Line(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'order_line_formation', 'order_line_session_id', 'order_line_qty', 'order_line_prix_unitaire',
'order_line_tax', 'order_line_type_reduction', 'order_line_type_valeur',
'order_line_montant_reduction', 'invoice_line_id', 'order_header_ref_interne',
'invoice_header_id', 'invoice_line_status', 'invoice_line_type', 'order_line_comment',
'order_line_montant_hors_taxes', 'order_line_tax_amount', 'order_line_montant_toutes_taxes',
'order_line_type_article', 'order_line_taux_taxe', 'order_line_type_apprenant',
'tab_inscription_ids', 'tab_inscription_ids_json', 'order_header_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', 'order_line_formation', "order_line_qty", "order_line_prix_unitaire",
'invoice_line_id', 'invoice_header_id',
'invoice_line_status', 'order_line_type_article', 'invoice_line_type']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
return False, " 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
mytoken = ""
if("token" in diction.keys() ):
mytoken = diction['token']
data = {}
if( diction['invoice_line_id'] == ""):
# il s'agit d'une creation initiale
# Initialisation des champs non envoyés à vide
for val in field_list:
if val not in diction.keys():
data[str(val)] = ""
print(" ### data 011 = ", data)
invoice_header_id = ""
if ("invoice_header_id" in diction.keys() and diction['invoice_header_id']):
invoice_header_id = diction['invoice_header_id']
data['invoice_header_id'] = invoice_header_id
invoice_is_valide = MYSY_GV.dbname['partner_invoice_header'].count_documents(
{'_id': ObjectId(str(diction['invoice_header_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
if (invoice_is_valide != 1):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la facture est invalide ")
return False, " L'identifiant de la facture est invalide "
invoice_data = MYSY_GV.dbname['partner_invoice_header'].find_one(
{'_id': ObjectId(str(diction['invoice_header_id'])),
'valide': '1',
'partner_owner_recid': str(my_partner['recid'])})
data['invoice_header_ref_interne'] = str(invoice_data['invoice_header_ref_interne'])
data['invoice_line_type'] = "facture"
data['invoice_date'] = str(invoice_data['invoice_date'])
else:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " L'identifiant de la facture est invalide ")
return False, " L'identifiant de la facture est invalide "
order_line_formation = ""
if ("order_line_formation" in diction.keys()):
order_line_formation = diction['order_line_formation']
data['order_line_formation'] = order_line_formation
"""
Verifier que l'article / formation est valide
"""
myclass_data = None
if ("order_line_type_article" in diction.keys()):
if( diction['order_line_type_article'] == "formation"):
print({'internal_url':str(diction['order_line_formation']),
'partner_owner_recid':str(my_partner['recid'])})
myclass_data = MYSY_GV.dbname['myclass'].find_one({'internal_url':str(diction['order_line_formation']),
'partner_owner_recid':str(my_partner['recid'])})
elif( diction['order_line_type_article'] == "produit"):
myclass_data = MYSY_GV.dbname['partner_produit_service'].find_one({'_id': ObjectId(str(diction['order_line_formation'])),
'partner_owner_recid': str(my_partner['recid'])})
if( myclass_data is None ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant de l'article est invalide ")
return False, " L'identifiant de l'article est invalide ",
# Si l'utilisateur a choisi une session, verifier qu'elle est valide
order_line_session_id = ""
if( "order_line_session_id" in diction.keys() and diction['order_line_session_id']):
is_valide_session_id_count = MYSY_GV.dbname['session_formation'].count_documents({'_id':ObjectId(str(diction['order_line_session_id'])),
'partner_owner_recid':str(my_partner['recid']),
'valide':'1'})
if( is_valide_session_id_count <= 0 ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " L'identifiant de session de formation "+str(diction['order_line_session_id'])+" n'est pas valide ")
return False, " L'identifiant de session de formation "+str(diction['order_line_session_id'])+" n'est pas valide "
order_line_session_id = str(diction['order_line_session_id'])
"""
Important : : Il peut arrivé qu'on souhaite supprimer la session du devis ou la commande, alors on autorise la mise à jour meme si vide
"""
data['order_line_session_id'] = order_line_session_id
invoice_line_type = ""
if ("invoice_line_type" in diction.keys()):
if diction['invoice_line_type']:
invoice_line_type = diction['invoice_line_type']
data['invoice_line_type'] = invoice_line_type
if( invoice_line_type not in ['facture']):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La valeur du champ 'invoice_line_type' est invalide. Les valeurs acceptées : 'facture' ")
return False, " La valeur du champ 'invoice_line_type' est invalide. Les valeurs acceptées : 'facture' "
invoice_line_status = ""
if ("invoice_line_status" in diction.keys()):
invoice_line_status = diction['invoice_line_status']
data['invoice_line_status'] = invoice_line_status
order_line_qty = ""
if ("order_line_qty" in diction.keys()):
order_line_qty = diction['order_line_qty']
data['order_line_qty'] = order_line_qty
order_line_type_article = ""
if ("order_line_type_article" in diction.keys()):
order_line_type_article = diction['order_line_type_article']
data['order_line_type_article'] = order_line_type_article
order_line_type_apprenant = ""
if ("order_line_type_apprenant" in diction.keys()):
if diction['order_line_type_apprenant']:
order_line_type_apprenant = str(diction['order_line_type_apprenant'])
# Verifier que le type d'apprenant est valide
is_type_apprenant_valide = MYSY_GV.dbname['type_apprenant'].count_documents({"code":str(order_line_type_apprenant), 'valide':'1', 'locked':'0'})
if( is_type_apprenant_valide != 1 ):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " Le type apprenant est invalide.")
return False, " Le type apprenant est invalide."
data['order_line_type_apprenant'] = order_line_type_apprenant
order_line_prix_unitaire = ""
if ("order_line_prix_unitaire" in diction.keys()):
order_line_prix_unitaire = diction['order_line_prix_unitaire']
data['order_line_prix_unitaire'] = order_line_prix_unitaire
order_line_tax = ""
if ("order_line_tax" in diction.keys()):
order_line_tax = diction['order_line_tax']
data['order_line_tax'] = order_line_tax
tab_inscrit_id = []
tab_inscrit_id_work = []
if( "tab_inscription_ids_json" in diction.keys() and diction['tab_inscription_ids_json']):
for inscrit_data in diction['tab_inscription_ids_json']:
tab_inscrit_id.append(inscrit_data)
elif ("tab_inscription_ids" in diction.keys() and diction['tab_inscription_ids']):
tab_inscrit_id_JSON = ast.literal_eval(diction['tab_inscription_ids'])
for inscrit_data in tab_inscrit_id_JSON:
tab_inscrit_id.append(inscrit_data)
data['tab_inscription_ids'] = tab_inscrit_id
order_line_taux_taxe = ""
if ("order_line_taux_taxe" in diction.keys()):
order_line_taux_taxe = diction['order_line_taux_taxe']
data['order_line_taux_taxe'] = order_line_taux_taxe
order_line_tax_amount = ""
if ("order_line_tax_amount" in diction.keys()):
order_line_tax_amount = diction['order_line_tax_amount']
data['order_line_tax_amount'] = order_line_tax_amount
order_line_montant_toutes_taxes = ""
if ("order_line_montant_toutes_taxes" in diction.keys()):
order_line_montant_toutes_taxes = diction['order_line_montant_toutes_taxes']
data['order_line_montant_toutes_taxes'] = order_line_montant_toutes_taxes
order_line_montant_hors_taxes = ""
if ("order_line_montant_hors_taxes" in diction.keys()):
order_line_montant_hors_taxes = diction['order_line_montant_hors_taxes']
data['order_line_montant_hors_taxes'] = order_line_montant_hors_taxes
order_line_type_reduction = ""
if ("order_line_type_reduction" in diction.keys()):
order_line_type_reduction = diction['order_line_type_reduction']
data['order_line_type_reduction'] = order_line_type_reduction
order_line_type_valeur = ""
if ("order_line_type_valeur" in diction.keys()):
order_line_type_valeur = diction['order_line_type_valeur']
data['order_line_type_valeur'] = order_line_type_valeur
order_line_montant_reduction = ""
if ("order_line_montant_reduction" in diction.keys()):
order_line_montant_reduction = diction['order_line_montant_reduction']
data['order_line_montant_reduction'] = order_line_montant_reduction
order_header_ref_interne = ""
if ("order_header_ref_interne" in diction.keys()):
order_header_ref_interne = diction['order_header_ref_interne']
data['order_header_ref_interne'] = order_header_ref_interne
order_line_comment = ""
if ("order_line_comment" in diction.keys()):
order_line_comment = diction['order_line_comment']
data['order_line_comment'] = order_line_comment
if(len(str(order_line_comment)) > 500):
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - Le champ 'order_line_comment' fait plus de 500 caractères ")
return False, " - Le champ 'Commentaire de la ligne' fait plus de 500 caractères "
invoice_line_id = ""
if ("invoice_line_id" in diction.keys() and len(str(diction['invoice_line_id'])) > 0 ) :
# il s'agit de mettre à jour la ligne. Il faut verifier que la ligne existe et est modifiable
invoice_line_id = diction['invoice_line_id']
existe_invoice_line_count = MYSY_GV.dbname['partner_order_line'].count_documents({'_id':ObjectId(str(invoice_line_id)), 'valide':'1', 'locked':'0',
'partner_owner_recid':str(my_partner['recid'])})
if( existe_invoice_line_count != 1 ):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La ligne à mettre à jour est invalide")
return False, "La ligne à mettre à jour est invalide",
data['update_date'] = str(datetime.now())
data['update_by'] = str(my_partner['_id'])
data['status'] = "0"
inserted_data = MYSY_GV.dbname['partner_invoice_line'].find_one_and_update(
{'_id': ObjectId(str(invoice_line_id)), 'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])},
{"$set": data},
return_document=ReturnDocument.AFTER,
upsert=False,
)
if (inserted_data is None):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - Impossible de mettre à jour la ligne (3)")
return False, " Impossible de mettre à jour la ligne (3) "
"""
Une fois qu'on a modifier une ligne, il faut remettre les statuts d'entete et de ligne à 'brouillon'
pour obligier l'utilisateur à revalider le devis
"""
local_update_data = {}
local_update_data['update_date'] = str(datetime.now())
local_update_data['update_by'] = str(my_partner['_id'])
local_update_data['status'] = "0"
upadate_header = MYSY_GV.dbname['partner_invoice_header'].find_one_and_update(
{'_id': ObjectId(str(diction['invoice_header_id'])), 'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])},
{"$set": local_update_data},
return_document=ReturnDocument.AFTER,
upsert=False,
)
local_update_data = {}
local_update_data['update_date'] = str(datetime.now())
local_update_data['update_by'] = str(my_partner['_id'])
local_update_data['status'] = "0"
upadate_line = MYSY_GV.dbname['partner_order_line'].find_one_and_update(
{'invoice_header_id': str(diction['invoice_header_id']), 'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])},
{"$set": local_update_data},
return_document=ReturnDocument.AFTER,
upsert=False,
)
"""
On relance un compute si une ligne a changé
"""
comput_diction = {}
comput_diction['token'] = diction['token']
comput_diction['_id'] = diction['invoice_header_id']
local_retval, local_message = Compute_Invoice_Header(comput_diction)
if (local_retval is False):
mycommon.myprint(" WARNING : Apres la confirmation, La fonction compute pour la facture : " + str(
comput_diction) + " n'a pas fonctionnée, ")
else:
# Il s'agit d'une creation d'une nouvelle ligne
data['valide'] = '1'
data['locked'] = '0'
data['partner_owner_recid'] = my_partner['recid']
data['creation_by'] = str(my_partner['_id'])
data['creation_date'] = str(datetime.now())
if( "tab_inscription_ids_json" in data.keys()):
del data['tab_inscription_ids_json']
inserted_line_id = ""
inserted_line_id = MYSY_GV.dbname['partner_invoice_line'].insert_one(data).inserted_id
if (not inserted_line_id):
mycommon.myprint(
" Impossible de créer la ligne de facture ")
return False, " Impossible de créer la ligne de facture "
"""
Une fois qu'on a modifier une ligne, il faut remettre les statuts d'entete et de ligne à 'brouillon'
pour obligier l'utilisateur à revalider le devis
"""
local_update_data = {}
local_update_data['update_date'] = str(datetime.now())
local_update_data['update_by'] = str(my_partner['_id'])
local_update_data['status'] = "0"
upadate_header = MYSY_GV.dbname['partner_invoice_header'].find_one_and_update(
{'_id': ObjectId(str(diction['invoice_header_id'])), 'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])},
{"$set": local_update_data},
return_document=ReturnDocument.AFTER,
upsert=False,
)
local_update_data = {}
local_update_data['update_date'] = str(datetime.now())
local_update_data['update_by'] = str(my_partner['_id'])
local_update_data['status'] = "0"
upadate_line = MYSY_GV.dbname['partner_order_line'].find_one_and_update(
{'invoice_header_id': str(diction['invoice_header_id']), 'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])},
{"$set": local_update_data},
return_document=ReturnDocument.AFTER,
upsert=False,
)
"""
On relance un compute si une ligne a changé
"""
comput_diction = {}
comput_diction['token'] = diction['token']
comput_diction['_id'] = diction['invoice_header_id']
local_retval, local_message = Compute_Invoice_Header(comput_diction)
if (local_retval is False):
mycommon.myprint(" WARNING : Apres la confirmation, La fonction compute pour la facture : " + str(
comput_diction) + " n'a pas fonctionnée, ")
"""
12/10/2024 - loguer les action dans l'historique général
"""
## Add to log history pour l'inscrit 'inscription'
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
history_event_dict = {}
history_event_dict['token'] = str(mytoken)
history_event_dict['related_collection'] = "partner_invoice_header"
history_event_dict['related_collection_recid'] = str(diction['invoice_header_id'])
history_event_dict['action_date'] = str(now)
article_info = str(myclass_data['_id'])
if (diction['order_line_type_article'] == "formation" and "external_code" in myclass_data.keys() ):
article_info = article_info+', '+str(myclass_data['external_code'])
elif (diction['order_line_type_article'] == "produit" and "code" in myclass_data.keys() ):
article_info = article_info+', '+str(myclass_data['code'])
history_event_dict['action_description'] = "Ajout / MAJ ligne " + str(article_info)
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(history_event_dict))
return True, " La ligne de commande a été correctement ajoutée/mise à 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 / mettre à jour la ligne de facture "
"""
Suppression d'une LIGNE DE facture qui est statut 'draft'
"""
def Delete_Partner_Draft_Invoice_Line(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'invoice_header_id', 'partner_invoice_line' ]
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé")
return False, " Les informations fournies sont incorrectes",
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', 'invoice_header_id', 'partner_invoice_line' ]
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][
3]) + " - La valeur '" + val + "' n'est pas presente dans la liste des arguments ")
return False, " 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
invoice_header_id = ""
if ("invoice_header_id" in diction.keys()):
if diction['invoice_header_id']:
invoice_header_id = diction['invoice_header_id']
"""
# Verifier que la commande existe et qu'elle est modifiable.
Pour les ligne, on fait pareil, on ne peut modifier que celles qui sont modifiable.
Conditions pour modifier entete :
1 - statut est : 0 => Brouillon
Pour un debut pas de facturation partielle. c'est tout ou rien.
"""
my_invoice_data_count = MYSY_GV.dbname['partner_invoice_header'].count_documents(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'status': '0',
'_id': ObjectId(str(invoice_header_id))})
if (my_invoice_data_count != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - L'identifiant de la facture est invalide ")
return False, " L'identifiant de la facture est invalide",
"""
La ligne
"""
my_invoice_line_data_count = MYSY_GV.dbname['partner_invoice_line'].count_documents(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0',
'_id': ObjectId(str(diction['partner_invoice_line']))})
if (my_invoice_line_data_count != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - L'identifiant de la ligne de facture est invalide ")
return False, " L'identifiant de la ligne de facture est invalide ",
my_invoice_line_data_count = MYSY_GV.dbname['partner_invoice_header'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0',
'_id': ObjectId(str(diction['partner_invoice_line']))})
invoice_line_to_delete_id = str(my_invoice_line_data_count['_id'])
invoice_line_to_delete_invoice_header_ref = str(my_invoice_line_data_count['order_line_formation'])
### 1 - Mise à jour de l'entete
now = str(datetime.now())
data = {}
data['status'] = "-1"
data['update_date'] = now
data['update_by'] = str(my_partner['_id'])
print(" ### Update_partner_order data = ", data)
inserted_data = MYSY_GV.dbname['partner_invoice_line'].delete(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0',
'_id': ObjectId(str(diction['partner_invoice_line']))},
)
if (inserted_data is None):
mycommon.myprint(
" Impossible de supprimer la ligne de facture (3) ")
return False, "Impossible de supprimer la ligne de facture (3) "
"""
On relance un compute si une ligne a changé
"""
comput_diction = {}
comput_diction['token'] = diction['token']
comput_diction['_id'] = diction['invoice_header_id']
local_retval, local_message = Compute_Invoice_Header(comput_diction)
if (local_retval is False):
mycommon.myprint(" WARNING : Apres la confirmation, La fonction compute pour la facture : " + str(
comput_diction) + " n'a pas fonctionnée, ")
# Gestion de l'historique
# pour la collection 'partner_order_header'
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
# print(" ####### laaaa diction = ", diction)
history_event_dict = {}
history_event_dict['token'] = token
history_event_dict['related_collection'] = "partner_invoice_header"
history_event_dict['related_collection_recid'] = str(invoice_header_id)
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Suppression de la Ligne de facture"+str(invoice_line_to_delete_id)+ " - "+str(invoice_line_to_delete_invoice_header_ref)
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(
history_event_dict))
return True, " La ligne a été correctement supprimée"
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de supprimer la ligne"
"""
Confirmation d'un brouillon de facture et transformation en facture reelle.
La facture doit etre au statut 'Draft', puis passer au statut confirmé
"""
def Confirm_Partner_Invoice_Header_And_Lines(diction):
try:
diction = mycommon.strip_dictionary(diction)
"""
Verification des input acceptés
"""
field_list = ['token', 'invoice_header_id', ]
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list and val.startswith('my_') is False:
mycommon.myprint(str(
inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé")
return False, " Les informations fournies sont incorrectes",
"""
Verification des champs obligatoires
"""
field_list_obligatoire = ['token', 'invoice_header_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 la liste des arguments ")
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
invoice_header_id = ""
if ("invoice_header_id" in diction.keys()):
if diction['invoice_header_id']:
invoice_header_id = diction['invoice_header_id']
my_order_data_count = MYSY_GV.dbname['partner_invoice_header'].count_documents(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'status':'0',
'_id': ObjectId(str(invoice_header_id))})
if (my_order_data_count != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - L'identifiant de la facture est invalide ")
return False, " L'identifiant de la facture est invalide",
"""
Verifier qu'il y a des ligne pour cette facture
"""
my_order_line_data_count = MYSY_GV.dbname['partner_invoice_line'].count_documents(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0',
'invoice_header_id': str(invoice_header_id)})
if (my_order_line_data_count <= 0):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - Aucune ligne pour cette facture ")
return False, " Aucune ligne pour cette facture",
"""
Recuperation et stockage des données de l'entete avant mise à jour
"""
my_order_data_previous_information = MYSY_GV.dbname['partner_invoice_header'].find_one(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0', 'status': '0',
'_id': ObjectId(str(invoice_header_id))})
"""
Important : : A present que tous les controles sont ok, on va proceder à la creation dans les table.
"""
# Récuperation de la sequence de l'objet "partner_invoice_header" dans la collection : "mysy_sequence"
retval_sequence_invoice = MYSY_GV.dbname['mysy_sequence'].find_one(
{'related_mysy_object': 'partner_invoice_header',
'valide': '1', 'partner_owner_recid': str(
my_partner['recid'])})
if (retval_sequence_invoice is None):
# Il n'y pas de sequence pour le partenaire, on va aller chercher la sequence par defaut
retval_sequence_invoice = MYSY_GV.dbname['mysy_sequence'].find_one(
{'related_mysy_object': 'partner_invoice_header',
'valide': '1', 'partner_owner_recid': 'default'})
if (retval_sequence_invoice is None or "current_val" not in retval_sequence_invoice.keys()):
mycommon.myprint(" Impossible de récupérer la sequence 'retval_sequence_invoice' ")
return False, "Impossible de récupérer la sequence 'retval_sequence_invoice'", False
current_seq_value = str(retval_sequence_invoice['current_val'])
new_sequence_value = int(mycommon.tryInt(current_seq_value)) + 1
new_sequance_data_to_update = {'current_val': new_sequence_value}
ret_val2 = MYSY_GV.dbname['mysy_sequence'].find_one_and_update(
{'_id': ObjectId(str(retval_sequence_invoice['_id'])), 'valide': '1'},
{"$set": new_sequance_data_to_update},
return_document=ReturnDocument.AFTER,
upsert=False,
)
### 1 - Mise à jour de l'entete
# Recuperation des champs
now = str(datetime.now())
invoice_date_time = str(datetime.now().strftime("%d/%m/%Y"))
data = {}
invoice_ref_interne = retval_sequence_invoice['prefixe'] + str(current_seq_value)
data['invoice_header_ref_interne'] = invoice_ref_interne
data['invoice_header_type'] = "facture"
data['invoice_date'] = invoice_date_time
data['status'] = "1"
data['update_date'] = now
data['update_by'] = str(my_partner['_id'])
print(" ### Update_partner_order data = ", data)
inserted_data = MYSY_GV.dbname['partner_invoice_header'].find_one_and_update(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0',
'_id': ObjectId(str(invoice_header_id))},
{"$set": data},
return_document=ReturnDocument.AFTER,
upsert=False,
)
if (inserted_data is None):
mycommon.myprint(
" Impossible de mettre à jour l'entête de facture ")
return False, "Impossible de mettre à jour l'entête de facture "
"""
Mise à jour des lignes (partner_order_line) dont les status sont à 0 (brouillon)
"""
local_qry = {'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0',
'invoice_header_id': str(invoice_header_id)
}
# print(" #### COMMANDE local_qry = ", local_qry)
inserted_data_line = MYSY_GV.dbname['partner_invoice_line'].update_many(
{'partner_owner_recid': str(my_partner['recid']),
'valide': '1', 'locked': '0',
'invoice_header_id': str(invoice_header_id),
},
{
"$set": {"status": "1", 'invoice_header_ref_interne' :invoice_ref_interne, 'invoice_line_type':'facture', 'invoice_date':invoice_date_time,
'update_date': now, 'update_by':str(my_partner['_id'])}
})
"""print("raw:", inserted_data_line.raw_result)
print("acknowledged:", inserted_data_line.acknowledged)
print("matched_count:", inserted_data_line.matched_count)"""
comput_diction = {}
comput_diction['token'] = diction['token']
comput_diction['_id'] = diction['invoice_header_id']
local_retval, local_message = Compute_Invoice_Header(comput_diction)
if( local_retval is False) :
mycommon.myprint(" WARNING : Apres la confirmation, La fonction compute pour la facture : "+str(comput_diction)+" n'a pas fonctionnée, ")
# Gestion de l'historique
# pour la collection 'partner_order_header'
now = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
# print(" ####### laaaa diction = ", diction)
history_event_dict = {}
history_event_dict['token'] = token
history_event_dict['related_collection'] = "partner_invoice_header"
history_event_dict['related_collection_recid'] = str(diction['invoice_header_id'])
history_event_dict['action_date'] = str(now)
history_event_dict['action_description'] = "Confirmation "
local_status, local_retval = mycommon.Collection_Historique.Add_Historique_Event(history_event_dict)
if (local_status is False):
mycommon.myprint(
" WARNING : Impossible de logguer l'historique pour l'évènement : " + str(
history_event_dict))
return True, " Le document a été correctement mise à 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 confirmer le document "
""""
Cette fonction calcul les totaux (reduction,HT, TTC, TAXES, etc) d'une facture (etat draft)
et met à jour ces info
"""
def Compute_Invoice_Header(diction):
try:
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 la liste des arguments ")
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
# Recuperation de la valeur de la TVA (taux tva)
partner_taux_tva = 20
if ("invoice_taux_vat" in my_partner.keys()):
IsInt_status, IsInt_retval = mycommon.IsInt(str(my_partner['invoice_taux_vat']))
if (IsInt_status is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La valeur '" + str(
my_partner['invoice_taux_vat']) + "' n'est pas un taux de TVA correcte ")
return False, " La valeur '" + str(
my_partner['invoice_taux_vat']) + "' n'est pas un taux de TVA correcte ",
partner_taux_tva = IsInt_retval
# print(" ### COMPUTE : le taux de TVA = ", str(partner_taux_tva))
# Verification de la validité de l'order
qry = {'_id': ObjectId(str(diction['_id'])), 'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}
print(" ### qry = ", qry)
is_Order_Existe_Count = MYSY_GV.dbname['partner_invoice_header'].count_documents(
{'_id': ObjectId(str(diction['_id'])),
'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])})
if (is_Order_Existe_Count != 1):
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La facture n'est pas valide ")
return False, " La facture n'est pas valide",
Order_header_data = MYSY_GV.dbname['partner_invoice_header'].find_one({'_id': ObjectId(str(diction['_id'])),
'valide': '1', 'locked': '0',
'partner_owner_recid': str(
my_partner['recid'])})
"""
Algo :
1 - récupérer toutes les lignes valides, créer des sous totaux
2 - Appliquer les eventuels reductions d'entete
"""
nb_line = 0
line_sum_order_line_tax_amount = 0
line_sum_order_line_montant_reduction = 0
line_sum_order_line_montant_hors_taxes_before_reduction = 0
line_sum_order_line_montant_hors_taxes_after_reduction = 0
line_sum_order_line_montant_toutes_taxes = 0
for local_retval in MYSY_GV.dbname['partner_invoice_line'].find(
{'invoice_header_id': str(diction['_id']), 'valide': '1', 'locked': '0',
'partner_owner_recid': str(my_partner['recid'])}):
# print(" ------------------- Pour la ligne numero : ", nb_line)
ligne_montant_reduction = 0
if ("order_line_montant_reduction" in local_retval.keys()):
line_sum_order_line_montant_reduction = line_sum_order_line_montant_reduction + mycommon.tryFloat( local_retval['order_line_montant_reduction'])
ligne_montant_reduction = mycommon.tryFloat(local_retval['order_line_montant_reduction'])
# print(" #### order_line_montant_reduction = ",
# str(mycommon.tryFloat(local_retval['order_line_montant_reduction'])))
if ("order_line_tax_amount" in local_retval.keys()):
line_sum_order_line_tax_amount = line_sum_order_line_tax_amount + mycommon.tryFloat(local_retval['order_line_tax_amount'])
# print(" #### order_line_tax_amount = ", str(mycommon.tryFloat(local_retval['order_line_tax_amount'])))
if ("order_line_montant_hors_taxes" in local_retval.keys()):
line_sum_order_line_montant_hors_taxes_before_reduction = line_sum_order_line_montant_hors_taxes_before_reduction + mycommon.tryFloat( local_retval['order_line_montant_hors_taxes'])
# print(" #### order_line_montant_hors_taxes = ", str(mycommon.tryFloat(local_retval['order_line_montant_hors_taxes'])))
order_line_montant_hors_taxes_APRES_REDUCTION = mycommon.tryFloat(local_retval['order_line_montant_hors_taxes']) - ligne_montant_reduction
# print(" #### order_line_montant_hors_taxes_APRES_REDUCTION = ", str(order_line_montant_hors_taxes_APRES_REDUCTION))
if ("order_line_montant_toutes_taxes" in local_retval.keys()):
line_sum_order_line_montant_toutes_taxes = line_sum_order_line_montant_toutes_taxes + mycommon.tryFloat( local_retval['order_line_montant_toutes_taxes'])
# print(" #### order_line_montant_toutes_taxes = ",
# str(mycommon.tryFloat(local_retval['order_line_montant_toutes_taxes'])))
# print(" ----------- FIN DES LIGNES ")
nb_line = nb_line + 1
line_sum_order_line_montant_hors_taxes_after_reduction = line_sum_order_line_montant_hors_taxes_before_reduction - line_sum_order_line_montant_reduction
print(" ###### line_sum_order_line_tax_amount = ", line_sum_order_line_tax_amount)
"""
print(" ###### Apres compute des lignes : NB_LINE = ", nb_line)
print(" ###### line_sum_order_line_montant_reduction = ", line_sum_order_line_montant_reduction)
print(" ###### line_sum_order_line_tax_amount = ", line_sum_order_line_tax_amount)
print(" ###### line_sum_order_line_montant_hors_taxes_before_reduction = ", line_sum_order_line_montant_hors_taxes_before_reduction)
print(" ###### line_sum_order_line_montant_hors_taxes_after_reduction = ", line_sum_order_line_montant_hors_taxes_after_reduction)
print(" ###### line_sum_order_line_montant_toutes_taxes = ", line_sum_order_line_montant_toutes_taxes)
"""
header_reduction_type = ""
header_reduction_type_value = ""
if ("order_header_type_reduction" in Order_header_data.keys()):
header_reduction_type = Order_header_data['order_header_type_reduction']
if ("order_header_type_reduction_valeur" in Order_header_data.keys()):
header_reduction_type_value = Order_header_data['order_header_type_reduction_valeur']
"""
print(" ### les reduction d'entete ")
print(" ###### header_reduction_type = ", header_reduction_type)
print(" ###### header_reduction_type_value = ", header_reduction_type_value)
"""
global_order_taxe_amount = 0
global_order_amount_ht_before_header_reduction = line_sum_order_line_montant_hors_taxes_after_reduction
global_order_amount_ht_after_header_reduction = 0
header_reduction_type_value_total_amount = 0
if (str(header_reduction_type) == "fixe"):
header_reduction_type_value_total_amount = mycommon.tryFloat(header_reduction_type_value)
global_order_amount_ht_after_header_reduction = line_sum_order_line_montant_hors_taxes_before_reduction - header_reduction_type_value_total_amount
"""print(" GRRRR 022 header_reduction_type_value_total_amount = ",
header_reduction_type_value_total_amount)
print(" GRRRR 022 global_order_amount_ht_after_header_reduction = ",
global_order_amount_ht_after_header_reduction)
"""
elif (str(header_reduction_type) == "percent"):
# print(" GRRRR line_sum_order_line_montant_hors_taxes_after_reduction = ", line_sum_order_line_montant_hors_taxes_after_reduction)
# print(" GRRRR mycommon.tryFloat(header_reduction_type_value)/100 = ",
# line_sum_order_line_montant_hors_taxes_after_reduction*mycommon.tryFloat(header_reduction_type_value)/100)
# print(" GRRRR mycommon.tryFloat(header_reduction_type_value)/100 = ",
# (line_sum_order_line_montant_hors_taxes_after_reduction - (line_sum_order_line_montant_hors_taxes_after_reduction*mycommon.tryFloat(header_reduction_type_value)/100)) )
header_reduction_type_value_total_amount = line_sum_order_line_montant_hors_taxes_before_reduction * mycommon.tryFloat(
header_reduction_type_value) / 100
global_order_amount_ht_after_header_reduction = line_sum_order_line_montant_hors_taxes_before_reduction - header_reduction_type_value_total_amount
# print(" GRRRR global_order_amount_ht_after_header_reduction = ",global_order_amount_ht_after_header_reduction)
else:
header_reduction_type_value_total_amount = 0
global_order_amount_ht_before_header_reduction = line_sum_order_line_montant_hors_taxes_before_reduction
global_order_amount_ht_after_header_reduction = line_sum_order_line_montant_hors_taxes_before_reduction
global_order_amount_ttc = global_order_amount_ht_after_header_reduction + line_sum_order_line_tax_amount
"""print(" ###### header_reduction_type_value_total_amount = ", header_reduction_type_value_total_amount)
print(" ###### global_order_amount_ht_before_header_reduction = ", line_sum_order_line_montant_hors_taxes_after_reduction)
print(" ###### global_order_amount_ht_after_header_reduction = ", global_order_amount_ht_after_header_reduction)
print(" ###### global_order_amount_ttc = ", global_order_amount_ttc)
"""
"""
Tous les calculs, ok, on met à l'entete de de l'order
"""
"""
Important : 20/08/204 :
mise à jour des calcul :
dans les lignes, le montant hors taxe, inclus la reduction (vrai HT - montant reduction).
par consequent dans le header :
- total_lines_hors_taxe_before_lines_reduction contient le montant hors taxe incluant la reduction
"""
header_computed_data = {}
header_computed_data['total_lines_montant_reduction'] = str(round(line_sum_order_line_montant_reduction, 2))
header_computed_data['total_lines_hors_taxe_before_lines_reduction'] = str(
round((line_sum_order_line_montant_hors_taxes_before_reduction + line_sum_order_line_montant_reduction), 2))
header_computed_data['total_lines_hors_taxe_after_lines_reduction'] = str(
round(line_sum_order_line_montant_hors_taxes_before_reduction, 2))
header_computed_data['order_header_montant_reduction'] = str(round(header_reduction_type_value_total_amount, 2))
header_computed_data['total_header_hors_taxe_before_header_reduction'] = str(
round(line_sum_order_line_montant_hors_taxes_before_reduction, 2))
header_computed_data['total_header_hors_taxe_after_header_reduction'] = str(
round(global_order_amount_ht_after_header_reduction, 2))
header_computed_data['order_header_tax'] = "TVA " + str(partner_taux_tva) + "%"
header_computed_data['order_header_tax_amount'] = str(round(line_sum_order_line_tax_amount, 2))
header_computed_data['total_header_toutes_taxes'] = str(round(global_order_amount_ttc, 2))
header_computed_data['update_date'] = str(datetime.now())
# print(" ### header_computed_data = ", header_computed_data)
local_retval = MYSY_GV.dbname['partner_invoice_header'].find_one_and_update({'_id': ObjectId(str(diction['_id'])),
'valide': '1', 'locked': '0',
'partner_owner_recid': str(
my_partner['recid'])},
{"$set": header_computed_data
},
upsert=False,
return_document=ReturnDocument.AFTER
)
if (local_retval is None):
mycommon.myprint(str(inspect.stack()[0][3]) + " Impossible de finaliser la mise à jour")
return False, " Impossible de finaliser la mise à jour "
return True, 'La mise à jour des prix a été correctement faite.'
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de génerer les calculs de mise à jour "