Controle tresorier 1 et 2 aux archives
This commit is contained in:
parent
89c8f33f68
commit
3f70d1b825
2 changed files with 0 additions and 0 deletions
|
@ -1,477 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) Stéphane Glondu
|
||||
# Licence : GPLv2
|
||||
|
||||
u"""Ce script permet au trésorier de repérer plus facilement les papiers que
|
||||
les câbleurs n'ont pas encore rendus.
|
||||
|
||||
Utilisations possibles :
|
||||
* %(prog)s OPTIONS {paiement|carte|list}
|
||||
* %(prog)s OPTIONS mail <liste>
|
||||
|
||||
Les options sont:
|
||||
-d, --debug <adresse> envoyer tous les mails à l'<adresse> indiquée, plutôt
|
||||
qu'aux vrais destinataires
|
||||
-h, --help affiche ce message
|
||||
-t, --tri <champ> trier suivant ce champ. Les champs possibles sont:
|
||||
id, nom, cableur ou date. Le défaut est ``nom''
|
||||
-i, --inverse trier par ordre inverse
|
||||
|
||||
Les commandes sont :
|
||||
* paiement contrôle interactif des nouvelles (ré-)adhésions
|
||||
* carte contrôle interactif des nouvelles cartes d'étudiant
|
||||
* list affiche le récapitulatif des papiers manquants
|
||||
* mail <liste> envoyer les mails de rappel aux câbleurs dont le
|
||||
login est dans la <liste>, 'bureau' désignant le mail
|
||||
récapitulatif envoyé à bureau ; si la liste est vide
|
||||
tous les mails nécessaires seront envoyés
|
||||
* help affiche ce message
|
||||
|
||||
Le modèle du mail envoyé aux câbleurs est lu sur l'entrée standard (typiquement
|
||||
via une redirection). Les trois premières lignes doivent être :
|
||||
Encoding: <encodage du fichier>
|
||||
Subject: <sujet du mail>
|
||||
<ligne vide>
|
||||
Le reste est le corps du message. Il doit contenir une occurrence de '%%s' qui
|
||||
sera remplacée par la liste des papiers manquants.
|
||||
|
||||
Le mail récapitulatif envoyé à bureau est immuable."""
|
||||
|
||||
|
||||
import sys, os, re, getopt
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
|
||||
# Fonctions d'affichage
|
||||
from affich_tools import coul, tableau, prompt, cprint
|
||||
|
||||
# Importation de la base de données
|
||||
from ldap_crans import crans_ldap, ann_scol
|
||||
db = crans_ldap()
|
||||
|
||||
# Détermination de l'uid du câbleur
|
||||
from user_tests import getuser
|
||||
uid = getuser()
|
||||
if not uid :
|
||||
cprint(u"Impossible de déterminer l'utilisateur !")
|
||||
sys.exit(1)
|
||||
cableur = db.search('uid=%s' % uid)['adherent'][0]
|
||||
|
||||
# Vérification des droits
|
||||
if u'Tresorier' not in cableur.droits():
|
||||
cprint(u"Il faut etre tresorier pour exécuter ce script !")
|
||||
sys.exit(1)
|
||||
|
||||
# Lors des tests, on m'envoie tous les mails !
|
||||
from socket import gethostname
|
||||
debug = False
|
||||
|
||||
# Le champ sur lequel on veut trier (id, nom, cableur, date)
|
||||
trier_par = "id"
|
||||
tri_inverse = True
|
||||
|
||||
if gethostname().split(".")[0] == 'egon':
|
||||
debug = 'glondu@crans.org'
|
||||
ann_scol = 2004
|
||||
|
||||
def _controle_interactif_adherents(liste, quoi):
|
||||
"""
|
||||
Contrôle interactif des adhérents de la liste (quoi = p ou c).
|
||||
Retourne (nb_OK, nb_pas_OK).
|
||||
"""
|
||||
if quoi not in 'pc': raise ValueError
|
||||
explicite = {'p': u'du paiement', 'c': u"de la carte d'étudiant"}[quoi]
|
||||
restant = len(liste)
|
||||
if restant == 0:
|
||||
return 0, 0
|
||||
|
||||
cprint(u'\nContrôle %s des adhérents' % explicite, 'cyan')
|
||||
cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n' (défaut=n).")
|
||||
cprint(u"Une autre réponse entraîne l'interruption du processus.")
|
||||
cprint(u"Le format est [nb_restant] Nom, Prénom (aid).")
|
||||
cprint(u"")
|
||||
|
||||
nb = 0
|
||||
for a in liste:
|
||||
ok = prompt(u'[%3d] %s, %s (%s) ?'
|
||||
% (restant, a.nom(), a.prenom(), a.id()), 'n', '').lower()
|
||||
restant -= 1
|
||||
if ok == 'o':
|
||||
modifiable = db.search('aid=%s' % a.id(), 'w')['adherent'][0]
|
||||
if modifiable._modifiable:
|
||||
modifiable.controle('+%s' % quoi)
|
||||
cprint(modifiable.save())
|
||||
nb += 1
|
||||
else:
|
||||
cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge')
|
||||
elif ok != 'n':
|
||||
cprint(u'Arrêt du contrôle %s des adhérents' % explicite, 'rouge')
|
||||
break
|
||||
|
||||
return nb, len(liste)-nb
|
||||
|
||||
|
||||
def _controle_interactif_clubs(liste):
|
||||
"""
|
||||
Contrôle interactif des clubs de la liste (uniquement la charte).
|
||||
Retourne (nb_OK, nb_pas_OK).
|
||||
"""
|
||||
restant = len(liste)
|
||||
if restant == 0:
|
||||
return 0, 0
|
||||
|
||||
cprint(u'\nContrôle de la charte des clubs', 'cyan')
|
||||
cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n'.")
|
||||
cprint(u"Une autre réponse entraîne l'interruption du processus.")
|
||||
cprint(u"Le format est [nb_restant] Nom (cid).")
|
||||
cprint(u"")
|
||||
|
||||
nb = 0
|
||||
for c in liste:
|
||||
ok = prompt(u'[%2d] %s (%s) ?'
|
||||
% (restant, c.Nom(), c.id()), 'n', '').lower()
|
||||
restant -= 1
|
||||
if ok == 'o':
|
||||
modifiable = db.search('cid=%s' % c.id(), 'w')['club'][0]
|
||||
if modifiable._modifiable:
|
||||
modifiable.controle('+p')
|
||||
cprint(modifiable.save())
|
||||
nb += 1
|
||||
else:
|
||||
cprint(u'Club %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge')
|
||||
elif ok != 'n':
|
||||
cprint(u'Arrêt du contrôle de la charte des clubs', 'rouge')
|
||||
break
|
||||
|
||||
return nb, len(liste)-nb
|
||||
|
||||
def qui(historique, quoi):
|
||||
"""
|
||||
Recherche le câbleur qui a effectué la dernière modification quoi
|
||||
dans l'historique, ou qui a inscrit l'adhérent.
|
||||
Retourne le couple (date, cableur) ou ('_inconnu_', '_inconnu_').
|
||||
"""
|
||||
regexp = re.compile(r'^([^,]*), ([^ :]*)')
|
||||
cableur = ('_inconnu_', '_inconnu_')
|
||||
|
||||
champ = re.compile(quoi)
|
||||
|
||||
for ligne in historique:
|
||||
if champ.search(ligne) or 'inscription' in ligne:
|
||||
matched = regexp.search(ligne)
|
||||
if matched: cableur = matched.group(1), matched.group(2)
|
||||
|
||||
return cableur
|
||||
|
||||
def controle_interactif(quoi):
|
||||
"""
|
||||
Procédure interactive de contrôle des paiements/chartes (quoi=p) et cartes (quoi=c).
|
||||
"""
|
||||
if quoi not in 'pc': raise ValueError
|
||||
todo_list = db.search('%s=%d&controle!=*%s*'
|
||||
% ({'p': 'paiement', 'c': 'carteEtudiant'}[quoi], ann_scol, quoi))
|
||||
|
||||
# Tri de la liste des adhérents selon nom, prénom
|
||||
todo_list['adherent'].sort(key = lambda x: (x.nom(), x.prenom()))
|
||||
|
||||
if trier_par == 'id':
|
||||
todo_list['adherent'].sort(key = lambda x: int(x.id()))
|
||||
elif trier_par == 'nom':
|
||||
pass
|
||||
else:
|
||||
champ = { 'date': 0, 'cableur': 1 }[trier_par]
|
||||
todo_list['adherent'].sort(key = lambda x: qui(x.historique(), r'paiement')[champ])
|
||||
|
||||
# Traitement des adhérents
|
||||
oka, noka = _controle_interactif_adherents(todo_list['adherent'], quoi)
|
||||
|
||||
if quoi == 'p':
|
||||
# Tri de la liste des clubs
|
||||
todo_list['club'].sort(lambda x, y: cmp(x.nom(), y.nom()))
|
||||
|
||||
# Traitement des clubs (uniquement la charte)
|
||||
okc, nokc =_controle_interactif_clubs(todo_list['club'])
|
||||
|
||||
cprint(u'\nRécapitulatif des nouveaux contrôles +%s :' % quoi, 'violet')
|
||||
liste = [[u'adhérents', str(oka), str(noka)]]
|
||||
if quoi == 'p':
|
||||
liste.append([u'clubs', str(okc), str(nokc)])
|
||||
cprint(tableau(liste,
|
||||
titre = [u'Catégorie', u'OK', u'pas OK'],
|
||||
largeur = [15, 10, 10]))
|
||||
|
||||
|
||||
def formater_pour_cableur(liste):
|
||||
"""
|
||||
Formate la liste d'adhérents ou de clubs avec les dates correspondantes.
|
||||
liste est une liste de couples (date, objet).
|
||||
"""
|
||||
lignes = []
|
||||
total = 0
|
||||
liste.sort(lambda x, y: cmp(x[1].nom(), y[1].nom()))
|
||||
|
||||
for date, a in liste:
|
||||
lignes.append([a.id(), a.Nom(), date])
|
||||
total += 1
|
||||
|
||||
if trier_par == 'id':
|
||||
lignes.sort(key = lambda ligne: int(ligne[0]))
|
||||
else:
|
||||
champ = {'nom' : 1, 'cableur' : 1, 'date' : 2}[trier_par]
|
||||
lignes.sort(key = lambda ligne: ligne[champ])
|
||||
|
||||
if tri_inverse: lignes.reverse()
|
||||
|
||||
return tableau(lignes,
|
||||
titre = [u'id', u'Nom', u'Date Heure'],
|
||||
largeur = [6, 40, 18],
|
||||
alignement = ['d', 'c', 'c']) + u'\nTotal : %d' % total
|
||||
|
||||
|
||||
def formater_pour_bureau(dico):
|
||||
"""
|
||||
Formate la liste d'adhérents ou de clubs avec les câbleurs correspondantes
|
||||
pour le mail récapitulatif envoyé à bureau.
|
||||
"""
|
||||
lignes = []
|
||||
total = 0
|
||||
|
||||
liste = dico.keys()
|
||||
liste.sort()
|
||||
for cableur in liste:
|
||||
for date, a in dico[cableur]:
|
||||
lignes.append([a.id(), a.Nom(), cableur, date])
|
||||
total += 1
|
||||
|
||||
if trier_par == 'id':
|
||||
lignes.sort(key = lambda ligne: int(ligne[0]))
|
||||
else:
|
||||
champ = {'nom' : 1, 'cableur' : 2, 'date' : 3}[trier_par]
|
||||
lignes.sort(key = lambda ligne: ligne[champ])
|
||||
|
||||
if tri_inverse: lignes.reverse()
|
||||
|
||||
return tableau(lignes,
|
||||
titre = [u'id', u'Nom', u'Câbleur', u'Date'],
|
||||
largeur = [6, 40, 18, 18],
|
||||
alignement = ['d', 'c', 'c', 'c']) + u'\nTotal : %d' % total
|
||||
|
||||
|
||||
def chercher_cableurs(liste, quoi):
|
||||
"""
|
||||
Renvoie un dictionnaire cableur->adherents à partir de liste, quoi
|
||||
désigne le champ qui sera recherché dans l'historique.
|
||||
"""
|
||||
resultat = {}
|
||||
|
||||
for a in liste:
|
||||
date, cableur = qui(a.historique(), quoi)
|
||||
if not resultat.has_key(cableur): resultat[cableur] = []
|
||||
resultat[cableur].append((date, a))
|
||||
|
||||
return resultat
|
||||
|
||||
|
||||
from email_tools import send_email, parse_mail_template
|
||||
|
||||
# Mise en application du mémorable cours de Fred sur les objets :-)
|
||||
|
||||
class ControleMailer:
|
||||
|
||||
def __init__(self):
|
||||
# Recherche des câbleurs possédant des cotisations/chartes
|
||||
todo_list = db.search('paiement=%d&controle!=*p*' % ann_scol)
|
||||
self._paiements = chercher_cableurs(todo_list['adherent'], r'(paiement|controle.*\+k)')
|
||||
self._chartes = chercher_cableurs(todo_list['club'], 'paiement')
|
||||
|
||||
# Recherche des câbleurs possédant des cartes d'étudiant
|
||||
todo_list = db.search('carteEtudiant=%d&controle!=*c*' % ann_scol)
|
||||
self._cartes = chercher_cableurs(todo_list['adherent'], 'carteEtudiant')
|
||||
|
||||
# Récupère tous les câbleurs qui doivent quelque chose
|
||||
cableurs = {}
|
||||
for a in self._paiements.keys():
|
||||
if a != '_inconnu_': cableurs[a] = None
|
||||
for a in self._chartes.keys():
|
||||
if a != '_inconnu_': cableurs[a] = None
|
||||
for a in self._cartes.keys():
|
||||
if a != '_inconnu_': cableurs[a] = None
|
||||
self._cableurs = cableurs.keys()
|
||||
|
||||
# Vérification de l'alias pour l'expéditeur
|
||||
if u'tresorier' in cableur.alias():
|
||||
self._sender = u'%s <tresorier@crans.org>' % cableur.Nom()
|
||||
else:
|
||||
self._sender = u'%s <%s@crans.org>' % (cableur.Nom(),
|
||||
cableur.canonical_alias() or cableur.mail())
|
||||
|
||||
# Se connecte au serveur SMTP par défaut
|
||||
from smtplib import SMTP
|
||||
self._server = SMTP()
|
||||
self._server.connect()
|
||||
|
||||
def __del__(self):
|
||||
# Termine la connexion au serveur SMTP
|
||||
self._server.quit()
|
||||
|
||||
def recapitulatif(self):
|
||||
"""
|
||||
Renvoie le récapitulatif pour le bureau.
|
||||
"""
|
||||
msg = u''
|
||||
|
||||
if self._paiements:
|
||||
msg += u"Fiches d'adhésion et cotisations et/ou caution des adhérents :\n"
|
||||
msg += formater_pour_bureau(self._paiements) + '\n\n'
|
||||
|
||||
if self._chartes:
|
||||
msg += u"Chartes signées des clubs :\n"
|
||||
msg += formater_pour_bureau(self._chartes) + '\n\n'
|
||||
|
||||
if self._cartes:
|
||||
msg += u"Carte d'étudiant des adhérents :\n"
|
||||
msg += formater_pour_bureau(self._cartes) + '\n\n'
|
||||
|
||||
return msg.strip()
|
||||
|
||||
def mail_bureau(self):
|
||||
"""
|
||||
Envoie le mail récapitulatif à bureau (s'il y a qqch à envoyer).
|
||||
"""
|
||||
msg = self.recapitulatif()
|
||||
if msg:
|
||||
msg += u"\n\n-- \nScript exécuté par %s\n" % cableur.Nom()
|
||||
send_email(self._sender,
|
||||
u"Bureau <bureau@crans.org>",
|
||||
u"Récapitulatif des papiers manquants",
|
||||
msg,
|
||||
server = self._server,
|
||||
debug = debug)
|
||||
return coul(u'Mail envoyé à bureau avec succès !', 'vert')
|
||||
else:
|
||||
return coul(u'Tout est à jour, aucun mail envoyé.', 'vert')
|
||||
|
||||
def mail_cableurs(self, subject, body, liste=None):
|
||||
"""
|
||||
Envoie un mail aux câbleurs concernés qui figurent dans la liste.
|
||||
Si liste vaut None, envoie un mail à tous les câbleurs concernés.
|
||||
Les arguments subject, body permettent de personnaliser (un peu)
|
||||
le mail qui sera envoyé.
|
||||
"""
|
||||
nb = 0
|
||||
if liste == None:
|
||||
liste = self._cableurs
|
||||
|
||||
for c in liste:
|
||||
msg = u''
|
||||
|
||||
if self._paiements.has_key(c):
|
||||
msg += u"Fiches d'adhésion, cotisations et/ou caution des adhérents :\n"
|
||||
msg += formater_pour_cableur(self._paiements[c]) + '\n\n'
|
||||
|
||||
if self._chartes.has_key(c):
|
||||
msg += u"Chartes signées des clubs :\n"
|
||||
msg += formater_pour_cableur(self._chartes[c]) + '\n\n'
|
||||
|
||||
if self._cartes.has_key(c):
|
||||
msg += u"Carte d'étudiant des adhérents :\n"
|
||||
msg += formater_pour_cableur(self._cartes[c]) + '\n\n'
|
||||
|
||||
if msg:
|
||||
msg = msg.strip()
|
||||
send_email(self._sender,
|
||||
"%s@crans.org" % c,
|
||||
subject,
|
||||
body % msg,
|
||||
server = self._server,
|
||||
debug = debug)
|
||||
nb += 1
|
||||
|
||||
return coul(u'%d mail(s) envoyé(s) aux câbleurs avec succès !' % nb, 'vert')
|
||||
|
||||
|
||||
def __usage(message=None):
|
||||
""" Comment ça marche ? """
|
||||
cprint(__doc__ % { 'prog': sys.argv[0] })
|
||||
if message:
|
||||
cprint(message)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__' :
|
||||
|
||||
try:
|
||||
options, arg = getopt.getopt(sys.argv[1:], 'ht:d:i', [ 'help', 'debug=', 'tri=', 'inverse' ])
|
||||
except getopt.error, msg:
|
||||
__usage(unicode(msg))
|
||||
|
||||
for opt, val in options:
|
||||
if opt in [ '-h', '--help' ]:
|
||||
__usage()
|
||||
|
||||
elif opt in [ '-d', '--debug' ]:
|
||||
debug = val
|
||||
cprint(u'Mode debug, tous les mails seront envoyés à %s.' % debug)
|
||||
|
||||
elif opt in [ '-t', '--tri' ]:
|
||||
if val in [ 'id', 'nom', 'cableur', 'date' ]:
|
||||
trier_par = val
|
||||
else:
|
||||
__usage(u'Champ de tri invalie %s' % val)
|
||||
|
||||
elif opt in [ '-i', '--inverse' ]:
|
||||
tri_inverse = True
|
||||
|
||||
else:
|
||||
__usage("option inconnue « %s »'" % opt)
|
||||
|
||||
if len(arg) == 0 or arg[0] == 'help':
|
||||
__usage()
|
||||
|
||||
elif arg[0] == 'paiement':
|
||||
if len(arg) != 1:
|
||||
__usage(u'Mauvaise utilisation de paiement')
|
||||
controle_interactif('p')
|
||||
|
||||
elif arg[0] == 'carte':
|
||||
if len(arg) != 1:
|
||||
__usage(u'Mauvaise utilisation de carte')
|
||||
controle_interactif('c')
|
||||
|
||||
elif arg[0] == 'list':
|
||||
if len(arg) != 1:
|
||||
__usage(u'Mauvaise utilisation de list')
|
||||
cprint(ControleMailer().recapitulatif(), newline=False)
|
||||
|
||||
elif arg[0] == 'mail':
|
||||
mailer = ControleMailer()
|
||||
cableurs = arg[1:]
|
||||
if cableurs:
|
||||
bureau = False
|
||||
if 'bureau' in cableurs:
|
||||
cableurs.remove('bureau')
|
||||
bureau = True
|
||||
else:
|
||||
bureau = True
|
||||
cableurs = mailer._cableurs
|
||||
if cableurs:
|
||||
cprint(u'Des mails vont être envoyés aux câbleurs, lecture du modèle...')
|
||||
subject, body = parse_mail_template(sys.stdin)
|
||||
try:
|
||||
body % u''
|
||||
except TypeError:
|
||||
cprint(u"Le format du modèle n'est pas correct, arrêt.")
|
||||
sys.exit(1)
|
||||
cprint(u'Modèle OK, on envoie les mails...')
|
||||
cprint(mailer.mail_cableurs(subject, body, cableurs))
|
||||
if bureau:
|
||||
cprint(mailer.mail_bureau())
|
||||
|
||||
else:
|
||||
__usage(u'Commande inconnue : %s' % arg[0])
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
# pydoc n'aime pas l'unicode :-(
|
|
@ -1,292 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# $Id: controle_tresorier2.py,v 1.3 2007-11-08 21:18:32 dimino Exp $
|
||||
#
|
||||
# tresorier.py
|
||||
# ------------
|
||||
#
|
||||
# Copyright (C) 2007 Jeremie Dimino <jeremie@dimino.org>
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This file is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
import os, sys
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
|
||||
from ldap_crans import crans_ldap, Adherent, Club
|
||||
from config import ann_scol
|
||||
import dialog, time, config, re
|
||||
|
||||
db = crans_ldap()
|
||||
|
||||
# Détermination de l'uid du câbleur
|
||||
from user_tests import getuser
|
||||
uid = getuser()
|
||||
if not uid :
|
||||
print "Impossible de determiner l'utilisateur !"
|
||||
sys.exit(1)
|
||||
cableur = db.search('uid=%s' % uid)['adherent'][0]
|
||||
|
||||
# Vérification des droits
|
||||
if u'Tresorier' not in cableur.droits():
|
||||
print "Il faut etre tresorier pour executer ce script !"
|
||||
sys.exit(1)
|
||||
|
||||
dlg = dialog.Dialog()
|
||||
dlg.setBackgroundTitle('Tresorerie')
|
||||
encoding = sys.stdin.encoding or 'UTF-8'
|
||||
|
||||
########################################################################
|
||||
# Retrait des accents
|
||||
#
|
||||
|
||||
_unaccent_dict = {u'Æ': u'AE', u'æ': u'ae', u'Œ': u'OE', u'œ': u'oe', u'ß': 'ss'}
|
||||
_re_latin_letter = re.compile(r"^(LATIN [A-Z]+ LETTER [A-Z]+) WITH")
|
||||
def unaccent(string):
|
||||
"""Remove accents ``string``."""
|
||||
result = []
|
||||
for char in string:
|
||||
if char in _unaccent_dict:
|
||||
char = _unaccent_dict[char]
|
||||
else:
|
||||
try:
|
||||
name = unicodedata.name(char)
|
||||
match = _re_latin_letter.search(name)
|
||||
if match:
|
||||
char = unicodedata.lookup(match.group(1))
|
||||
except:
|
||||
pass
|
||||
result.append(char)
|
||||
return "".join(result)
|
||||
|
||||
########################################################################
|
||||
# Ajoute un cheque a la liste
|
||||
#
|
||||
|
||||
_civilite = [ "M", "MLLE", "MME" ]
|
||||
_banque = [("CIC", u"CiC"),
|
||||
("BNP", u"BNP"),
|
||||
("BP", u"Banque Populaire"),
|
||||
("CA", u"Crédit Agricole"),
|
||||
("CE", u"Caisse d'Épargne"),
|
||||
("CL", u"Crédit Lyonnais"),
|
||||
("CM", u"Crédit Mutuel"),
|
||||
("CN", u"Crédit du Nord"),
|
||||
("HSBC", u"HSBC"),
|
||||
("LBP", u"La Banque Postale"),
|
||||
("LCL", u"Le Crédit Lyonnais"),
|
||||
("LP", u"La Poste"),
|
||||
("SG", u"Société Générale")]
|
||||
_banque.sort()
|
||||
_banque.insert(0, ("Autre", u"Éspèces"))
|
||||
def add_cheque(adh):
|
||||
annul, result = dlg.menu(u"Banque", choices = _banque)
|
||||
if annul: return False
|
||||
|
||||
banque = result
|
||||
if banque == "Autre":
|
||||
return True
|
||||
|
||||
annul, result = dlg.menu(u"Civilité",
|
||||
choices=[("1", u"Monsieur"),
|
||||
("2", u"Mademoiselle"),
|
||||
("3", u"Madame")])
|
||||
if annul: return False
|
||||
|
||||
civilite = _civilite[int(result)-1]
|
||||
|
||||
|
||||
line = '%s %s %s' % (civilite, unaccent(adh.Nom()).upper(), banque)
|
||||
|
||||
annul, line = dlg.inputbox(u"Vérification de l'émetteur du chèque", init=line)
|
||||
|
||||
f = open("%s/remise_cheques" % os.getenv("HOME"), 'a')
|
||||
f.write('%s\n' % line)
|
||||
f.close()
|
||||
return True
|
||||
|
||||
########################################################################
|
||||
# Menu de sélection des adhérents
|
||||
#
|
||||
|
||||
def main_menu():
|
||||
while True:
|
||||
|
||||
annul, result = dlg.checklist(u"Choisissez les adhérents à inclure dans la liste",
|
||||
choices=[("1", u'Nouvelles adhésions', 1),
|
||||
("2", u'Réadhésions', 0),
|
||||
("3", u'Inscriptions(gratuite)', 1),
|
||||
("4", u'Clubs', 0)])
|
||||
|
||||
if annul:
|
||||
return
|
||||
|
||||
include_new_adhs = "1" in result
|
||||
include_re_adhs = "2" in result
|
||||
include_inscriptions = "3" in result
|
||||
include_clubs = "4" in result
|
||||
|
||||
# Construction de la liste des adhérents à contrôler
|
||||
search_result_p = db.search('paiement=%d&controle!=*p*' % ann_scol)
|
||||
search_result_c = db.search('paiement=%d&controle!=*c*' % ann_scol)
|
||||
lst_p = search_result_p['adherent'] + search_result_p['club']
|
||||
lst_c = search_result_c['adherent'] + search_result_c['club']
|
||||
|
||||
lst = {}
|
||||
for adh in lst_p:
|
||||
lst[adh.id()] = adh
|
||||
for adh in lst_c:
|
||||
lst[adh.id()] = adh
|
||||
lst = lst.values()
|
||||
|
||||
# Date de début de la nouvelle année
|
||||
start_date = time.mktime((ann_scol, 8, 1, 0, 0, 0, 0, 0, 0))
|
||||
|
||||
# Filtre des adhérents
|
||||
lst = [adh for adh in lst if
|
||||
((include_new_adhs and isinstance(adh, Adherent) and adh.adherentPayant() and adh.dateInscription() >= start_date) or
|
||||
(include_re_adhs and isinstance(adh, Adherent) and adh.adherentPayant() and adh.dateInscription() < start_date) or
|
||||
(include_inscriptions and isinstance(adh, Adherent) and not adh.adherentPayant()) or
|
||||
(include_clubs and isinstance(adh, Club)))]
|
||||
|
||||
adherent_menu(lst)
|
||||
|
||||
|
||||
########################################################################
|
||||
# Liste des adhérents
|
||||
#
|
||||
|
||||
def adherent_menu(lst):
|
||||
if lst == []:
|
||||
dlg.msgbox(u"Il n'y a personne à contrôler!")
|
||||
return
|
||||
|
||||
nom_adh = {}
|
||||
adhs = []
|
||||
for adh in lst:
|
||||
disp = ' '.join([unicode(adh.id()).rjust(4), adh.Nom()]).encode(encoding)
|
||||
adhs.append((disp, ''))
|
||||
nom_adh[disp] = adh
|
||||
|
||||
adhs.sort()
|
||||
|
||||
while True:
|
||||
annul, result = dlg.menu(u'Liste des adhérents', choices=adhs)
|
||||
|
||||
if annul:
|
||||
return
|
||||
|
||||
adh = nom_adh[result]
|
||||
|
||||
if admin_menu(adh):
|
||||
adhs.remove((result, ''))
|
||||
|
||||
|
||||
########################################################################
|
||||
# Controle d'un adhérent (repompé de gest_crans.py)
|
||||
#
|
||||
|
||||
def on_off(cond):
|
||||
if cond:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def admin_menu(adh):
|
||||
|
||||
# Le proprietaire a-t-il une section carte d'étudiant (pas les clubs) ?
|
||||
has_card = adh.idn != 'cid'
|
||||
|
||||
# Initialisation des différentes checkbox
|
||||
carte = on_off(ann_scol in adh.carteEtudiant())
|
||||
paiement = on_off(ann_scol in adh.paiement())
|
||||
#precab = on_off(ann_scol + 1 in adh.paiement())
|
||||
caution = on_off('k' in adh.controle())
|
||||
paiement_ok = on_off('p' in adh.controle())
|
||||
carte_ok = on_off('c' in adh.controle())
|
||||
|
||||
# Construction de la boîte de dialogue
|
||||
texte = []
|
||||
checklist = []
|
||||
|
||||
if has_card:
|
||||
checklist.append(("1", u"Carte d'étudiant %d/%d fournie" % (ann_scol, ann_scol+1), carte))
|
||||
|
||||
checklist.append(("2", u"Cotisation %d/%d réglée et charte signée" % (ann_scol, ann_scol+1), paiement))
|
||||
|
||||
# TODO: controle pour le précâblage
|
||||
#if config.precab:
|
||||
# checklist.append(("3", u"Adhésion %d/%d réglée et charte signée (précâblage)" % (ann_scol+1, ann_scol+2), precab))
|
||||
|
||||
if has_card:
|
||||
checklist.append(("4", u"Carte d\'étudiant vérifiée", carte_ok))
|
||||
checklist.append(("5", u"Cotisation/charte/caution vérifées", paiement_ok))
|
||||
|
||||
annul, result = dlg.checklist(u"Etat administratif de %s" % adh.Nom(),
|
||||
choices=checklist)
|
||||
if annul:
|
||||
return False
|
||||
|
||||
modif = False
|
||||
# On cherche s'il y a des modifs
|
||||
for tag, item, state in checklist:
|
||||
if (tag in result) ^ state:
|
||||
modif = True
|
||||
|
||||
if not modif:
|
||||
return False
|
||||
|
||||
if isinstance(adh, Club):
|
||||
adh = db.search('cid=%s' % adh.id(), 'w')['club'][0]
|
||||
else:
|
||||
adh = db.search('aid=%s' % adh.id(), 'w')['adherent'][0]
|
||||
|
||||
# Traitement
|
||||
if has_card:
|
||||
if '1' in result:
|
||||
adh.carteEtudiant(ann_scol)
|
||||
elif carte_ok:
|
||||
adh.carteEtudiant(-ann_scol)
|
||||
if '4' in result:
|
||||
adh.controle('+c')
|
||||
else:
|
||||
adh.controle('-c')
|
||||
|
||||
if '2' in result and ann_scol not in adh.paiement():
|
||||
adh.paiement(ann_scol)
|
||||
elif '2' not in result and paiement_ok:
|
||||
adh.paiement(-ann_scol)
|
||||
|
||||
if '3' in result:
|
||||
adh.paiement(ann_scol+1)
|
||||
elif paiement_ok:
|
||||
adh.paiement(-ann_scol-1)
|
||||
|
||||
if '5' in result:
|
||||
adh.controle('+p')
|
||||
else:
|
||||
adh.controle('-p')
|
||||
|
||||
if 'C' in result:
|
||||
adh.controle('+k')
|
||||
else:
|
||||
adh.controle('-k')
|
||||
|
||||
adh.save()
|
||||
|
||||
return True
|
||||
|
||||
main_menu()
|
Loading…
Add table
Add a link
Reference in a new issue