scripts/gestion/dialog/adherent.py
Valentin Samir acd7d8fd7f [gest_crans_lc] Ajout des validate_changes() même là où ça sert à rien
Pour ne pas avoir de surprise si quelqu'un modifie validate_changes() dans lc_ldap.
2014-12-01 13:32:55 +01:00

883 lines
46 KiB
Python

#!/bin/bash /usr/scripts/python.sh
# -*- coding: utf-8 -*-
u"""
Copyright (C) Valentin Samir
Licence : GPLv3
"""
import sys
import time
if '/usr/scripts' not in sys.path:
sys.path.append('/usr/scripts')
import lc_ldap.objets as objets
import lc_ldap.attributs as attributs
from lc_ldap.attributs import UniquenessError
import proprio
from CPS import TailCall, tailcaller, Continue
class Dialog(proprio.Dialog):
def modif_adherent_blacklist(self, adherent, cont):
"""Raccourci vers edit_blacklist spécifique aux adherent"""
return self.edit_blacklist(obj=adherent, title="Éditions des blacklist de %s %s" % (adherent['prenom'][0], adherent['nom'][0]), update_obj='adherent', cont=cont)
def modif_adherent(self, cont, adherent=None, tag=None):
"""Menu d'édition d'un adhérent"""
if adherent is None:
adherent = self.select(["adherent"], "Recherche d'un adhérent pour modification", cont=cont)
a = attributs
menu_droits = {
'Administratif' : [a.cableur, a.nounou],
'Personnel':[a.cableur, a.nounou, a.soi],
'Études':[a.nounou, a.soi, a.cableur],
'Chambre':[a.cableur, a.nounou],
'Compte':[a.cableur, a.nounou],
'GPGFingerprint' : [a.nounou, a.soi],
'Remarques' : [a.cableur, a.nounou],
'Droits':[a.nounou, a.bureau],
'Blackliste':[a.cableur, a.nounou],
'Vente':[a.cableur, a.nounou],
'Supprimer':[a.nounou, a.bureau],
}
menu = {
'Administratif' : {'text' : "Adhésion, carte étudiant, chartes", "callback":self.adherent_administratif},
'Personnel' : {'text' : "Nom, prénom, téléphone... (ajouter l'age ?)", 'callback':self.adherent_personnel},
'Études' : {'text' : "Étude en cours", "callback":self.adherent_etudes},
'Chambre' : {'text' : 'Déménagement', "callback":self.adherent_chambre},
'Compte' : {'text' : "Gestion du compte crans", "adherent":"proprio", "callback":self.proprio_compte, 'help':"Création/Suppression/Activation/Désactivation du compte, gestion des alias mails crans du compte"},
'GPGFingerprint' : {'text':'Ajouter ou supprimer une empeinte GPG', 'attribut':attributs.gpgFingerprint},
'Remarques' : {'text':'Ajouter ou supprimer une remarque de la machine', 'attribut':attributs.info},
'Droits' : {'text':"Modifier les droits alloués à cet adhérent", "callback":self.adherent_droits},
'Blackliste' : {'text': 'Modifier les blacklist de la machine', 'callback':self.modif_adherent_blacklist},
'Vente' : {'text':"Chargement solde crans, vente de cable ou adaptateur ethernet ou autre", "adherent":"proprio", "callback":self.proprio_vente},
'Supprimer' : {'text':"Supprimer l'adhérent de la base de donnée", 'callback':TailCall(self.delete_adherent, del_cont=cont(proprio=None))},
}
menu_order = ['Administratif', 'Personnel', 'Études', 'Chambre', 'Compte']
menu_compte_crans = ['Droits']
medu_end = ['GPGFingerprint', 'Remarques', 'Blackliste', 'Vente', 'Supprimer']
if "cransAccount" in adherent['objectClass']:
menu_order.extend(menu_compte_crans)
menu_order.extend(medu_end)
def box(default_item=None):
choices = []
for key in menu_order:
if self.has_right(menu_droits[key], adherent):
choices.append((key, menu[key]['text'], menu[key].get('help', "")))
return self.dialog.menu(
"Que souhaitez vous modifier ?",
width=0,
height=0,
menu_height=0,
timeout=self.timeout,
item_help=1,
default_item=str(default_item),
title="Modification de %s %s" % (adherent['prenom'][0], adherent["nom"][0]),
scrollbar=True,
cancel_label="Retour",
backtitle=u"Vous êtes connecté en tant que %s" % self.conn.current_login,
choices=choices)
def todo(tag, menu, adherent, cont_ret):
if not tag in menu_order:
raise Continue(cont_ret)
else:
if 'callback' in menu[tag]:
raise Continue(TailCall(menu[tag]['callback'], cont=cont_ret, **{menu[tag].get('adherent', 'adherent'):adherent}))
elif 'attribut' in menu[tag]:
raise Continue(TailCall(self.modif_adherent_attributs, adherent=adherent, cont=cont_ret, attr=menu[tag]['attribut'].ldap_name))
else:
raise EnvironmentError("Il n'y a ni champ 'attribut' ni 'callback' pour le tag %s" % tag)
(code, tag) = self.handle_dialog(cont, box, tag)
cont_ret = TailCall(self.modif_adherent, cont=cont, adherent=adherent, tag=tag)
return self.handle_dialog_result(
code=code,
output=tag,
cancel_cont=cont(proprio=adherent),
error_cont=cont_ret,
codes_todo=[([self.dialog.DIALOG_OK], todo, [tag, menu, adherent, cont_ret])]
)
def adherent_administratif(self, cont, adherent, default_item=None):
"""Menu de gestion du compte crans d'un proprio"""
a = attributs
menu_droits = {
"Adhésion": [a.cableur, a.nounou],
'Connexion': [a.cableur, a.nounou],
"Charte MA" : [a.nounou, a.bureau],
"Carte Étudiant" : [a.nounou, a.cableur, a.tresorier],
}
menu = {
"Adhésion" : {"text":"Pour toute réadhésion *sans* connexion.", "help":"", "callback":self.adherent_adhesion},
'Connexion' : {'text': "Mise à jour de l'accès Internet (effectue la réadhésion si besoin)", "help":"", 'callback':self.adherent_connexion},
"Carte Étudiant" : {"text" : "Validation de la carte étudiant", "help":"", "callback":self.adherent_carte_etudiant},
"Charte MA" : {"text" : "Signature de la charte des membres actifs", "help":'', "callback":self.adherent_charte},
}
menu_order = ["Adhésion", 'Connexion']
if self.has_right(a.tresorier, adherent) or not adherent.carte_controle():
menu_order.append("Carte Étudiant")
menu_order.append("Charte MA")
def box(default_item=None):
return self.dialog.menu(
"Quelle action administrative effectuer",
width=0,
height=0,
timeout=self.timeout,
item_help=1,
default_item=str(default_item),
title="Gestion administrative de %s %s" % (adherent.get('prenom', [''])[0], adherent["nom"][0]),
scrollbar=True,
cancel_label="Retour",
backtitle=u"Vous êtes connecté en tant que %s" % self.conn.current_login,
choices=[(k, menu[k]['text'], menu[k]['help']) for k in menu_order if self.has_right(menu_droits[k], adherent)])
def todo(tag, menu, adherent, self_cont):
if not tag in menu_order:
raise Continue(self_cont)
elif 'callback' in menu[tag]:
raise Continue(TailCall(menu[tag]['callback'], cont=self_cont, adherent=adherent))
else:
raise EnvironmentError("Il n'y a pas de champs 'callback' pour le tag %s" % tag)
(code, tag) = self.handle_dialog(cont, box, default_item)
self_cont = TailCall(self.adherent_administratif, adherent=adherent, cont=cont, default_item=tag)
return self.handle_dialog_result(
code=code,
output=tag,
cancel_cont=cont,
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [tag, menu, adherent, self_cont])]
)
def adherent_adhesion(self, cont, adherent):
self.dialog.msgbox("todo", width=0, height=0)
return cont
def adherent_connexion(self, cont, adherent, cancel_cont=None):
self.dialog.msgbox("todo", width=0, height=0)
return cont
def adherent_carte_etudiant(self, cont, adherent, values={}, cancel_cont=None):
# Dictionnaire décrivant quelle est la valeur booléenne à donner à l'absence de l'attribut
a = attributs
choices = []
if self.has_right(a.tresorier, adherent) or not adherent.carte_controle():
choices.append((a.carteEtudiant.ldap_name, "Carte étudiant présentée", 1 if adherent[a.carteEtudiant.ldap_name] or values.get(a.carteEtudiant.ldap_name, False) else 0))
if self.has_right(a.tresorier, adherent):
choices.append(("controleCarte", "La carte a-t-elle été controlée", 1 if adherent.carte_controle() or values.get("controleCarte", False) else 0))
if not choices:
self.dialog.msgbox("Carte d'étudiant déjà validée et non modifiable", title="Gestion de la carte étudiant", width=0, height=0)
if cancel_cont:
cancel_cont(cont=cont)
try:
cont(cancel_cont=cancel_cont)
except TypeError:
pass
raise Continue(cont)
def box():
return self.dialog.checklist("Gestion de la carte étudiant",
height=0,
width=0,
timeout=self.timeout,
list_height=7,
choices=choices,
title="Gestion de la carte étudiant")
def todo(values, adherent, cont):
# On met à jour chaque attribut si sa valeur à changé
with self.conn.search(dn=adherent.dn, scope=0, mode='rw')[0] as adherent:
# Si on est trésorier et que controleCarte a changer on enregistre le changement
if self.has_right(a.tresorier, adherent) and values["controleCarte"] and not adherent.carte_controle():
if adherent["controle"]:
adherent["controle"] = u"c%s" % adherent["controle"][0]
else:
adherent["controle"] = u"c"
elif self.has_right(a.tresorier, adherent) and not values["controleCarte"] and adherent.carte_controle():
adherent["controle"]=unicode(adherent["controle"][0]).replace('c','')
if not adherent["controle"][0]:
adherent["controle"] = []
# Si la carte n'est pas validé ou qu'on est trésorier, on sauvegarde les changements
if values[a.carteEtudiant.ldap_name] and not adherent[a.carteEtudiant.ldap_name] and (not adherent.carte_controle() or self.has_right(a.tresorier, adherent)):
adherent[a.carteEtudiant.ldap_name] = u"TRUE"
elif not values[a.carteEtudiant.ldap_name] and adherent[a.carteEtudiant.ldap_name] and (not adherent.carte_controle() or self.has_right(a.tresorier, adherent)):
adherent[a.carteEtudiant.ldap_name] = []
if adherent["controle"]:
adherent["controle"]=unicode(adherent["controle"][0]).replace('c','')
if not adherent["controle"][0]:
adherent["controle"] = []
adherent.validate_changes()
adherent.history_gen()
adherent.save()
# On s'en va en mettant à jour dans la continuation la valeur de obj
raise Continue(cont(adherent=adherent))
(code, output) = self.handle_dialog(cont, box)
# On transforme la liste des cases dialog cochée en dictionnnaire
values = dict((a[0], a[0] in output) for a in choices)
# Une continuation que l'on suivra si quelque chose se passe mal
retry_cont = TailCall(self.adherent_carte_etudiant, adherent=adherent, cont=cont, values=values)
return self.handle_dialog_result(
code=code,
output=output,
cancel_cont=cancel_cont if cancel_cont else cont,
error_cont=retry_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [values, adherent, cont])]
)
def adherent_charte(self, cont, adherent):
a = attributs
attribs = [a.charteMA]
return self.edit_boolean_attributs(
obj=adherent,
attribs=attribs,
title="Signature de la charte membre actif de %s %s" % (adherent['prenom'][0], adherent['nom'][0]),
update_obj='adherent',
cont=cont)
def adherent_personnel(self, cont, adherent=None, fields_attrs={}, make_compte_crans=None, force_create=False):
"""
Permet d'éditer les nom, prénom et téléphone d'un adhérent, ou de créer un adhérent.
Il faut encore trouver un moyen de récupérer des valeurs pour les attributs mail et chbre
"""
a = attributs
# Quel sont les attributs ldap dont on veut afficher et
# la taille du champs d'édition correspondant
to_display = [(a.nom, 30), (a.prenom, 30), (a.tel, 30), (a.mail, 30)]
non_empty = [a.nom, a.prenom, a.tel]
input_type = {'default':0}
# Quel séparateur on utilise pour les champs multivalué
separateur = ' '
def box(make_compte_crans):
if force_create and adherent is None and fields_attrs and make_compte_crans is not None:
return (self.dialog.DIALOG_OK, [fields_attrs[a] for a,l in to_display], make_compte_crans)
if adherent:
attrs = dict((k,[str(a) for a in at]) for k,at in adherent.items())
if 'cransAccount' in adherent['objectClass']:
input_type[attributs.mail] = 2
to_display.append((attributs.mailExt, 30))
else:
attrs = {}
if make_compte_crans is None:
if self.dialog.yesno("Crééra-t-on un compte crans à l'utilisateur ?", timeout=self.timeout, title="Création d'un adhérent", width=50) == self.dialog.DIALOG_OK:
input_type[attributs.mail] = 2
make_compte_crans = True
to_display.append((attributs.mailExt, 30))
else:
make_compte_crans = False
fields = [(
"%s %s:" % (a.legend, '(optionnel) ' if a.optional else ''),
fields_attrs.get(a, separateur.join(attrs.get(a.ldap_name, [a.default] if a.default else []))),
l+1, l,
input_type.get(a, input_type['default'])
) for a,l in to_display]
(code, tags) = self.dialog.form(
text="",
timeout=self.timeout,
height=0, width=0, form_height=0,
fields=fields,
title="Création d'un adhérent" if adherent is None else "Édition des informations de %s %s" % (adherent['prenom'][0], adherent['nom'][0]),
backtitle="Gestion des adhérents du Crans")
return (code, tags, make_compte_crans)
def modif_adherent(adherent, attrs):
with self.conn.search(dn=adherent.dn, scope=0, mode='rw')[0] as adherent:
for (key, values) in attrs.items():
adherent[key]=values
adherent.validate_changes()
adherent.history_gen()
adherent.save()
return adherent
def create_adherent(attrs, make_compte_crans, force_create, self_cont, cont):
if not force_create:
items = self.conn.search("(&(prenom=%s)(nom=%s))" % (attrs['prenom'], attrs['nom']))
if items:
newadherent = self.select_one(items, title="Choisir un adhérant existant", text="Des adhérent avec les même noms et prénoms existent déjà, en utiliser un ?\n(Annuler pour continuer la création)", cont=self_cont(make_compte_crans=make_compte_crans, force_create=True))
raise Continue(cont(adherent=newadherent))
with self.conn.newAdherent({}) as adherent:
delay={}
for (key, values) in attrs.items():
try:
adherent[key]=values
# En cas d'erreur, on a peut être besoin du compte crans
except ValueError:
delay[key]=values
print delay
# on récupère la chambre
adherent = self.adherent_chambre_campus(success_cont=None, cont=self_cont(make_compte_crans=make_compte_crans), adherent=adherent, create=True)
# Si c'est EXT, on demande une adresse complète
if 'EXT' in adherent['chbre']:
adherent = self.adherent_chambre_ext(keep_machine=True, keep_compte=True, success_cont=None, cont=self_cont(make_compte_crans=make_compte_crans), adherent=adherent, create=True)
# Si compte crans à créer, on le crée.
# On le met en dernier pour éviter de faire entrez plusieurs fois son mdp à l'adhérent
# en cas d'erreur de la part du cableur
if make_compte_crans:
adherent = self.proprio_compte_create(proprio=adherent, cont=self_cont(make_compte_crans=None, force_create=False, adherent=None), update_obj='adherent', return_obj=True)
# On réeaffecte les attributs de tout à l'heure
for (key, values) in delay.items():
adherent[key]=values
# On confirme la création
if self.confirm_item(adherent, title="Créer l'adhérent suivant ?"):
adherent.validate_changes()
adherent.create()
else:
adherent = None
return adherent
def todo(to_display, non_empty, tags, adherent, separateur, make_compte_crans, force_create, self_cont, cont):
attrs = {}
# On traite les valeurs reçues
for ((a,l),values) in zip(to_display, tags):
if not values and a in non_empty:
raise ValueError("%s ne devrait pas être vide" % a.legend)
values = unicode(values, 'utf-8')
# Si le champs n'est pas single value, on utilise separateur pour découper
# et on ne garde que les valeurs non vides
if not a.singlevalue:
values = [v for v in values.split(separateur) if v]
attrs[a.ldap_name]=values
if adherent:
adherent = modif_adherent(adherent, attrs)
else:
adherent = create_adherent(attrs, make_compte_crans, force_create, self_cont, cont)
raise Continue(cont(adherent=adherent))
(code, tags, make_compte_crans) = self.handle_dialog(cont, box, make_compte_crans)
# On prépare les fiels à afficher à l'utilisateur si une erreure à lieu
# pendant le traitement des donnée (on n'éfface pas ce qui a déjà été entré
# c'est au cableur de corriger ou d'annuler
fields_attrs = dict((a, values) for ((a,l),values) in zip(to_display, tags))
retry_cont = TailCall(self.adherent_personnel, adherent=adherent, cont=cont, fields_attrs=fields_attrs)
return self.handle_dialog_result(
code=code,
output=tags,
cancel_cont=cont,
error_cont=retry_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [to_display, non_empty, tags, adherent, separateur, make_compte_crans, force_create, retry_cont, cont])]
)
@tailcaller
def adherent_chambre_campus(self, success_cont, cont, adherent, create=False):
"""Permet de faire déménager d'adhérent sur le campus"""
def box():
return self.dialog.inputbox(
"chambre ?",
title="%s de %s %s" % ("Création" if create else "Déménagement", adherent['prenom'][0], adherent["nom"][0]),
cancel_label="Retour",
width=50, timeout=self.timeout,
)
def expulse_squatteur(adherent, chbre):
with self.conn.search(u"chbre=%s" % chbre, mode='rw')[0] as squatteur:
if self.confirm_item(
item=squatteur,
title="Chambre occupée",
defaultno=True,
text=u"L'adhérent ci-dessous occupé déjà la chambre %s :\n" % output,
text_bottom=u"\nPasser la chambre de cet adhérent en chambre inconnue ?"
):
squatteur['chbre']=u'????'
squatteur.validate_changes()
squatteur.history_gen()
squatteur.save()
return True
else:
return False
def set_chambre(adherent, chbre):
try:
adherent['postalAddress']=[]
adherent['chbre']=unicode(output, 'utf-8')
except UniquenessError:
if expulse_squatteur(adherent, chbre):
# La chambre est maintenant normalement libre
adherent['chbre']=unicode(output, 'utf-8')
else:
raise Continue(self_cont)
return adherent
def todo(chbre, adherent, self_cont, success_cont):
if not output:
raise Continue(self_cont)
if output == "????":
raise ValueError("Chambre ???? invalide")
if create:
return set_chambre(adherent, chbre)
else:
with self.conn.search(dn=adherent.dn, scope=0, mode='rw')[0] as adherent:
adherent = set_chambre(adherent, chbre)
adherent.validate_changes()
adherent.history_gen()
adherent.save()
self.display_item(item=adherent, title="Adhérent déménagé dans la chambre %s" % output)
raise Continue(success_cont(adherent=adherent))
(code, output) = self.handle_dialog(cont, box)
self_cont = TailCall(self.adherent_chambre_campus, adherent=adherent, success_cont=success_cont, cont=cont, create=create)
return self.handle_dialog_result(
code=code,
output=output,
cancel_cont=cont,
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [output, adherent, self_cont, success_cont])]
)
@tailcaller
def adherent_chambre_ext(self, keep_machine, keep_compte, success_cont, cont, adherent, create=False):
"""Permet de faire déménager l'adhérent hors campus"""
if keep_machine and not keep_compte:
raise EnvironmentError("On ne devrait pas supprimer un compte crans et y laisser des machines")
elif keep_machine and keep_compte:
def box(values={}):
form = [("Adresse", 40), ("Compl. adr.", 40), ("Code postal", 7), ("Ville", 16)]
fields = [("%s :" % k, values.get(k, ""), l, 50) for k,l in form]
return self.dialog.form(
text="",
timeout=self.timeout,
height=0, width=0, form_height=0,
fields=fields,
title="Paramètres machine",
backtitle="Gestion des machines du Crans")
def todo(output, adherent, success_cont, cont):
if not create:
if self.dialog.yesno("changer l'adresse de l'adhérent pour %s ?" % ", ".join([o for o in output if o]),
title=u"Déménagement de %s %s" % (adherent['prenom'][0], adherent["nom"][0]),
defaultno=True, timeout=self.timeout) == self.dialog.DIALOG_OK:
with self.conn.search(dn=adherent.dn, scope=0, mode='rw')[0] as adherent:
adherent['postalAddress']=[unicode(pa, 'utf-8') for pa in output]
adherent['chbre']=u'EXT'
adherent.validate_changes()
adherent.history_gen()
adherent.save()
self.display_item(item=adherent, title="Adhérent déménégé hors campus, machines conservées")
raise Continue(success_cont(adherent=adherent))
else:
raise Continue(cont)
else:
adherent['postalAddress']=[unicode(pa, 'utf-8') for pa in output]
adherent['chbre']=u'EXT'
return adherent
elif not keep_machine and keep_compte:
if create:
raise EnvironmentError("On ne crée pas un adhérent en lui supprimant des machines")
def box(values={}):
return (self.dialog.DIALOG_OK, "")
def todo(output, adherent, success_cont, cont):
if self.confirm_item(
item=adherent,
text=u"Supprimer toutes les machines de l'adhérent ci-dessous ?\n\n",
text_bottom=u"\nLa chambre de l'adhérent passera de plus en EXT.",
title=u"Déménagement de %s %s" % (adherent['prenom'][0], adherent["nom"][0]),
defaultno=True):
with self.conn.search(dn=adherent.dn, scope=0, mode='rw')[0] as adherent:
for machine in adherent.machines():
with machine:
machine.delete()
adherent['chbre']=u'EXT'
adherent.validate_changes()
adherent.history_gen()
adherent.save()
self.display_item(item=adherent, title="Adhérent déménégé hors campus, machines supprimées")
raise Continue(success_cont(adherent=adherent))
else:
raise Continue(cont)
elif not keep_machine and not keep_compte:
if create:
raise EnvironmentError("On ne crée pas un adhérent en lui supprimant des machines et un compte")
def box(values={}):
return (self.dialog.DIALOG_OK, "")
def todo(output, adherent, success_cont, cont):
if adherent.get('solde', [0])[0] > 0:
self.dialog.msgbox("Solde de l'adhérent %s€ strictement positif, impossible de supprimer le compte\nRepasser le solde à 0€ pour supprimer le compte." % adherent.get('solde', [0])[0],
title=u"Déménagement de %s %s" % (adherent['prenom'][0], adherent["nom"][0]),
width=50, timeout=self.timeout)
raise Continue(cont)
elif self.confirm_item(
item=adherent,
text=u"Supprimer toutes les machines et du compte crans de l'adhérent ci-dessous ?\n\n",
text_bottom=u"\nLa chambre de l'adhérent passera de plus en EXT.",
title=u"Déménagement de %s %s" % (adherent['prenom'][0], adherent["nom"][0]),
defaultno=True):
with self.conn.search(dn=adherent.dn, scope=0, mode='rw')[0] as adherent:
for machine in adherent.machines():
with machine:
machine.delete()
adherent['chbre']=u'EXT'
adherent.validate_changes()
adherent.history_gen()
adherent.save()
# On supprime le compte crans (on essaye)
def post_deletion(proprio, cont):
if not "cransAccount" in proprio['objectClass']:
self.display_item(item=adherent, title="Adhérent déménégé hors campus, machines et compte crans supprimées")
else:
self.display_item(item=adherent, title="Adhérent déménégé hors campus, machines supprimées et compte crans concervé")
raise Continue(cont(adherent=proprio))
self.proprio_compte_delete(proprio=adherent, cont=TailCall(post_deletion, proprio=adherent, cont=success_cont(adherent=adherent)), force=True)
else:
raise Continue(cont)
else:
raise EnvironmentError("Impossible, on a fait tous les cas, python est buggué")
(code, output) = self.handle_dialog(cont, box)
self_cont = TailCall(self.adherent_chambre_ext, adherent=adherent, keep_machine=keep_machine, keep_compte=keep_compte, success_cont=success_cont, cont=cont)
return self.handle_dialog_result(
code=code,
output=output,
cancel_cont=cont,
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [output, adherent, success_cont, cont])]
)
def adherent_chambre(self, adherent, cont, default_item=None):
"""Permet de faire déménager d'adhérent"""
a = attributs
menu_droits = {
'0' : [a.cableur, a.nounou],
'1' : [a.cableur, a.nounou],
'2' : [a.cableur, a.nounou],
'3' : [a.cableur, a.nounou],
}
menu = {
"0": {'text':"Déménagement sur le campus", 'callback':self.adherent_chambre_campus, 'help': "Déménagement vers une chambre sur le campus, on ne demande que le bâtiment et la chambre"},
"1": {'text':"Déménagement à l'extérieur en conservant les machines", "callback": TailCall(self.adherent_chambre_ext, keep_machine=True, keep_compte=True), "help": "Pour concerver ses machines, il faut donner un adresse postale complète"},
"2": {'text':"Départ du campus en conservant son compte", "callback":TailCall(self.adherent_chambre_ext, keep_machine=False, keep_compte=True), "help":"Supprime les machines mais concerve le compte crans, l'adresse passe en EXT sans plus d'information"},
"3": {'text':"Départ du campus en supprimant son compte", "callback":TailCall(self.adherent_chambre_ext, keep_machine=False, keep_compte=False), "help":"Supprime les machines et le compte crans, l'adhérent reste dans la base de donnée, il est possible de mettre une redirection du mail crans vers une autre adresse dans bcfg2"},
}
menu_order = [str(i) for i in range(4)]
def box(default_item=None):
return self.dialog.menu(
"Quel est le type du déménagement ?",
width=0,
height=0,
menu_height=0,
timeout=self.timeout,
item_help=1,
default_item=str(default_item),
title="Déménagement de %s %s" % (adherent['prenom'][0], adherent["nom"][0]),
scrollbar=True,
cancel_label="Retour",
backtitle=u"Vous êtes connecté en tant que %s" % self.conn.current_login,
choices=[(k, menu[k]['text'], menu[k]['help']) for k in menu_order if self.has_right(menu_droits[k], adherent)])
def todo(tag, menu, adherent, self_cont, cont):
if not tag in menu_order:
raise Continue(self_cont)
else:
raise Continue(TailCall(menu[tag]['callback'], cont=self_cont, success_cont=cont, adherent=adherent))
(code, tag) = self.handle_dialog(cont, box, default_item)
self_cont = TailCall(self.adherent_chambre, adherent=adherent, cont=cont, default_item=tag)
return self.handle_dialog_result(
code=code,
output=tag,
cancel_cont=cont,
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [tag, menu, adherent, self_cont, cont])]
)
def create_adherent(self, cont):
"""Crée un adhérent et potentiellement son compte crans avec lui"""
def mycont(adherent=None, **kwargs):
if adherent:
# Une fois l'adhérent créé, on vois s'il donne sa carte étudiant et s'il adhére/prend la connexion internet
adh_cont = TailCall(self.modif_adherent, cont=cont, adherent=adherent)
conn_cont = TailCall(self.adherent_connexion, cont=adh_cont, adherent=adherent)
carte_cont = TailCall(self.adherent_carte_etudiant, cont=conn_cont, adherent=adherent)
etude_cont = TailCall(self.adherent_etudes, cont=carte_cont, adherent=adherent)
etude_cont(cancel_cont=etude_cont)
carte_cont(cancel_cont=etude_cont)
conn_cont(cancel_cont=carte_cont)
raise Continue(etude_cont)
else:
raise Continue(cont)
return self.adherent_personnel(cont=TailCall(mycont))
def delete_adherent(self, cont, del_cont, adherent=None):
"""Permet la suppression d'un adhérent de la base ldap"""
if adherent is None:
adherent = self.select(["adherent"], "Recherche d'un adhérent pour supression", cont=cont)
def todo(adherent):
if self.confirm_item(item=adherent, title="Voulez vous vraiement supprimer l'adhérent ?", defaultno=True):
with self.conn.search(dn=adherent.dn, scope=0, mode='rw')[0] as adherent:
adherent.delete()
self.dialog.msgbox("L'adherent a bien été supprimée", timeout=self.timeout, title="Suppression d'un adherent")
raise Continue(del_cont(proprio=None))
else:
raise Continue(cont)
return self.handle_dialog_result(
code=self.dialog.DIALOG_OK,
output="",
cancel_cont=cont(proprio=adherent),
error_cont=cont(proprio=adherent),
codes_todo=[([self.dialog.DIALOG_OK], todo, [adherent])]
)
def adherent_droits(self, adherent, cont, choices_values=None):
"""Gestion des droits d'un adhérent"""
def box():
return self.dialog.checklist(
text="",
height=0, width=0, list_height=0,
choices=choices_values if choices_values else [(droit, "", 1 if droit in adherent["droits"] else 0) for droit in attributs.TOUS_DROITS],
title="Droits de %s %s" % (adherent['prenom'][0], adherent['nom'][0]),
timeout=self.timeout
)
def todo(droits, adherent, self_cont, cont):
# Les vérifications de sécurité sont faites dans lc_ldap
with self.conn.search(dn=adherent.dn, scope=0, mode='rw')[0] as adherent:
adherent['droits']=[unicode(d) for d in droits]
adherent.validate_changes()
adherent.history_gen()
adherent.save()
if adherent["uid"] and adherent["uid"][0] == self.conn.current_login:
self.check_ldap()
raise Continue(cont(adherent=adherent))
(code, droits) = self.handle_dialog(cont, box)
self_cont = TailCall(self.adherent_droits, adherent=adherent, cont=cont, choices_values=[(d, "", 1 if d in droits else 0) for d in attributs.TOUS_DROITS])
return self.handle_dialog_result(
code=code,
output=droits,
cancel_cont=cont,
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [droits, adherent, self_cont, cont])]
)
def adherent_etudes(self, adherent, cont, default_item=None, etablissement=None, annee=None, section=None):
"""Gestion des études de l'adhérent. etudes est un triplet (établissement, année, section)"""
choices_etablissement = [
('Autre', ''),
('ENS', 'École Normale Supérieure'),
('IUT Cachan', ''),
('Maximilien Sorre', ''),
('Gustave Eiffel', ''),
('EFREI', ''),
('ESTP', ''),
('P1', 'Université Panthéon Sorbonne'),
('P2', 'Université Panthéon Assas'),
('P3', 'Université de la Sorbonne Nouvelle'),
('P4', 'Université Paris Sorbonne'),
('P5', 'Université René Descartes'),
('P6', 'Université Pierre et Marie Curie'),
('P7', 'Université Paris Diderot'),
('P8', 'Université Vincennes Saint Denis'),
('P9', 'Université Paris Dauphine'),
('P10', 'Université de Nanterre'),
('P11', 'Université de Paris Sud (Orsay)'),
('P12', 'Université Val de Marne (Créteil)'),
('P13', 'Université Paris Nord'),
('IUFM', ''),
('Personnel ENS', "appartement ENS ou personnel CROUS"),
]
LMD = ['P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7', 'P8', 'P9', 'P10', 'P11', 'P12', 'P13']
LM = ['EFREI']
LYCEE = ['Maximilien Sorre', 'Gustave Eiffel']
ANNEE = ['IUT Cachan', 'ESTP']
def choices(max_annee):
c = []
if max_annee>=1:
c.append(('1', '1ère année'))
for i in range(2, max_annee+1):
c.append((str(i), "%sème année" % i))
c.append(('Autre', ''))
return c
choices_LMD = [
('L1', 'Licence 1ère année'),
('L2', 'Licence 2ième année'),
('L3', 'Licence 3ième année'),
('M1', 'Master 1ère année'),
('M2', 'Master 2ième année'),
('D1', '1ère année de thèse'),
('D2', '2ième année de thèse'),
('D3', '3ième année de thèse'),
('Autre', ''),
]
choices_LM = choices_LMD[:5] + choices_LMD[-1:]
choices_ENS = [
('1', 'Licence'),
('2', 'Master 1'),
('3', 'Agrégation'),
('4', 'Master 2'),
('5', '1ère année de thèse'),
('6', '2ième année de thèse'),
('7', '3ième année de thèse'),
('Autre', ''),
]
section_ENS = [
('A0', 'Informatique'),
('A1', 'Mathématiques'),
('A2', 'Physique fondamentale'),
("A'2", 'Physique appliquée'),
("A''2", 'Chimie'),
('A3', 'Biochimie'),
('B1', 'Mécanique'),
('B2', 'Génie civil'),
('B3', 'Génie mécanique'),
('B4', 'Génie électrique'),
('C', 'Art et création industrielle'),
('D2', 'Economie gestion'),
('D3', 'Sciences sociales'),
('E', 'Anglais'),
('Autre', ''),
]
choices_LYCEE = [
('Seconde',''),
('Première',''),
('Terminale',''),
('1/2', '1ère année de prépa'),
('3/2', '2nd année de prépa'),
('5/2', '3ième année de prépa'),
('Autre',''),
]
def box_etablissement(default_item):
if etablissement == 'Autre' or \
(etablissement is not None and etablissement not in [i[0] for i in choices_etablissement]) or \
(default_item is not None and default_item not in [i[0] for i in choices_etablissement]):
return self.dialog.inputbox(
text="Choisissez l'établissement :",
title="Études de %s %s" % (adherent['prenom'][0], adherent["nom"][0]),
timeout=self.timeout,
init=str(default_item) if default_item else "")
else:
return self.dialog.menu(
"Choisissez l'établissement :",
width=0,
height=0,
menu_height=0,
timeout=self.timeout,
item_help=0,
default_item=str(default_item) if default_item else 'ENS',
title="Études de %s %s" % (adherent['prenom'][0], adherent["nom"][0]),
scrollbar=True,
cancel_label="Retour",
backtitle=u"Vous êtes connecté en tant que %s" % self.conn.current_login,
choices=choices_etablissement)
def box_annee(default_item):
if etablissement in LMD:
box_choice = choices_LMD
elif etablissement in LM:
box_choice = choices_LM
elif etablissement in LYCEE:
box_choice = choices_LYCEE
elif etablissement == 'ENS':
box_choice = choices_ENS
else:
box_choice = choices(7)
if not box_choice or annee == 'Autre' or \
(annee is not None and annee not in [i[0] for i in box_choice]) or \
(default_item is not None and default_item not in [i[0] for i in box_choice]):
return self.dialog.inputbox(
text="Choisissez l'année administrative :",
title="Études de %s %s" % (adherent['prenom'][0], adherent["nom"][0]),
timeout=self.timeout,
init=str(default_item) if default_item else "")
else:
return self.dialog.menu(
"Choisissez l'année administrative :",
width=0,
height=0,
menu_height=0,
timeout=self.timeout,
item_help=0,
default_item=str(default_item),
title="Études de %s %s" % (adherent['prenom'][0], adherent["nom"][0]),
scrollbar=True,
cancel_label="Retour",
backtitle=u"Vous êtes connecté en tant que %s" % self.conn.current_login,
choices=box_choice)
def box_section(default_item):
if etablissement != 'ENS' or section == 'Autre' or \
(section and section not in [i[0] for i in section_ENS]) or \
(default_item is not None and default_item not in [i[0] for i in section_ENS]):
return self.dialog.inputbox(
text="Choisissez la section :",
title="Études de %s %s" % (adherent['prenom'][0], adherent["nom"][0]),
timeout=self.timeout,
init=str(default_item) if default_item else "")
else:
return self.dialog.menu(
"Choisissez la section :",
width=0,
height=0,
menu_height=0,
timeout=self.timeout,
item_help=0,
default_item=str(default_item),
title="Études de %s %s" % (adherent['prenom'][0], adherent["nom"][0]),
scrollbar=True,
cancel_label="Retour",
backtitle=u"Vous êtes connecté en tant que %s" % self.conn.current_login,
choices=section_ENS)
self_cont = TailCall(self.adherent_etudes, adherent=adherent, cont=cont, default_item=default_item, etablissement=etablissement, annee=annee, section=section)
if etablissement is None or etablissement == 'Autre':
if not default_item and adherent["etudes"]:
default_item = str(adherent["etudes"][0])
cancel_cont = cont
(code, etablissement) = self.handle_dialog(cancel_cont, box_etablissement, default_item)
output = etablissement
self_cont(default_item=etablissement)
elif annee is None or annee == 'Autre':
if not default_item and adherent["etudes"]:
default_item = str(adherent["etudes"][1])
print default_item
cancel_cont = TailCall(self.adherent_etudes, adherent=adherent, cont=cont, default_item=etablissement, etablissement=None, annee=None, section=None)
(code , annee) = self.handle_dialog(cancel_cont, box_annee, default_item)
output = annee
self_cont(default_item=annee)
elif section is None or section == 'Autre':
if not default_item and adherent["etudes"]:
default_item = str(adherent["etudes"][2])
cancel_cont = TailCall(self.adherent_etudes, adherent=adherent, cont=cont, default_item=annee, etablissement=etablissement, annee=None, section=None)
(code, section) = self.handle_dialog(cancel_cont, box_section, default_item)
output = section
self_cont(default_item=section)
else:
output = ""
cancel_cont = TailCall(self.adherent_etudes, adherent=adherent, cont=cont, default_item=section, etablissement=etablissement, annee=annee, section=None)
def todo(etablissement, annee, section, adherent, self_cont, cont):
if etablissement is None or etablissement == 'Autre':
raise Continue(self_cont(default_item=None, etablissement=etablissement))
elif annee is None or annee == 'Autre':
raise Continue(self_cont(default_item=None, etablissement=etablissement, annee=annee))
elif section is None or section == 'Autre':
raise Continue(self_cont(default_item=None, etablissement=etablissement, annee=annee, section=section))
else:
if not adherent["etudes"] or adherent["etudes"][0] != etablissement or adherent["etudes"][1] != annee or adherent["etudes"][2] != section:
with self.conn.search(dn=adherent.dn, scope=0, mode='rw')[0] as adherent:
adherent["etudes"]=[unicode(etablissement), unicode(annee), unicode(section)]
adherent.validate_changes()
adherent.history_gen()
adherent.save()
raise Continue(cont(adherent=adherent))
return self.handle_dialog_result(
code=code,
output=output,
cancel_cont=cancel_cont,
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [etablissement, annee, section, adherent, self_cont, cont])]
)