Script pour recréditer des impressions.
* Une version avec un unique mail envoyé à l'adh avec impression en copie suivra.
This commit is contained in:
parent
cb21cb77bf
commit
f7cf7bdf4b
9 changed files with 185 additions and 0 deletions
|
@ -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
|
||||
|
|
1
gestion/mail/template/remboursement_impressions/From/fr
Normal file
1
gestion/mail/template/remboursement_impressions/From/fr
Normal file
|
@ -0,0 +1 @@
|
|||
<impression@crans.org>
|
1
gestion/mail/template/remboursement_impressions/README
Normal file
1
gestion/mail/template/remboursement_impressions/README
Normal file
|
@ -0,0 +1 @@
|
|||
Signale les remboursements d'impressions qui ne se sont pas déroulées correctement aux imprimeurs.
|
|
@ -0,0 +1 @@
|
|||
Remboursement d'impressions
|
3
gestion/mail/template/remboursement_impressions/To/fr
Normal file
3
gestion/mail/template/remboursement_impressions/To/fr
Normal file
|
@ -0,0 +1,3 @@
|
|||
{{To}}
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{{ mailer }}
|
||||
|
||||
|
8
gestion/mail/template/remboursement_impressions/body/fr
Normal file
8
gestion/mail/template/remboursement_impressions/body/fr
Normal file
|
@ -0,0 +1,8 @@
|
|||
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.
|
163
impression/recredit.py
Executable file
163
impression/recredit.py
Executable file
|
@ -0,0 +1,163 @@
|
|||
#!/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)
|
||||
|
3
respbats/recredit
Executable file
3
respbats/recredit
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
sudo -u respbats /usr/scripts/impression/recredit.py "$@"
|
Loading…
Add table
Add a link
Reference in a new issue