Commit f7cf7bdf authored by Gabriel Detraz's avatar Gabriel Detraz Committed by Pierre-Elliott Bécue

Script pour recréditer des impressions.

 * Une version avec un unique mail envoyé à l'adh avec impression en copie suivra.
parent cb21cb77
......@@ -47,3 +47,5 @@ From_imprimante = 'impression@crans.org'
#: Informations supplémentaires sur l'état de l'imprimante, affichée sur l'intranet
state_msg = []
#: Temps sur lequel le script de recrédit des impressions peut regarder, en jours
delta_recredit_jours = 15
Signale les remboursements d'impressions qui ne se sont pas déroulées correctement aux imprimeurs.
L'imprimeur {{imprimeur}} a procédé à un ou plusieurs remboursements d'impressions pour l'adhérent {{adhname}}.
Le montant total des remboursements s'élève à : {{montant}} Euros.
Voici le détail de ces impressions :
{{taches}}
Le script de remboursement.
#!/bin/bash /usr/scripts/python.sh
# -*- coding: utf-8 -*-
"""
Effectue la recréditation des impressions qui n'ont pas été effectuées
par l'imprimante, soit ne sont pas sorties correctement, et contiennent
des logs d'erreur.
Le script est fait pour éviter de recréditer plusieurs fois les mêmes
impressions, et croise dans l'historique de l'adhérent les impressions
(débits), et les créditations que ce script a lui même déjà effectuées.
Un mail est envoyé pour signaler les activités de crédits.
L'exécution se fait pas appel du script suivi de l'aid.
Auteurs : Gabriel Détraz <detraz@crans.org>
Pierre-Elliott Bécue <becue@crans.org>
avec contributions importantes de Daniel Stan, Valentin Samir et Lucas Serrano
"""
# Import des modules génériques
import argparse
import sys
import datetime
import re
from utils.sendmail import actually_sendmail
# Imports des scripts développés au Crans
import lc_ldap.shortcuts
import lc_ldap.filter2 as lfilter
import gestion.config as config
from pythondialog.dialog import Dialog
from gestion import mail
# On ouvre une connexion LDAP à la base de test une fois pour toute.
conn = lc_ldap.shortcuts.lc_ldap_admin()
# Des fonctions...
IMP_DONE_REGEX = re.compile(r".*respbats : debit (?P<montant>[^ ]*) Euros \[impression\((?P<jid>.*)\):.*fichiers/(?P<login>.*)/(?P<file>[^ ]*) .*\]")
IMP_DEJ_REMB_REGEX = re.compile(r".*credit (?P<montant>[^ ]*) Euros \[Impression ratee, jid=(?P<jid>.*), tache=(?P<fichier>.*)\]")
def do_remb(args):
"""Fonction appelant l'interface curses et listant les remboursements
possibles.
"""
rendu = []
adh = conn.search(lfilter.human_to_ldap(args.filtre.decode(config.encoding.in_encoding)), mode="w")
# conn.search peut retourner une liste vide.
if not adh:
return []
with adh[0] as adh:
liste_rembs = find_rembs(adh)
while True:
(ret, val) = dialog_remb(liste_rembs)
if ret:
adh.save()
break
else:
selected = liste_rembs[int(val)]
if confirm(selected):
adh.update_solde(float(selected["montant"]), u"Impression ratee, jid=%(jid)s, tache=%(file)s" % selected)
_ = liste_rembs.pop(int(val))
rendu.append(selected)
else:
continue
send_mail(rendu, adh)
return
def find_rembs(adh):
"""Fonction qui calcule les entrées remboursables d'un adhérent
"""
now = datetime.datetime.now()
begin = now - datetime.timedelta(days=config.impression.delta_recredit_jours)
liste_taches = list()
liste_rembs = list()
for ent in adh["historique"]:
date = ent.get_datetime()
if date > begin:
match_entry = IMP_DONE_REGEX.match(unicode(ent))
if match_entry is not None:
liste_taches.append(match_entry.groupdict())
continue
match_entry = IMP_DEJ_REMB_REGEX.match(unicode(ent))
if match_entry is not None:
liste_rembs.append(match_entry.groupdict())
continue
# On génère la liste avant le return, pour ne pas la regénérer autant de fois qu'il
# y a de tâches dans liste_taches
jid_rembs = [remb["jid"] for remb in liste_rembs]
return [tache for tache in liste_taches if tache['jid'] not in jid_rembs]
def dialog_remb(liste_rembs):
"""Crée une boîte de dialogue à partir de la liste des remboursements, pour
en faire un.
"""
if not liste_rembs:
return (1, "")
dialog = Dialog()
choices = [("%s" % liste_rembs.index(dico), "Remb impression du fichier %(file)s (montant: %(montant)s, jid: %(jid)s)." % dico) for dico in liste_rembs]
return dialog.menu("Quelle impression souhaitez-vous rembourser ?", width=0, height=0, menu_height=0, title="Remboursement", choices=choices, cancel_label="Quitter", backtitle=u"Remboursement d'impressions ratées.")
def confirm(dico):
"""Demande avec dialog si on doit confirmer le remboursement.
"""
dialog = Dialog()
return dialog.yesno("Confirmer le remboursement ?") == dialog.DIALOG_OK
def send_mail(liste_rendus, adh):
"""Si la liste des remboursements est non-vide, envoie un mail pour prévenir
les imprimeurs.
"""
if not liste_rendus:
return
montant = sum([float(dico["montant"]) for dico in liste_rendus])
affs = [dico['file'] for dico in liste_rendus]
login = unicode(adh["uid"][0])
To = 'impression@crans.org'
From = 'impression@crans.org'
mailtxt = mail.generate('remboursement_impressions', {
'To': To,
'From': From,
'adhname': login,
'taches': u', '.join(affs),
'montant': montant,
'imprimeur': lc_ldap.shortcuts.current_user,
})
# print mailtxt.as_string()
actually_sendmail(From, (To,), mailtxt)
#Un bloc de test
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Script pour recréditer les adhérents.", add_help=False)
parser.add_argument('-h', '--help', help="Affiche ce message et quitte.", action="store_true")
parser.add_argument('filtre', type=str, nargs="?", help="Le filtre LDAP à utiliser")
# Et on parse
args = parser.parse_args()
if args.help:
parser.print_help()
sys.exit(0)
else:
if not args.filtre:
parser.print_help()
sys.exit(1)
else:
do_remb(args)
#!/bin/bash
sudo -u respbats /usr/scripts/impression/recredit.py "$@"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment