Elyos_FI_Back_Office/Job_Cron.py

416 lines
17 KiB
Python

"""
Ce fichier permet de gerer les crons et differents job
"""
import ast
import bson
import pymongo
import xlsxwriter
from pymongo import MongoClient
import json
from bson import ObjectId
import re
from datetime import datetime, date, timedelta
import module_editique
import partner_order
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 survey_mgt as survey_mgt
"""
Ce job permet d'envoyer les demandes d'enquetes comme les
evaluation à froid.
Les informations sont stockées dans la collection : "survey"
Par exemple, une fois par jour ce job va tourner,
"date_demande_envoi" = date_jour, alors on envoi
on met à jour avec la collection avec
"""
def Global_MySy_Cron_Traitement():
try:
today = str(datetime.now().strftime("%d/%m/%Y"))
today_date_ISODATE = datetime.strptime(str(today), '%d/%m/%Y')
qery_match = {'$and': [{"valide": '1', 'locked':'0'},
{
'mysy_cron_date_start': {'$lte': today_date_ISODATE},
},
{
'mysy_cron_date_end': {'$gte': today_date_ISODATE,},
},
]}
pipe_qry = ([
{"$addFields": {
"mysy_cron_date_start": {
'$dateFromString': {
'dateString': '$date_start',
'format': "%d/%m/%Y"
}
}
}
},
{"$addFields": {
"mysy_cron_date_end": {
'$dateFromString': {
'dateString': '$date_end',
'format': "%d/%m/%Y"
}
}
}
},
{'$match': qery_match},
])
for val in MYSY_GV.dbname['Job_Cron'].aggregate(pipe_qry):
if( "job_name" in val.keys() ):
possibles = globals().copy()
possibles.update(locals())
cron_function = possibles.get(val['job_name'])
if not cron_function:
return False, "Fonction '"+str(val['job_name'])+"' est introuvable"
local_con_status, local_con_retval = cron_function()
print(" local_con_status = ", local_con_status)
"""
Mettre à jour le cron pour dire que tout s'est bien poassé
"""
now = str(datetime.now())
cron_update_data = {}
cron_update_data['last_run'] = str(now)
if( local_con_status is True ):
cron_update_data['last_run_status'] = "1"
else:
cron_update_data['last_run_status'] = "0"
cron_update_data['last_run_message'] = local_con_retval
node_traitement = {}
node_traitement['run_date'] = str(now)
node_traitement['run_status'] = str(cron_update_data['last_run_status'])
node_traitement['run_message'] = str(local_con_retval)
if( "cront_list_traitement" in val.keys() and val['cront_list_traitement']):
local_cront_list_traitement = val['cront_list_traitement']
local_cront_list_traitement.append(node_traitement)
else:
local_cront_list_traitement = []
local_cront_list_traitement.append(node_traitement)
cron_update_data['cront_list_traitement'] = local_cront_list_traitement
ret_val = MYSY_GV.dbname['Job_Cron'].find_one_and_update(
{'_id': ObjectId(str(val['_id']))},
{"$set": cron_update_data},
return_document=ReturnDocument.AFTER,
upsert=False,
)
return True, "OK"
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)
"""
CRON fonction qui envoie les demandes d'enquete
"""
def Cron_Send_Survey():
try:
for val in MYSY_GV.dbname['survey'].find({"automatique_traitement":"1",
'automatique_traitement_done':'0',
'valide':'1',
'locked':'0'}) :
if( "automatique_sending_request_date" in val.keys() and val['automatique_sending_request_date']):
automatic_date_to_send = str(val['automatique_sending_request_date'])[0:10]
local_status = mycommon.CheckisDate(automatic_date_to_send)
if (local_status is False):
mycommon.myprint(str(inspect.stack()[0][
3]) + " La date 'automatique_sending_request_date' de n'est pas au format jj/mm/aaaa.")
return False, " La date 'automatique_sending_request_date' de n'est pas au format jj/mm/aaaa."
if (datetime.strptime(str(automatic_date_to_send), '%d/%m/%Y') <= datetime.strptime(str(datetime.now().strftime("%d/%m/%Y")), '%d/%m/%Y') ) :
print(" OKK to run job ")
local_dicton = {}
local_dicton['partner_owner_recid'] = str(val['partner_owner_recid'])
local_dicton['tab_ids'] = (str(val['_id']))
local_status, local_retval = survey_mgt.Automatic_Send_Survey_TabIds(local_dicton)
#data['date_update'] = str(datetime.now())
survey_update_data = {}
sending_status = "0"
if( local_status is False ):
sending_status = "0"
else:
sending_status = "1"
survey_update_data['automatique_traitement_done'] = "1"
survey_update_data['date_envoi'] = str(datetime.now())
ret_val = MYSY_GV.dbname['survey'].find_one_and_update(
{'_id': ObjectId(str(val['_id']))},
{"$set": survey_update_data},
return_document=ReturnDocument.AFTER,
upsert=False,
)
return True, ""
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, str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)
"""
CRON fonction qui fait les relances de devis
/!\ Algorithme :
1 - Recuperer dans la collection "base_partner_setup" les partenaires
qui ont la relance auto active : "relance_auto"
2 - Pour chaque devis du partenaire concernée "partner_owner_recid", recuperé à l'etape 1
Verifier que les devis repondent aux critères suivants (la collection : partner_order_header, order_header_type = "devis"
- devis n'a pas expiré
- devis relance_auto = 1
- devis status : En cours => valeur 1
- devis nb_relance non depassé
- on ne relance un devis que la frequence de la relance est gerée
"""
def Cron_Quotation_Relance():
try:
todays_date = str(date.today().strftime("%d/%m/%Y"))
todays_date_ISODATE = datetime.strptime(str(todays_date), '%d/%m/%Y')
for relance_setp in MYSY_GV.dbname['base_partner_setup'].find({'valide':'1',
'locked':'0',
'config_name':'relance_auto',
'config_value':'1',
'related_collection':'quotation',
'partner_owner_recid': {'$ne': 'default'},
}):
if( "partner_owner_recid" in relance_setp.keys() and relance_setp['partner_owner_recid'] ):
local_partner_owner_recid = str(relance_setp['partner_owner_recid'])
devis_qery_match = {'$and': [{'partner_owner_recid':str(local_partner_owner_recid),
'valide':'1',
'locked':'0', 'order_header_type':'devis', 'order_header_status':'1',
'relance_auto':'1'},
{
'mysy_devis_expiration_date': {
'$gte': todays_date_ISODATE,
}
}, ]}
pipe_qry = ([
{"$addFields": {
"mysy_devis_expiration_date": {
'$dateFromString': {
'dateString': '$order_header_date_expiration',
'format': "%d/%m/%Y"
}
}
}
},
{'$match': devis_qery_match},
])
print(" ## pipe_qry Cron_Quotation_Relance = ", pipe_qry)
for local_devis in MYSY_GV.dbname['partner_order_header'].aggregate(pipe_qry):
is_quotation_validated = 0
if( "validation_by" in local_devis.keys() and local_devis['validation_by'] and
"date_validation" in local_devis.keys() and local_devis['date_validation'] ):
# Ce devis a déjà ete validée, donc pas de relance
is_quotation_validated = 1
#print( "### local_devis a traiter = ", local_devis)
relance_done = 0
nb_limite_relance = 0
if( "nb_relance" in local_devis.keys() and local_devis['nb_relance']):
relance_done = mycommon.tryInt(str(local_devis['nb_relance']))
if ("nb_relance_auto" in local_devis.keys() and local_devis['nb_relance_auto']):
nb_limite_relance = mycommon.tryInt(str(local_devis['nb_relance_auto']))
date_derniere_relance_auto = "01/12/2099"
if( "date_dernier_relance_auto" in local_devis.keys() and local_devis['date_dernier_relance_auto'] ):
date_derniere_relance_auto = str(local_devis['date_dernier_relance_auto'])[0:10]
date_derniere_relance_auto_ISODATE = datetime.strptime(str(date_derniere_relance_auto), '%d/%m/%Y')
frequence_relance_auto = 0
if ("frequence_relance_auto" in local_devis.keys() and local_devis['frequence_relance_auto']):
frequence_relance_auto = mycommon.tryInt(str(local_devis['frequence_relance_auto']))
new_relance_date_ISODATE = date_derniere_relance_auto_ISODATE + timedelta(days=frequence_relance_auto)
print(" ### LA frequence_relance_auto ", frequence_relance_auto)
print(" ### LA dernière relance date de ", date_derniere_relance_auto)
print(" ### LA PROCHAINE RELANCE EST ", new_relance_date_ISODATE)
new_relance_date_no_ISODATE = str(new_relance_date_ISODATE.strftime("%d/%m/%Y"))
print(" ### LA PROCHAINE RELANCE EST (new_relance_date_no_ISODATE) ", new_relance_date_no_ISODATE)
datetime.strptime(str(todays_date), '%d/%m/%Y')
if( datetime.strptime(str(todays_date), '%d/%m/%Y') >= datetime.strptime( str(new_relance_date_no_ISODATE).strip(), '%d/%m/%Y') ):
print(" ### todays_date est SUPERIEUR = new_relance_date_ISODATE")
else:
print(" ### todays_date est INFERIEUR new_relance_date_ISODATE")
if( is_quotation_validated == 0 and relance_done <= nb_limite_relance and datetime.strptime(str(todays_date), '%d/%m/%Y') >= datetime.strptime( str(new_relance_date_no_ISODATE).strip(), '%d/%m/%Y') ):
print(" ### OUIIII on fait la relanceeeeeeeeeeeee")
"""
On fait le traitement, on envoie le mail
1 - recuperation des data
"""
local_status, my_partner = mycommon.Get_Connected_User_Partner_Data_From_RecID(str(local_devis['partner_owner_recid']))
if (local_status is not True):
return local_status, my_partner
tab_client = []
tab_client.append(ObjectId(str(local_devis['order_header_client_id'])))
local_diction = {'token':str(my_partner['token']), 'order_id': str(local_devis['_id'])}
local_send_remind_status, local_send_remind_retval = partner_order.Send_Quotation_Remind_Level1(local_diction)
print(" relance return local_send_remind_status = ", local_send_remind_status)
if( local_send_remind_status is True):
print(" RELANCE FAIT ET OK ")
"""
Une fois la relance faite, on met à jour le devis avec les infos suivant :
- liste_relance
"""
frequence_relance_auto_reached = "0"
if("list_relance" in local_devis.keys() and local_devis['list_relance']):
local_node = {}
local_node['date_relance'] = str(date.today())
local_node['mesg_relance'] = str(local_send_remind_retval)
local_devis['list_relance'].append(local_node)
else :
local_node = {}
local_node['date_relance'] = str(date.today())
local_devis['list_relance'] = []
local_devis['list_relance'].append(local_node)
local_node['mesg_relance'] = str(local_send_remind_retval)
nb_relance = str(len(local_devis['list_relance']))
local_data_update = local_devis
id_to_update = str(local_data_update['_id'])
del local_data_update['_id']
del local_data_update['mysy_devis_expiration_date']
local_data_update['nb_relance'] = str(nb_relance)
local_data_update['date_dernier_relance_auto'] = str(todays_date)
result = MYSY_GV.dbname['partner_order_header'].find_one_and_update(
{'_id': ObjectId(str(id_to_update)),
'valide': '1',
'locked': '0'},
{"$set": local_data_update},
upsert=False,
return_document=ReturnDocument.AFTER
)
else:
print(" ### NoNNNNNNNNNN on NEEEE fait la relanceeeeeeeeeeeee")
print(" limite relance atteint : ")
print(" limite relance_done : ", relance_done)
print(" limite nb_limite_relance : ", nb_limite_relance)
return True, ""
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, str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno)