662 lines
35 KiB
Python
662 lines
35 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 (perso, je pense que c'est à supprimer)", "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.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])]
|
|
)
|
|
|
|
def adherent_etudes(self, adherent, cont, cancel_cont=None):
|
|
"""Gestion des études de l'adhérent"""
|
|
self.dialog.msgbox("todo", width=0, height=0)
|
|
return 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.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.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.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.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.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.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])]
|
|
)
|
|
|
|
|