795 lines
33 KiB
Python
795 lines
33 KiB
Python
# -*- coding: utf8 -*-
|
|
from pyramid.renderers import render, get_renderer
|
|
from pyramid.response import Response
|
|
from pyramid.view import (
|
|
view_config,
|
|
forbidden_view_config,
|
|
)
|
|
from pyramid.httpexceptions import (
|
|
HTTPFound,
|
|
)
|
|
|
|
from datetime import *
|
|
from time import strftime, sleep
|
|
from email.utils import formataddr
|
|
from urllib.request import urlopen
|
|
from urllib.parse import quote
|
|
|
|
from pyramid_mailer import get_mailer
|
|
from pyramid_mailer.message import Message, Attachment
|
|
import json
|
|
|
|
from ..models.reservation import *
|
|
from ..models.default import *
|
|
|
|
from ..views.default import (
|
|
to_euro,
|
|
to_date,
|
|
to_time,
|
|
to_int,
|
|
to_percent,
|
|
envoyerMail,
|
|
getConfirmText,
|
|
getMessageText,
|
|
)
|
|
|
|
|
|
@view_config(route_name='carnet_rdv', renderer='../templates/reservation/carnet_rdv.pt', permission='view')
|
|
def carnet_rdv(request):
|
|
"""Carnet de rendez-vous view"""
|
|
logged_in = request.authenticated_userid
|
|
eleve_info = get_eleve_info(request, logged_in)
|
|
|
|
ajoutRDVB = ""
|
|
ajoutPlateau = ""
|
|
ajoutRoute = ""
|
|
ajoutTA = ""
|
|
if eleve_info['permis'] == 'B' or eleve_info['permis'] == 'B78':
|
|
# si permis B, autoriser ajouter rdv B
|
|
ajoutRDVB = request.route_url('rdvb_dispo')
|
|
elif eleve_info['permis'] == 'A1' or eleve_info['permis'] == 'A2':
|
|
try:
|
|
# déterminer les ajouts de RDV possibles selon le suivi pédagogique
|
|
html = urlopen('https://suivi-eleve.marietton.com/CONTROLES/CTRL-suiviA2.php?codeE=' + logged_in)
|
|
# analyser la réponse : X;ZZ-2020 : X plateau / ZZ mois de examen prevu
|
|
rep = html.read().decode("utf-8")
|
|
reponse = rep.split(';')
|
|
# niveau de l'élève renseigné ?
|
|
|
|
niveau = reponse[0]
|
|
if niveau != '':
|
|
# niveau de l'élève après le 1er plateau
|
|
if niveau != '0':
|
|
# eleve a-t-il eu son examen pratique ? oui, ne plus proposer ajout PLATEAU
|
|
if ctl_pratique_ok(request, logged_in):
|
|
ajoutPlateau = ''
|
|
else:
|
|
ajoutPlateau = request.route_url('rdva_dispo', type_lecon='PLATEAU')
|
|
|
|
if niveau == '1':
|
|
plateau_min = 3 # niveau = 1, eleve doit avoir min 3 plateaux pour prendre des routes
|
|
else:
|
|
plateau_min = 2
|
|
# eleve a-t-il le niveau pour faire la route ?
|
|
if ctl_heures_plateau(request, logged_in) >= plateau_min:
|
|
ajoutRoute = request.route_url('rdva_dispo', type_lecon='ROUTE')
|
|
else:
|
|
ajoutRoute = ''
|
|
|
|
if reponse[1] != '0':
|
|
# l' éève a déjà un examen blanc, il ne peut plus en ajouter
|
|
if ctl_heures_TA(request, logged_in):
|
|
ajoutTA = ''
|
|
else:
|
|
ajoutTA = request.route_url('rdva_dispo', type_lecon='EXAM BLANC')
|
|
except Exception as e :
|
|
pass
|
|
# lire les rdv de l'élève
|
|
items = get_rdv_by_code(request, logged_in)
|
|
|
|
return {
|
|
'page_title': "Carnet de rendez-vous",
|
|
'items': items,
|
|
'ajoutRDVB': ajoutRDVB,
|
|
'ajoutPlateau': ajoutPlateau,
|
|
'ajoutRoute': ajoutRoute,
|
|
'ajoutTA': ajoutTA,
|
|
'now': datetime.now(),
|
|
}
|
|
|
|
|
|
@view_config(route_name='rdvb_del', renderer='../templates/reservation/rdvb_del.pt', permission='view')
|
|
def rdvb_del(request):
|
|
logged_in = request.authenticated_userid
|
|
pla_ligne = request.matchdict["no_ligne"]
|
|
|
|
# lire le rendez-vous dans le carnet
|
|
item = get_rdvB_by_no(request, pla_ligne)
|
|
if not item:
|
|
request.session.flash("Le rendez-vous no %s n'existe pas." % pla_ligne, 'danger')
|
|
return HTTPFound(location=request.route_url('carnet_rdv'))
|
|
if item.NoPlan == 0:
|
|
# RDV déjà supprimé, le client a cliqué 2 fois ?
|
|
return HTTPFound(location=request.route_url('carnet_rdv'))
|
|
|
|
# controle heure spéciale ?
|
|
if item.CIRCUIT > 0:
|
|
request.session.flash('Veuillez contacter <a href="/agence">votre agence</a> pour annuler ce rendez-vous (%s).' % item.INTITULE[:-4], 'danger')
|
|
return HTTPFound(location=request.route_url('carnet_rdv'))
|
|
if 'AVT PERMIS' in item.COMMENT.upper() or 'AVANT PERMIS' in item.COMMENT.upper():
|
|
request.session.flash('Veuillez contacter <a href="/agence">votre agence</a> pour annuler ce rendez-vous (AVANT PERMIS).', 'danger')
|
|
return HTTPFound(location=request.route_url('carnet_rdv'))
|
|
|
|
# controler le délai annulation ?
|
|
delaiOK = ctl_delai_annul(request, item.DATE, item.NoPlan, item.cree_le - timedelta(days=10), item.STATUT)
|
|
|
|
if 'form.submitted' in request.params:
|
|
if delaiOK == True :
|
|
# mise à jour de la ligne comme annulée
|
|
upd_eleves_rdv_annule(request, 'B', pla_ligne, logged_in)
|
|
statut_rdv = ""
|
|
jour_rdv = "d'%s" % item.DATE.strftime('%d-%m-%Y')
|
|
type_msg = "annulP48"
|
|
# créer la même heure en dispo web
|
|
update_rdvb(request, 0, 0, 99995, item.DATE, item.NoPlan, item.QTE, "HCB", item.CD_MON, item.AGENCE, '', 0, 0, 0, 0, 'WEB')
|
|
# logger dans t_log_nuit
|
|
ins_t_log_nuit(request, 'ANNUL+48', '%s %s %sh -> %s - %s' % (item.REF, item.DATE.strftime('%d-%m-%Y'), item.NoPlan, logged_in, item.NOM))
|
|
message = "Votre rendez-vous du %s à %sh00 a été annulé." % (item.DATE.strftime('%d-%m-%Y'), item.NoPlan)
|
|
else:
|
|
# mise à jour de la ligne comme annulée -48h
|
|
upd_eleves_rdv_statut3(request, 'B', pla_ligne)
|
|
# logger dans t_log_nuit
|
|
ins_t_log_nuit(request, 'ANNUL-48', '%s -> %s - %s' % (item.REF, logged_in, item.NOM))
|
|
statut_rdv = "- URGENT -"
|
|
type_msg = "annulM48"
|
|
if item.DATE == date.today():
|
|
jour_rdv = "d'AUJOURD'HUI"
|
|
else:
|
|
jour_rdv = "de DEMAIN"
|
|
message = "Votre rendez-vous du %s à %sh00 a été proposé aux autres élèves." % (item.DATE.strftime('%d-%m-%Y'), item.NoPlan)
|
|
|
|
# envoyer un message à la secrétaire
|
|
agence_email = get_eleve_agence(request, logged_in).email
|
|
# Fabrication du corps du Message
|
|
body = getMessageText(request, 'annuleRDV',
|
|
item.NOM, logged_in, '%s à %s h' % (jour_rdv, item.NoPlan), 'B', item.INTITULE + item.COMMENT)
|
|
destinataires=[agence_email]
|
|
envoyerMail(request, destinataires, "%s Annulation de rendez-vous en ligne" % statut_rdv, body)
|
|
|
|
# envoyer un message au moniteur via la tablette
|
|
date_heure = '%s %s:00' % (item.DATE.strftime('%d-%m-%Y'), str(item.NoPlan).zfill(2))
|
|
intitule = item.INTITULE
|
|
url = 'https://suivi-eleve.marietton.com/MSG-fromAEM.php?codeE=%s&dest=%s&msgType=%s&date=%s&qte=%s&type=%s' \
|
|
% (logged_in, item.CD_MON, type_msg, quote(date_heure), item.QTE, quote(intitule))
|
|
html = urlopen(url)
|
|
# nlus = html.read()
|
|
|
|
request.session.flash(message, 'success')
|
|
return HTTPFound(location=request.route_url('carnet_rdv'))
|
|
|
|
return {
|
|
'page_title': "Annulation de rendez-vous",
|
|
'item': item,
|
|
'delaiOK': delaiOK,
|
|
}
|
|
|
|
@view_config(route_name='rdvb_add', renderer='../templates/reservation/rdvb_add.pt', permission='view')
|
|
def rdvb_add(request):
|
|
logged_in = request.authenticated_userid
|
|
pla_ligne = request.matchdict["no_ligne"]
|
|
message = ''
|
|
|
|
# lire le rendez-vous dans le planning B
|
|
item = get_rdvB_by_no(request, pla_ligne)
|
|
if not item:
|
|
request.session.flash(u"Le rendez-vous no %s n'existe pas." % pla_ligne, 'danger')
|
|
return HTTPFound(location=request.route_url('carnet_rdv'))
|
|
if item.NoPlan == 0:
|
|
# RDV déjà pris, le client a fait cliqué 2 fois ?
|
|
return HTTPFound(location=request.route_url('carnet_rdv'))
|
|
|
|
# controler le délai annulation ?
|
|
delaiOK = ctl_delai_annul(request, item.DATE, item.NoPlan, item.cree_le + timedelta(days=10), item.STATUT)
|
|
|
|
# controler heures autorisées
|
|
err_msg = {1 : 'Vous avez déjà un rendez-vous à la même date et même heure, le ',
|
|
2 : 'Vous allez dépasser les 2h de leçon maximum par jour, le ',
|
|
3 : 'Vous allez dépasser les 4h de leçon maximum par semaine du ',
|
|
}
|
|
retour = ctl_heures_resaB(request, logged_in, logged_in, item.CD_MON, item.DATE, item.NoPlan, item.QTE)
|
|
if retour > 0 :
|
|
request.session.flash(err_msg[retour] + item.DATE.strftime('%d-%m-%Y'), 'danger')
|
|
return HTTPFound(location=request.route_url("rdvb_dispo"))
|
|
|
|
if 'form.submitted' in request.params:
|
|
nDelai = ctl_solde_resa(request, int(logged_in), "HCB")
|
|
# plafond dépassé ?
|
|
if nDelai == -1:
|
|
message = "Votre encours a dépassé son plafond autorisé. Impossible d'ajouter une heure."
|
|
else:
|
|
update_rdvb(request, item.no_ligne, item.CD_CLI, int(logged_in), item.DATE, item.NoPlan, item.QTE, "HCB", item.CD_MON, item.AGENCE, '', 0, 0, nDelai, item.cd_cli_old, 'WEB')
|
|
|
|
eleve = get_eleves_by_code(request, logged_in)
|
|
# lire le compte
|
|
cptes = get_eleve_cpt_extrait(request, logged_in)
|
|
# calculer le solde de > 0'élève
|
|
sum_to_pay = 0
|
|
sum_paid = 0
|
|
for cpt in cptes:
|
|
sum_to_pay += float(cpt.DEBIT)
|
|
sum_paid += float(cpt.CREDIT)
|
|
solde = sum_paid + eleve.encours_societe - sum_to_pay
|
|
|
|
# logger dans t_log_nuit
|
|
ins_t_log_nuit(request, 'AJOUT-' + str(nDelai), '%s %s %sh -> %s - %s' % (item.REF, item.DATE.strftime('%d-%m-%Y'), item.NoPlan, logged_in, eleve.NOMPREN))
|
|
|
|
if nDelai == 0:
|
|
request.session.flash(u"Le rendez-vous a été CONFIRME avec succès.", 'success')
|
|
else:
|
|
request.session.flash(u"Le rendez-vous a été RESERVE avec succès.", 'warning')
|
|
|
|
nompren = "%s %s %s" % (eleve.CIVILITE, eleve.NOM, eleve.PRENOM)
|
|
if solde >= 0:
|
|
# heure confirmée
|
|
body = getConfirmText(request, 'HCB', nompren, logged_in,
|
|
'%s à %s:00' % (item.DATE.strftime('%d-%m-%Y'), item.NoPlan), item.moniteur, item.QTE)
|
|
|
|
envoyerMail(request, [eleve.email], "Votre réservation a été confirmée", body)
|
|
return HTTPFound(location=request.route_url("carnet_rdv"))
|
|
else:
|
|
# heure réservée
|
|
body = getConfirmText(request, 'HCBR', nompren, logged_in,
|
|
'%s à %s:00' % (item.DATE.strftime('%d-%m-%Y'), item.NoPlan), '', '')
|
|
|
|
envoyerMail(request, [eleve.email], "Votre réservation a été prise en compte", body)
|
|
return HTTPFound(location=request.route_url("confirm_rdv"))
|
|
|
|
return {
|
|
'page_title': "Réserver un rendez-vous",
|
|
'message': message,
|
|
'item': item,
|
|
'delaiOK': delaiOK,
|
|
}
|
|
|
|
@view_config(route_name='rdvb_dispo', renderer='../templates/reservation/rdvb_dispo.pt', permission='view')
|
|
def rdvb_dispo(request):
|
|
|
|
def generer_planning(cd_cli):
|
|
|
|
rows = get_rdvb_dispos(request, cd_cli)
|
|
|
|
# construire la liste des events
|
|
dateMin = date.today() + timedelta(days=365) # today + 1 year
|
|
events = []
|
|
for row in rows:
|
|
# heure du créneau dispo est passée ? oui, ignorer
|
|
if not (row.DATE == date.today() and row.noplan <= datetime.now().hour and (row.cd_cli==99995 or row.statut==3)):
|
|
# déterminer la date la plus récente
|
|
if row.DATE < dateMin:
|
|
dateMin = row.DATE
|
|
# déterminer la couleur de l'event
|
|
if row.cd_cli == int(cd_cli) :
|
|
color = 'LightBlue' # rdv élève
|
|
url = ''
|
|
elif row.statut == 3 or row.cd_cli == 99995:
|
|
color = 'LightGreen' # creneau disponible
|
|
url = '/rdvb_add/%s' % (row.no_ligne)
|
|
else:
|
|
color = 'LightYellow' # ???
|
|
url = ''
|
|
|
|
json_event = {
|
|
'title': '%sh %s' % (row.qte, row.nom_moniteur),
|
|
'start': '%s %02d:00:00' % (row.DATE.strftime('%Y-%m-%d'), row.noplan),
|
|
'end': '%s %02d:00:00' % (row.DATE.strftime('%Y-%m-%d'), row.noplan + row.qte),
|
|
'allDay': False,
|
|
'color': color,
|
|
'textColor': '#000000',
|
|
'url': url,
|
|
}
|
|
events.append(json_event)
|
|
return events, dateMin
|
|
|
|
# récupérer les paramètres de l'appel de la view
|
|
logged_in = request.authenticated_userid
|
|
message = ''
|
|
|
|
# generer le calendrier des dispos
|
|
events, dateMin = generer_planning(logged_in)
|
|
|
|
datePlan = dateMin.strftime('%Y-%m-%d')
|
|
|
|
return {
|
|
'page_title': "Prise de rendez-vous",
|
|
'datePlan': datePlan,
|
|
'message': message,
|
|
'fullcalendar_events': json.dumps(events),
|
|
'nb_events': len(events),
|
|
}
|
|
|
|
@view_config(route_name='extrait_compte', renderer='../templates/reservation/extrait_compte.pt', permission='view')
|
|
@view_config(route_name='confirm_rdv', renderer='../templates/reservation/extrait_compte.pt', permission='view')
|
|
def extrait_compte(request):
|
|
"""Extrait de compte view"""
|
|
|
|
if 'confirm_rdv' in request.current_route_path():
|
|
confirm_rdv = True
|
|
page_title = "Récap sur mon en-cours"
|
|
else:
|
|
confirm_rdv = False
|
|
page_title = "Mon en-cours"
|
|
|
|
logged_in = request.authenticated_userid
|
|
eleve = get_eleves_by_code(request, logged_in)
|
|
# get compte
|
|
items = get_eleve_cpt_extrait(request, logged_in)
|
|
|
|
# calculate sums
|
|
sum_to_pay = 0
|
|
sum_paid = 0
|
|
for item in items:
|
|
sum_to_pay += float(item.DEBIT)
|
|
sum_paid += float(item.CREDIT)
|
|
|
|
# ajouter la prise en charge de la societe
|
|
sum_paid += eleve.encours_societe
|
|
solde = float(sum_to_pay - sum_paid)
|
|
|
|
if 'form.submitted' in request.params:
|
|
return HTTPFound(location=request.route_url('reglement', ref='CPT', mttotal=solde, nfois='1'))
|
|
|
|
return {
|
|
'page_title': page_title,
|
|
'items': items,
|
|
'sum_to_pay': to_euro(sum_to_pay),
|
|
'sum_paid': to_euro(sum_paid),
|
|
'today': strftime("%d/%m/%Y"),
|
|
'solde': solde,
|
|
'remain_to_pay': to_euro(solde * -1),
|
|
'member_has_email': bool(eleve.email),
|
|
'pec_designation': 'PRISE EN CHARGE %s' % eleve.NOM_ENTREPRISE,
|
|
'pec_montant': eleve.encours_societe,
|
|
'confirm_rdv': confirm_rdv,
|
|
}
|
|
|
|
@view_config(route_name='rdva_del', renderer='../templates/reservation/rdva_del.pt', permission='view')
|
|
def rdva_del(request):
|
|
logged_in = request.authenticated_userid
|
|
pla_ligne = request.matchdict["no_ligne"]
|
|
|
|
# lire le rendez-vous dans le carnet
|
|
item = get_rdvA_by_no(request, pla_ligne)
|
|
if not item:
|
|
request.session.flash(u"Le rendez-vous no %s n'existe pas." % pla_ligne, 'danger')
|
|
return HTTPFound(location=request.route_url('carnet_rdv'))
|
|
|
|
# controle heure spéciale ?
|
|
if item.LIBELLE.find('1er pla') == 0:
|
|
request.session.flash('Veuillez contacter <a href="/agence">votre agence</a> pour annuler ce rendez-vous (%s).' % item.LIBELLE, 'danger')
|
|
return HTTPFound(location=request.route_url('carnet_rdv'))
|
|
|
|
# controler le délai annulation ?
|
|
delaiOK = ctl_delai_annul(request, item.DATE, 8, item.cree_le - timedelta(days=10), item.STATUT)
|
|
|
|
if 'form.submitted' in request.params:
|
|
if delaiOK == True :
|
|
# mise à jour de la ligne comme annulée
|
|
upd_eleves_rdv_annule(request, 'A', pla_ligne, logged_in, )
|
|
statut_rdv = ""
|
|
jour_rdv = "du %s" % item.DATE.strftime('%d-%m-%Y')
|
|
# logger dans t_log_nuit
|
|
ins_t_log_nuit(request, 'ANNUL+48', '%s %s -> %s - %s' % (item.REF, item.DATE.strftime('%d-%m-%Y'), logged_in, item.NOM))
|
|
message = "Votre rendez-vous %s a été annulé." % jour_rdv
|
|
else:
|
|
# mise à jour de la ligne comme annulée -48h
|
|
upd_eleves_rdv_statut3(request, 'A', pla_ligne)
|
|
# logger dans t_log_nuit
|
|
ins_t_log_nuit(request, 'ANNUL-48', '%s %s -> %s - %s' % (item.REF, item.DATE.strftime('%d-%m-%Y'), logged_in, item.NOM))
|
|
statut_rdv = "- URGENT -"
|
|
if item.DATE == date.today():
|
|
jour_rdv = "d'AUJOURD'HUI"
|
|
else:
|
|
jour_rdv = "de DEMAIN"
|
|
message = "Votre rendez-vous %s a été proposé aux autres élèves." % jour_rdv
|
|
|
|
# envoyer un message à la secrétaire
|
|
agence_email = get_eleve_agence(request, logged_in).email
|
|
# Fabrication du corps du Message
|
|
body = getMessageText(request, 'annuleRDV', item.NOM, logged_in, jour_rdv, 'A', '')
|
|
destinataires=[agence_email]
|
|
envoyerMail(request, destinataires, "%s Annulation de rendez-vous en ligne" % statut_rdv, body)
|
|
|
|
request.session.flash(message, 'success')
|
|
return HTTPFound(location=request.route_url('carnet_rdv'))
|
|
|
|
return {
|
|
'page_title': "Annulation de rendez-vous",
|
|
'item': item,
|
|
'delaiOK': delaiOK,
|
|
}
|
|
|
|
@view_config(route_name='rdva_add', renderer='../templates/reservation/rdva_add.pt', permission='view')
|
|
def rdva_add(request):
|
|
logged_in = request.authenticated_userid
|
|
rdv_cli = request.matchdict["cd_cli"]
|
|
if rdv_cli == logged_in:
|
|
# ne peut pas prendre ce lecon en statut=3
|
|
return HTTPFound(location=request.route_url('carnet_rdv'))
|
|
|
|
|
|
rdv_id = request.matchdict["rdv_id"]
|
|
rdv_type = rdv_id[0]
|
|
rdv_date = rdv_id[1:11]
|
|
rdv_groupe = rdv_id[11:12]
|
|
rdv_lecon = rdv_id[12]
|
|
if rdv_lecon == 'P':
|
|
lecon = "une leçon PLATEAU"
|
|
ref = 'HCA3'
|
|
route = 0
|
|
elif rdv_lecon == 'R':
|
|
lecon = "une leçon ROUTE"
|
|
ref = 'HCA3'
|
|
route = -1
|
|
else:
|
|
lecon = "un examen blanc"
|
|
ref = 'TA'
|
|
route = 0
|
|
# une seule lecon TA
|
|
if ctl_heures_TA(request, logged_in) :
|
|
request.session.flash('Vous avez déjà un examen blanc programmé.', 'danger')
|
|
return HTTPFound(location=request.route_url("carnet_rdv"))
|
|
|
|
|
|
# obtenir heure de debut et duree lecon
|
|
debut, duree = getHeureDureeLeconA(rdv_type, rdv_groupe)
|
|
# date du rdv en format date
|
|
madate = datetime.strptime(rdv_date, '%Y-%m-%d')
|
|
date_rdv = '%s à %s h' % (madate.strftime('%d-%m-%Y'), debut)
|
|
|
|
# controle délai
|
|
delaiOK = ctl_delai_annul_A(request, madate)
|
|
message = ''
|
|
|
|
# controler heures autorisées
|
|
msg_retour = ctl_heures_resaA(request, rdv_lecon, logged_in, rdv_date, rdv_groupe)
|
|
if msg_retour != '' :
|
|
request.session.flash(msg_retour, 'danger')
|
|
return HTTPFound(location=request.route_url("carnet_rdv"))
|
|
|
|
if 'form.submitted' in request.params:
|
|
|
|
if rdv_cli != '0':
|
|
# cas de lecçon avec statut 3, relire le rdv
|
|
item = get_rdvA_by_id(request, rdv_type, rdv_date, rdv_groupe, rdv_cli)
|
|
if not item:
|
|
request.session.flash(u"Le rendez-vous no %s n'existe pas." % rdv_id, 'danger')
|
|
return HTTPFound(location=request.route_url('carnet_rdv'))
|
|
|
|
nDelai = ctl_solde_resa(request, int(logged_in), "HCA3")
|
|
# plafond dépassé ?
|
|
if nDelai == -1:
|
|
message = "Votre encours a dépassé son plafond autorisé. Impossible d'ajouter une leçon."
|
|
else:
|
|
update_rdva(request, rdv_type, rdv_date, rdv_groupe, int(rdv_cli), int(logged_in), duree, ref, route, nDelai)
|
|
|
|
eleve = get_eleves_by_code(request, logged_in)
|
|
# lire le compte
|
|
cptes = get_eleve_cpt_extrait(request, logged_in)
|
|
# calculer le solde de l'élève
|
|
sum_to_pay = 0
|
|
sum_paid = 0
|
|
for cpt in cptes:
|
|
sum_to_pay += float(cpt.DEBIT)
|
|
sum_paid += float(cpt.CREDIT)
|
|
solde = sum_paid + eleve.encours_societe - sum_to_pay
|
|
|
|
# logger dans t_log_nuit
|
|
ins_t_log_nuit(request, 'AJOUT-' + str(nDelai), '%s %s G:%s -> %s - %s' % (ref, date_rdv, rdv_groupe, logged_in, eleve.NOMPREN))
|
|
|
|
if nDelai == 0:
|
|
request.session.flash(u"Le rendez-vous a été CONFIRME avec succès.", 'success')
|
|
else:
|
|
request.session.flash(u"Le rendez-vous a été RESERVE avec succès.", 'warning')
|
|
|
|
nompren = "%s %s %s" % (eleve.CIVILITE, eleve.NOM, eleve.PRENOM)
|
|
if solde >= 0:
|
|
# heure confirmée
|
|
body = getConfirmText(request, ref, nompren, logged_in, date_rdv, lecon, str(duree))
|
|
|
|
envoyerMail(request, [eleve.email], "Votre réservation a été confirmée", body)
|
|
return HTTPFound(location=request.route_url("carnet_rdv"))
|
|
else:
|
|
# heure réservée
|
|
body = getConfirmText(request, 'HCAR', nompren, logged_in, date_rdv, '', '')
|
|
|
|
envoyerMail(request, [eleve.email], "Votre réservation a été prise en compte", body)
|
|
return HTTPFound(location=request.route_url("confirm_rdv"))
|
|
|
|
return {
|
|
'page_title': "Réserver %s" % lecon,
|
|
'message': message,
|
|
'date_rdv': date_rdv,
|
|
'duree': duree,
|
|
'delaiOK': delaiOK,
|
|
}
|
|
|
|
@view_config(route_name='rdva_dispo', renderer='../templates/reservation/rdva_dispo.pt', permission='view')
|
|
def rdva_dispo(request):
|
|
|
|
def generer_planning(type_lecon, cd_cli):
|
|
|
|
rows = get_rdva_dispos(request, type_lecon, cd_cli)
|
|
|
|
# construire la liste des events
|
|
dateMin = date.today() + timedelta(days=365) # today + 1 year
|
|
events = []
|
|
for row in rows:
|
|
# identifiant du rdv = id du planning ligne + 1er car du type de lecon
|
|
rdv_id = row.type + row.date.strftime('%Y-%m-%d') + row.groupe + type_lecon[0]
|
|
# déterminer la date la plus récente
|
|
if row.date < dateMin:
|
|
dateMin = row.date
|
|
# déterminer le début et la durée de la leçon
|
|
debut, duree = getHeureDureeLeconA(row.type, row.groupe)
|
|
|
|
# déterminer la couleur de la leçon
|
|
if row.cd_cli == int(cd_cli) :
|
|
color = 'LightBlue' # rdv élève
|
|
url = ''
|
|
elif row.cd_cli > 0:
|
|
color = 'LightGreen' # séance avec statut 3
|
|
url = '/rdva_add/%s/%s' % (rdv_id, row.cd_cli)
|
|
else:
|
|
color = 'LightGreen' # séance normale
|
|
url = '/rdva_add/%s/0' % (rdv_id)
|
|
|
|
json_event = {
|
|
'title': str(duree) + ' h',
|
|
'start': '%s %02d:00:00' % (row.date.strftime('%Y-%m-%d'), debut),
|
|
'end': '%s %02d:00:00' % (row.date.strftime('%Y-%m-%d'), debut + duree),
|
|
'allDay': False,
|
|
'color': color,
|
|
'textColor': '#000000',
|
|
'url': url,
|
|
}
|
|
events.append(json_event)
|
|
return events, dateMin
|
|
|
|
# récupérer les paramètres de l'appel de la view
|
|
logged_in = request.authenticated_userid
|
|
type_lecon = request.matchdict["type_lecon"]
|
|
message = ''
|
|
|
|
# lire le Max leçons A par semaine
|
|
agence6 = get_agences(request, 6)
|
|
if agence6.MaxLeconASemaine == 0:
|
|
request.session.flash('La réservation de leçon A est temporairement suspendue. Veuillez revenir plus tard', 'danger')
|
|
return HTTPFound(location=request.route_url("carnet_rdv"))
|
|
|
|
|
|
# generer le calendrier des dispos
|
|
events, dateMin = generer_planning(type_lecon, logged_in)
|
|
|
|
datePlan = dateMin.strftime('%Y-%m-%d')
|
|
# compter les séances dispo
|
|
nb = 0
|
|
for item in events :
|
|
if item['url'] != '':
|
|
nb += 1
|
|
|
|
return {
|
|
'page_title': "Disponiblités %s" % type_lecon,
|
|
'datePlan': datePlan,
|
|
'message': message,
|
|
'fullcalendar_events': json.dumps(events),
|
|
'nb_events': nb,
|
|
}
|
|
|
|
def getHeureDureeLeconA(type, groupe):
|
|
# déterminer le début et la durée de la leçon
|
|
if type == "A":
|
|
duree = 3
|
|
if groupe == "F" or groupe == "G":
|
|
debut = 13
|
|
elif groupe == "B":
|
|
debut = 12
|
|
elif groupe == "C":
|
|
debut = 15
|
|
elif groupe == "D":
|
|
debut = 18
|
|
else:
|
|
# groupes A et E
|
|
debut = 8
|
|
else:
|
|
# groupe F : exmaen blanc
|
|
debut = ord(groupe) - 57
|
|
duree = 1
|
|
|
|
return debut, duree
|
|
|
|
@view_config(route_name='batch_jour')
|
|
def batch_jour(request):
|
|
"""
|
|
Ce traitement est lancé périodiquement sur le serveur du site web, par une tâche planifiée :
|
|
- Executer en tant que : root
|
|
- Commande : wget http://localhost:6543/batch_jour/Arya5tark
|
|
- Quand executer : chaque jour, tous les 5 minutes
|
|
Par sécurité, ce view ne peut être appelé qu'avec un paramètre secret 'Arya5tark'
|
|
|
|
Il a pour but de confirmer les réservations effectuées par le WEB
|
|
|
|
"""
|
|
# contrôle : paramètre correct ? ? non, terminer
|
|
par = request.matchdict['param']
|
|
if par != 'Arya5tark':
|
|
return Response('Erreur : paramètre incorrect')
|
|
|
|
# =============== CONFIRMATION DES INSCRIPTIONS ===================
|
|
confirm_inscriptions(request)
|
|
# attendre 5 secondes
|
|
sleep(5)
|
|
|
|
# ----- lancer les notifications inscription
|
|
notifier_reservations(request, 'INSCR')
|
|
|
|
return Response('Batch jour terminé OK')
|
|
|
|
|
|
def confirm_inscriptions(request):
|
|
"""
|
|
- LIRE LES RESA des PLANNINGS B et A
|
|
- REMPLIR la table EMAILS_RESA
|
|
|
|
"""
|
|
|
|
TODAY = date.today()
|
|
|
|
# LIRE LES RESA des PLANNINGS B et A
|
|
resas = get_inscriptions(request)
|
|
for resa in resas:
|
|
# controler le solde REEL de l'élève
|
|
eleve = get_solde_eleve(request, resa.cd_cli, resa.ref)
|
|
if eleve.solde >= 0 :
|
|
# -- confirmer inscription STAGES
|
|
update_reservation_confirm(request, "C", resa.no_ligne, resa.ref, resa.statut, resa.cd_cli_old)
|
|
if resa.ref in ["POINT", "PEM125", "PASSERELLE", "B96", "CODE"] :
|
|
# -- creer une notification de confirmation STAGE
|
|
insert_email_resa(request, resa.ref, resa.cd_cli, "Inscr.", resa.date, resa.noplan, "CONFIRMEE")
|
|
elif resa.ref == "HCB" :
|
|
# -- creer une notification de confirmation HEURE
|
|
insert_email_resa(request, resa.ref, resa.cd_cli, "WEB_B", resa.date, resa.noplan, "CONFIRMEE")
|
|
# -- heure annuléen hors dleai HCB ?
|
|
if resa.statut == 3 and resa.cd_cli_old > 0 :
|
|
# -- creer une notification de l'ancien élève
|
|
insert_email_resa(request, resa.ref, resa.cd_cli_old, "WEB_48H", resa.date, resa.noplan, "CONFIRMEE")
|
|
else:
|
|
# -- fin de résa a dépassé de 10 mn ?
|
|
delai = (datetime.now() - resa.cree_le).total_seconds()/60
|
|
if round(delai) > 10:
|
|
#-- annuler l'inscription
|
|
update_reservation_confirm(request, "A", resa.no_ligne, resa.ref, resa.statut, resa.cd_cli_old)
|
|
if resa.ref in ["POINT", "PEM125", "PASSERELLE", "B96", "CODE"] :
|
|
# -- creer une notification de annulation
|
|
insert_email_resa(request, resa.ref, resa.cd_cli, "Inscr.", resa.date, resa.noplan, "ANNULEE")
|
|
elif resa.ref in ["TA", "HCA3"] :
|
|
# -- creer une notification de confirmation HEURE MOTO
|
|
insert_email_resa(request, resa.ref, resa.cd_cli, "WEB_A", resa.date, resa.noplan, "ANNULEE")
|
|
elif resa.ref in ["TB", "HCB"] :
|
|
# -- creer une notification de confirmation HEURE
|
|
insert_email_resa(request, resa.ref, resa.cd_cli, "WEB_B", resa.date, resa.noplan, "ANNULEE")
|
|
|
|
|
|
def notifier_reservations(request, type_resa):
|
|
|
|
# lire les rappels non encore envoyés
|
|
rappels = get_email_resa(request, type_resa)
|
|
|
|
nbLus = 0
|
|
nbConfirmes = 0
|
|
nbAnnules = 0
|
|
|
|
for item in rappels:
|
|
# import pdb;pdb.set_trace()
|
|
nbLus += 1
|
|
# Résa ayant une heure (HCB) ?
|
|
if item.resa_date.hour > 0 :
|
|
date_heure = item.resa_date.strftime('%d/%m/%Y - %H:%M')
|
|
else:
|
|
date_heure = item.resa_date.strftime('%d/%m/%Y')
|
|
|
|
noAgence = item.agence
|
|
if item.resa_statut == "CONFIRMEE" :
|
|
nbConfirmes += 1
|
|
confirm = "CONFIRMEE"
|
|
else:
|
|
nbAnnules += 1
|
|
confirm = "ANNULEE, faute de crédit suffisant"
|
|
if item.ref == "HCA3" or item.resa_type == "Inscr.":
|
|
# envoyer CC à l'agence Vaugneray
|
|
noAgence = 6
|
|
|
|
# selon le type de résa, préparer le message
|
|
if item.resa_type == "Inscr.":
|
|
# résa de stage effectuée sur le WEB
|
|
message = "<p>Nous vous informons que votre inscription au stage %s du %s a été %s.</p>" % (item.ref, date_heure, confirm)
|
|
elif item.resa_type == "WEB_48H.":
|
|
# heure annulée en moins 48 heures sur le WEB remplacée
|
|
message = "<p>Nous vous informons que l'annulation de votre leçon de %s du %s ne vous sera pas débitée " + \
|
|
"car nous avons pu vous trouver un remplaçant.</p>" % (item.ref, date_heure)
|
|
elif item.resa_type in ["WEB_A", "WEB_B"] :
|
|
# résa d'heure A ou B effectuée sur le WEB
|
|
message = "<p>Nous vous informons que votre inscription au stage %s du %s a été %s.</p>" % (item.ref, date_heure, confirm)
|
|
else:
|
|
# résa d'heure A ou B effectuée en agence
|
|
message = "<p>Nous vous informons qu'une réservation de leçon a été <b>" + confirm + "</b>.</p>"
|
|
|
|
szBody = "<html><body><p>Bonjour " + item.nompren + ",</p>" + message + \
|
|
"<p>Merci de consulter votre carnet de rendez-vous remis à jour sur votre espace : " + \
|
|
"<a href=""http://monespace.marietton.com"">monespace.marietton.com</a></p>" + \
|
|
"<p>Nous vous rappelons votre code élève pour vous connecter : <b>" + str(item.cd_cli) + "</b></p>" + \
|
|
"<p>Veuillez agréer nos sincères salutations.</p>" + \
|
|
"<p>Votre équipe Marietton</p></body></html>"
|
|
destinataires = [item.email]
|
|
if len(item.payeur_email) > 0:
|
|
destinataires.append(item.payeur_email)
|
|
|
|
# import pdb;pdb.set_trace()
|
|
email_notification(request, "Réservation de leçon " + confirm, szBody, destinataires, noAgence)
|
|
# attendre 6 secondes, envoi de 10 emails par minute
|
|
sleep(6)
|
|
|
|
# marquer le rdv comme envoyé ou traité
|
|
update_email_resa(request, item.no_id)
|
|
|
|
# si résa WEB, logguer la confirmation
|
|
if type_resa == 'INSCR':
|
|
insert_log(request, item.resa_type, "%s -> %s : %s - %s" % (item.resa_type, confirm, str(item.cd_cli), item.nompren))
|
|
|
|
return nbLus, nbConfirmes, nbAnnules
|
|
|
|
def email_notification(request, objet, corps, destinataires, code):
|
|
# lire l'agence
|
|
agence = get_agences(request, code)
|
|
if agence:
|
|
expediteur = agence.email
|
|
else:
|
|
expediteur = "circuit@marietton.com"
|
|
|
|
# si annulation de résa, CC à l'agence de l'élève
|
|
if objet.find(' ANNULEE, ') > 0:
|
|
destinataires.append(expediteur)
|
|
|
|
reponse = 0
|
|
reponse = send_mail(request, expediteur, destinataires, objet, corps)
|
|
|
|
return reponse
|
|
|
|
def send_mail(request, expediteur, destinataires, objet, corps):
|
|
body = """
|
|
|
|
%s
|
|
""" % (corps)
|
|
|
|
message = Message(subject=objet,
|
|
sender=expediteur,
|
|
recipients=destinataires,
|
|
html=body)
|
|
mailer = get_mailer(request)
|
|
# import pdb;pdb.set_trace()
|
|
msg = ''
|
|
try:
|
|
mailer.send_immediately(message)
|
|
|
|
except Exception as e:
|
|
# Just print(e) is cleaner and more likely what you want,
|
|
# but if you insist on printing message specifically whenever possible...
|
|
if hasattr(e, 'message'):
|
|
msg = e.message
|
|
else:
|
|
msg = e
|
|
# logguer l'erreur
|
|
insert_log(request, 'MAILER', "- ERROR : %s, TO : %s" % (msg, destinataires))
|
|
|
|
return len(msg)
|
|
|