mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-10-31 15:50:03 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			334 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			334 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| WEI
 | |
| ===
 | |
| 
 | |
| Cette application gère toute la phase d'inscription au WEI.
 | |
| 
 | |
| Modèles
 | |
| -------
 | |
| 
 | |
| WEIClub
 | |
| ~~~~~~~
 | |
| 
 | |
| Le modèle ``WEIClub`` hérite de ``Club`` et contient toutes les informations d'un WEI.
 | |
| 
 | |
| * ``year`` : ``PositiveIntegerField`` unique, année du WEI.
 | |
| * ``date_start`` : ``DateField``, date de début du WEI.
 | |
| * ``date_end`` : ``DateField``, date de fin du WEI.
 | |
| 
 | |
| Champs hérités de ``Club`` de l'application ``member`` : 
 | |
| 
 | |
| * ``parent_club`` : ``ForeignKey(Club)``. Ce champ vaut toujours ``Kfet`` dans le cas d'un WEI : on doit être membre du
 | |
|   club Kfet pour participer au WEI.
 | |
| * ``email`` : ``EmailField``, adresse e-mail sur laquelle contacter les gérant⋅es du WEI.
 | |
| * ``membership_start`` : ``DateField``, date à partir de laquelle il est possible de s'inscrire au WEI.
 | |
| * ``membership_end`` : ``DateField``, date de fin d'adhésion possible au WEI.
 | |
| * ``membership_duration`` : ``PositiveIntegerField``, inutilisé dans le cas d'un WEI, vaut ``None``.
 | |
| * ``membership_fee_paid`` : ``PositiveIntegerField``, montant de la cotisation (en centimes) pour qu'un⋅e élève normalien⋅ne
 | |
|   (donc rémunéré⋅e) puisse adhérer.
 | |
| * ``membership_fee_unpaid`` : ``PositiveIntegerField``, montant de la cotisation (en centimes) pour qu'un⋅e étudiant⋅e
 | |
|   normalien⋅ne (donc non rémunéré⋅e) puisse adhérer.
 | |
| * ``name`` : ``CharField``, nom du WEI.
 | |
| * ``require_memberships`` : ``BooleanField``, vaut toujours ``True`` pour le WEI.
 | |
| 
 | |
| Bus
 | |
| ~~~
 | |
| 
 | |
| Contient les informations sur un bus allant au WEI.
 | |
| 
 | |
| * ``wei`` : ``ForeignKey(WEIClub)``, WEI auquel ce bus est rattaché.
 | |
| * ``name`` : ``CharField``, nom du bus. Le champ est unique pour le WEI attaché.
 | |
| * ``description`` : ``TextField``, description textuelle de l'ambiance du bus.
 | |
| * ``information_json`` : ``TextField``, diverses informations non publiques qui permettent d'indiquer divers paramètres
 | |
|   pouvant varier selon les années permettant l'attribution des bus aux 1A.
 | |
| 
 | |
| Il est souhaitable de créer chaque année un bus "Staff" (non accessible aux 1A bien évidemment) pour les GC WEI qui ne
 | |
| monteraient pas dans un bus.
 | |
| 
 | |
| BusTeam
 | |
| ~~~~~~~
 | |
| 
 | |
| Contient les informations d'une équipe WEI.
 | |
| 
 | |
| * ``wei`` : ``ForeignKey(WEIClub)``, WEI auquel cette équipe est rattachée.
 | |
| * ``name`` : ``CharField``, nom de l'équipe.
 | |
| * ``color`` : ``PositiveIntegerField``, entier entre 0 et 16777215 = 0xFFFFFF représentant la couleur du T-Shirt.
 | |
|   La donnée se rentre en hexadécimal via un sélecteur de couleur. Cette information est purement cosmétique et n'est
 | |
|   utilisée nulle part.
 | |
| * ``description`` : ``TextField``, description de l'équipe.
 | |
| 
 | |
| WEIRole
 | |
| ~~~~~~~
 | |
| 
 | |
| Ce modèle hérité de  ``Role``, ne contient qu'un champ ``name`` (``CharField``), le nom du rôle. Ce modèle ne permet
 | |
| que de dissocier les rôles propres au WEI des rôles s'appliquant pour n'importe quel club.
 | |
| 
 | |
| WEIRegistration
 | |
| ~~~~~~~~~~~~~~~
 | |
| 
 | |
| Inscription au WEI, contenant les informations avant validation. Ce modèle est créé dès lors que quelqu'un⋅e se pré-inscrit au WEI.
 | |
| 
 | |
| * ``user`` : ``ForeignKey(User)``, utilisateur⋅rice qui s'est pré-inscrit⋅e. Ce champ est unique avec ``wei``.
 | |
| * ``wei`` : ``ForeignKey(WEIClub)``, le WEI auquel l'utilisateur⋅rice s'est pré-inscrit⋅e. Ce champ est unique avec ``user``.
 | |
| * ``soge_credit`` : ``BooleanField``, indique si l'utilisateur⋅rice a déclaré vouloir ouvrir un compte à la Société générale.
 | |
| * ``caution_check`` : ``BooleanField``, indique si l'utilisateur⋅rice (en 2ème année ou plus) a bien remis son chèque de
 | |
|   caution auprès de la trésorerie.
 | |
| * ``birth_date`` : ``DateField``, date de naissance de l'utilisateur⋅rice.
 | |
| * ``gender`` : ``CharField`` parmi ``male`` (Homme), ``female`` (Femme), ``non binary`` (Non binaire), genre de la personne.
 | |
| * ``health_issues`` : ``TextField``, problèmes de santé déclarés par l'utilisateur⋅rice.
 | |
| * ``emergency_contact_name`` : ``CharField``, nom du contact en cas d'urgence.
 | |
| * ``emergency_contact_phone`` : ``CharField``, numéro de téléphone du contact en cas d'urgence.
 | |
| * ``ml_events_registration`` : ``BooleanField``, déclare si l'utilisateur⋅rice veut s'inscrire à la liste de diffusion des
 | |
|   événements du BDE (1A uniquement)
 | |
| * ``ml_art_registration`` : ``BooleanField``, déclare si l'utilisateur⋅rice veut s'inscrire à la liste de diffusion des
 | |
|   actualités du BDA (1A uniquement)
 | |
| * ``ml_sport_registration`` : ``BooleanField``, déclare si l'utilisateur⋅rice veut s'inscrire à la liste de diffusion des
 | |
|   actualités du BDS (1A uniquement)
 | |
| * ``first_year`` : ``BooleanField``, indique si l'inscription est d'un⋅e 1A ou non. Non modifiable par n'importe qui.
 | |
| * ``information_json`` : ``TextField`` non modifiable manuellement par n'importe qui stockant les informations du
 | |
|   questionnaire d'inscription au WEI pour les 1A, et stocke les demandes faites par un⋅e 2A+ concernant bus, équipes et rôles.
 | |
|   On utilise un ``TextField`` contenant des données au format JSON pour permettre de la modularité au fil des années,
 | |
|   sans avoir à tout casser à chaque fois.
 | |
| 
 | |
| WEIMembership
 | |
| ~~~~~~~~~~~~~
 | |
| 
 | |
| Ce modèle hérite de ``Membership`` et contient les informations d'une adhésion au WEI.
 | |
| 
 | |
| * ``bus`` : ``ForeignKey(Bus)``, bus dans lequel se trouve l'utilisateur⋅rice.
 | |
| * ``team`` : ``ForeignKey(BusTeam)`` pouvant être nulle (pour les chefs de bus et électrons libres), équipe dans laquelle
 | |
|   se trouve l'utilisateur⋅rice.
 | |
| * ``registration`` : ``OneToOneField(WEIRegistration)``, informations de la pré-inscription.
 | |
| 
 | |
| Champs hérités du modèle ``Membership`` :
 | |
| 
 | |
| * ``club`` : ``ForeignKey(Club)``, club lié à l'adhésion. Doit être un ``WEIClub``.
 | |
| * ``user`` : ``ForeignKey(User)``, utilisateur⋅rice qui a adhéré.
 | |
| * ``date_start`` : ``DateField``, date de début d'adhésion.
 | |
| * ``date_end`` : ``DateField``, date de fin d'adhésion.
 | |
| * ``fee`` : ``PositiveIntegerField``, montant de la cotisation payée.
 | |
| * ``roles`` : ``ManyToManyField(Role)``, liste des rôles endossés par l'adhérent⋅e. Les rôles doivent être des ``WEIRole``.
 | |
| 
 | |
| Graphe des modèles
 | |
| ~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| Pour une meilleure compréhension, le graphe des modèles de l'application ``member`` ont été ajoutés au schéma.
 | |
| 
 | |
| .. image:: ../_static/img/graphs/wei.svg
 | |
|    :width: 960
 | |
|    :alt: Graphe des modèles de l'application WEI
 | |
| 
 | |
| Fonctionnement
 | |
| --------------
 | |
| 
 | |
| Création d'un WEI
 | |
| ~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| Seul un⋅e respo info peut créer un WEI. Pour cela, se rendre dans l'onglet WEI, puis « Liste des WEI » et enfin
 | |
| « Créer un WEI ». Diverses informations sont demandées, comme le nom du WEI, l'adresse mail de contact, l'année du WEI
 | |
| (doit être unique), les dates de début et de fin, et les dates pendant lesquelles les utilisateurs peuvent s'inscrire.
 | |
| 
 | |
| Don des droits à un GC WEI
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| Læ GC WEI peut gérer tout ce qui a un rapport avec le WEI. Iel ne peut cependant pas créer le WEI, ce privilège est
 | |
| réservé aux respos info. Pour avoir ses droits, læ GC WEI doit s'inscrire au WEI avec le rôle GC WEI, et donc payer
 | |
| en premièr⋅e sa cotisation. C'est donc aux respos info de créer l'adhésion du GC WEI. Voir ci-dessous pour l'inscription au WEI.
 | |
| 
 | |
| S'inscrire au WEI
 | |
| ~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| N'importe quel⋅le utilisateur⋅rice peut s'auto-inscrire au WEI, lorsque les dates d'adhésion le permettent. Celleux qui se sont
 | |
| déjà inscrit⋅es peuvent également inscrire un⋅e 1A. Seul⋅es les GC WEI et les respos info peuvent inscrire un⋅e autre 2A+.
 | |
| 
 | |
| À tout moment, tant que le WEI n'est pas passé, l'inscription peut être modifiée, même après validation.
 | |
| 
 | |
| Inscription d'un⋅e 2A+
 | |
| ^^^^^^^^^^^^^^^^^^^^^^
 | |
| 
 | |
| Comme indiqué, les 2A+ sont assez autonomes dans leur inscription au WEI. Iels remplissent le questionnaire et sont
 | |
| ensuite pré-inscrit⋅es. Le questionnaire se compose de plusieurs champs (voir WEIRegistration) :
 | |
| 
 | |
| * Est-ce que l'utilisateur⋅rice a déclaré avoir ouvert un compte à la Société générale ? (Option disponible uniquemement
 | |
|   si cela n'a pas été fait une année avant)
 | |
| * Date de naissance
 | |
| * Genre (Homme/Femme/Non-binaire)
 | |
| * Problèmes de santé
 | |
| * Nom du contact en cas d'urgence
 | |
| * Numéro du contact en cas d'urgence
 | |
| * Bus préférés (choix multiple, utile pour les électrons libres)
 | |
| * Équipes préférées (choix multiple éventuellement vide, vide pour les chefs de bus/staff)
 | |
| * Rôles souhaités
 | |
| 
 | |
| Les trois derniers champs n'ont aucun caractère définitif et sont simplement là en suggestion pour læ GC WEI qui
 | |
| validera l'inscription. C'est utile si on hésite entre plusieurs bus.
 | |
| 
 | |
| L'inscription est ensuite créée, le GC WEI devra ensuite la valider (voir plus bas).
 | |
| 
 | |
| Inscription d'un⋅e 1A
 | |
| ^^^^^^^^^^^^^^^^^^^^^
 | |
| 
 | |
| N'importe quelle personne déjà inscrite au WEI peut inscrire un⋅e 1A. Le formulaire 1A est assez peu différent du formulaire 2A+ :
 | |
| 
 | |
| * Est-ce que l'utilisateur⋅rice a déclaré avoir ouvert un compte à la Société générale ?
 | |
| * Date de naissance
 | |
| * Genre (Homme/Femme/Non-binaire)
 | |
| * Problèmes de santé
 | |
| * Nom du contact en cas d'urgence
 | |
| * Numéro du contact en cas d'urgence
 | |
| * S'inscrire à la ML événements
 | |
| * S'inscrire à la ML BDA
 | |
| * S'inscrire à la ML BDS
 | |
| 
 | |
| Læ 1A ne peut donc pas choisir de son bus et de son équipe, et peut s'inscrire aux listes de diffusion.
 | |
| Il y a néanmoins une différence majeure : une fois le formulaire rempli, un questionnaire se lance.
 | |
| Ce questionnaire peut varier au fil des années (voir section Questionnaire), et contient divers formulaires de collecte
 | |
| de données qui serviront à déterminer quel est le meilleur bus pour ce⋅tte nouvelleau utilisateur⋅rice.
 | |
| 
 | |
| Questionnaire 1A
 | |
| ^^^^^^^^^^^^^^^^
 | |
| 
 | |
| Le questionnaire 1A permet de poser des questions aux 1A lors de leur inscription au WEI afin de déterminer quel serait
 | |
| le meilleur bus pour eux. Un algorithme attribue ensuite à chaque 1A le bus sélectionné.
 | |
| 
 | |
| Afin de permettre de la modularité et de s'adapter aux changements au fil des années, il n'y a pas de modèle dédié au
 | |
| sondage. On sauvegarde alors les données du sondage sous la forme d'un dictionnaire enregistré au format JSON
 | |
| dans le champ ``information_json`` du modèle ``WEIRegistration``. Ce champ est modifiable manuellement uniquement par
 | |
| les respos info et les GC WEI.
 | |
| 
 | |
| Je veux changer d'algorithme de répartition, que faire ?
 | |
| """"""""""""""""""""""""""""""""""""""""""""""""""""""""
 | |
| 
 | |
| Cette section est plus technique et s'adresse surtout aux respos info en cours de mandat.
 | |
| 
 | |
| Première règle : on ne supprime rien (sauf si vraiment c'est du mauvais boulot). En prenant exemple sur des fichiers déjà existant tels que ``apps/wei/forms/surveys/wei2021.py``, créer un nouveau fichier ``apps/wei/forms/surveys/wei20XY.py``. Ce fichier doit inclure les éléments suivants :
 | |
| 
 | |
| WEISurvey
 | |
| """""""""
 | |
| 
 | |
| Une classe héritant de ``wei.forms.surveys.base.WEISurvey``, comportant les éléments suivants :
 | |
| 
 | |
| * Une fonction ``get_year(cls)`` indiquant l'année du WEI liée au sondage
 | |
| * Une fonction ``get_survey_information_class(cls)`` indiquant la classe héritant de
 | |
|   ``wei.forms.surveys.base.WEISurveyInformation`` contenant les données du sondage (voir plus bas)
 | |
| * Une fonction ``get_algorithm_class(cls)`` indiquant la classe héritant de
 | |
|   ``wei.forms.surveys.base.WEISurveyAlgorithm`` contenant l'algorithme de répartition (voir plus bas)
 | |
| * Une fonction ``get_form_class(self)`` qui indique la classe du formulaire Django à remplir. Cette classe peut dépendre
 | |
|   de l'état actuel du sondage.
 | |
| * Une fonction ``update_form(self, form)``, optionnelle, appelée lorsqu'un formulaire dont la classe est spécifiée via
 | |
|   la fonction ``get_form_class``, et permet d'opérer sur le formulaire si besoin.
 | |
| * Une fonction ``form_valid(self, form)`` qui indique quoi faire lorsque le formulaire est rempli. Cette fonction peut
 | |
|   bien sûr dépendre de l'état actuel du sondage.
 | |
| * Une fonction ``is_complete(self)`` devant renvoyer un booléen indiquant si le sondage est complet ou non.
 | |
| 
 | |
| Naturellement, il est implicite qu'une fonction ayant pour premier argument ``cls`` doit être annotée par ``@classmethod``.
 | |
| Nativement, la classe ``WEISurvey`` comprend les informations suivantes :
 | |
| 
 | |
| * ``registration``, le modèle ``WEIRegistration`` de l'utilisateur⋅rice qui remplit le questionnaire
 | |
| * ``information``, instance de ``WEISurveyInformation``, contient les données du questionnaire en cours de remplissage.
 | |
| * ``get_wei(cls)``, renvoie le WEI correspondant à l'année du sondage.
 | |
| * ``save(self)``, enregistre les informations du sondage dans l'objet ``registration`` associé, qui est ensuite
 | |
|   enregistré en base de données.
 | |
| * ``select_bus(self, bus)``, choisit le bus ``bus`` comme bus préféré. Cela à pour effet de remplir les champs
 | |
|   ``selected_bus_pk`` et ``selected_bus_name`` par les identifiant et nom du bus, et ``valid`` à ``True``.
 | |
| 
 | |
| Pour information, ``WEISurvey.__init__`` prend comme paramètre l'inscription ``registration``, et récupère les
 | |
| informations du sondage converties en dictionnaire Python puis en objet ``WEISurveyInformation``.
 | |
| 
 | |
| WEISurveyInformation
 | |
| """"""""""""""""""""
 | |
| 
 | |
| Une classe héritant de ``wei.forms.surveys.base.WEISurveyInformation``, comportant les informations brutes du sondage.
 | |
| Le champ ``information_json`` de ``WEIRegistration`` est traduit en dictionnaire Python depuis JSON, puis les différents
 | |
| champs de WEISurveyInformation sont mis à jour depuis ce dictionnaire. Il n'y a rien de supplémentaire à ajouter, tout
 | |
| est déjà géré.
 | |
| 
 | |
| Ainsi, plutôt que de modifier laborieusement le champ JSON, préférez utiliser cette classe. Attention : pour des soucis
 | |
| de traduction facile, merci de n'utiliser que des objets primitifs (nombres, chaînes de caractère, booléens, listes,
 | |
| dictionnaires simples). Les instances de modèle sont à proscrire, préférez stocker l'identifiant et créer une fonction
 | |
| qui récupère l'instance à partir de l'identifiant.
 | |
| 
 | |
| Attention, 3 noms sont réservés : ``selected_bus_pk``, ``selected_bus_name`` et ``valid``, qui représentent la sortie
 | |
| de l'algorithme de répartition.
 | |
| 
 | |
| À noter que l'interface de validation des inscriptions affiche les données brutes du sondage.
 | |
| 
 | |
| WEIBusInformation
 | |
| """""""""""""""""
 | |
| 
 | |
| Une classe héritant de ``wei.forms.surveys.base.WEIBusInformation``, qui contient les informations sur un bus,
 | |
| de la même manière que ``WEISurveyInformation`` contient les informations d'un sondage. Le fonctionnement est le même :
 | |
| on récupère le champ ``information_json`` du modèle ``Bus`` qu'on convertit en dictionnaire puis en objet Python.
 | |
| Cet objet est en lecture uniquement, on modifie à la main les paramètres d'un bus.
 | |
| 
 | |
| Le champ ``bus`` est fourni.
 | |
| 
 | |
| WEISurveyAlgorithm
 | |
| """"""""""""""""""
 | |
| 
 | |
| Une classe héritant de ``wei.forms.surveys.base.WEISurveyAlgorithm``, qui contient 3 fonctions :
 | |
| 
 | |
| * ``get_survey_class(cls)``, qui renvoie la classe du ``WEISurvey`` associée à l'algorithme.
 | |
| * ``get_bus_information_class(cls)`` qui renvoie la classe du ``WEIBusInformation`` décrivant les informations d'
 | |
| * ``run_algorithm(self)``, la fonction importante. Cette fonction n'est supposée n'être exécutée qu'une seule fois
 | |
|   par WEI, et a pour cahier des charges de prendre chaque sondage d'un 1A et d'appeler la fonction ``WEISurvey.select_bus(bus)``,
 | |
|   en décidant convenablement de quel bus le membre doit prendre. C'est bien sûr la fonction la plus complexe à mettre en oeuvre.
 | |
|   Tout est permis tant qu'à la fin tout le monde a bien son bus.
 | |
| 
 | |
| Trois fonctions sont implémentées nativement :
 | |
| 
 | |
| * ``get_registrations(cls)``, renvoie un ``QuerySSet`` vers l'ensemble des inscriptions au WEI concerné des 1A.
 | |
| * ``get_buses(cls)``, renvoie l'ensemble des bus du WEI concerné.
 | |
| * ``get_bus_information(cls, bus)``, renvoie l'objet ``WEIBusInformation`` instancié avec les informations fournies
 | |
|   par le champ ``information_json`` de ``bus``.
 | |
| 
 | |
| 
 | |
| La dernière chose à faire est dans le fichier ``apps/wei/forms/surveys/__init__.py``, où la classe ``CurrentSurvey``
 | |
| est à mettre à jour. Il n'y a rien d'autre à changer, tout le reste est normalement géré pour qu'il n'y ait pas nécessité
 | |
| d'y toucher.
 | |
| 
 | |
| Le lancement de l'algorithme se fait en ligne de commande, via la commande ``python manage.py wei_algorithm``. Elle a
 | |
| pour unique effet d'appeler la fonction ``run_algorithm`` décrite plus tôt. Une fois cela fait, vous aurez noté qu'il
 | |
| n'a pas été évoqué d'adhésion. L'adhésion est ensuite manuelle, l'algorithme ne fournit qu'une suggestion.
 | |
| 
 | |
| Cette structure, complexe mais raisonnable, permet de gérer plus ou moins proprement la répartition des 1A,
 | |
| en limitant très fortement le hard code. Ami⋅e nouvelleau développeur⋅se, merci de bien penser à la propreté du code :)
 | |
| En particulier, on évitera de mentionner dans le code le nom des bus, et profiter du champ ``information_json``
 | |
| présent dans le modèle ``Bus``.
 | |
| 
 | |
| Valider les inscriptions
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| Cette partie est moins technique.
 | |
| 
 | |
| Une fois la pré-inscription faite, elle doit être validée par le BDE, afin de procéder au paiement. Læ GC WEI a accès à
 | |
| la liste des inscriptions non validées, soit sur la page de détails du WEI, soit sur un tableau plus large avec filtre.
 | |
| Une inscription non validée peut soit être validée, soit supprimée (la suppression est irréversible).
 | |
| 
 | |
| Lorsque læ GC WEI veut valider une inscription, iel a accès au récapitulatif de l'inscription ainsi qu'aux informations
 | |
| personnelles de l'utilisateur⋅rice. Il lui est proposé de les modifier si besoin (du moins les informations liées au WEI,
 | |
| pas les informations personnelles). Iel a enfin accès aux résultats du sondage et la sortie de l'algorithme s'il s'agit
 | |
| d'un⋅e 1A, aux préférences d'un⋅e 2A+. Avant de valider, læ GC WEI doit sélectionner un bus, éventuellement une équipe
 | |
| et un rôle. Si c'est un⋅e 1A et que l'algorithme a tourné, ou si c'est un⋅e 2A+ qui n'a fait qu'un seul choix de bus,
 | |
| d'équipe, de rôles, les champs sont automatiquement pré-remplis.
 | |
| 
 | |
| Quelques restrictions cependant :
 | |
| 
 | |
| * Si c'est un⋅e 2A+, le chèque de caution doit être déclaré déposé
 | |
| * Si l'inscription se fait via la Société générale, un message expliquant la situation apparaît : la transaction de
 | |
|   paiement sera créée mais invalidée, les trésorièr⋅es devront confirmer plus tard sur leur interface que le compte
 | |
|   à la Société générale a bien été créé avant de valider la transaction (voir `Trésorerie <treasury>`_ section
 | |
|   Crédit de la Société générale).
 | |
| * Dans le cas contraire, l'utilisateur⋅rice doit avoir le solde nécessaire sur sa note avant de pouvoir adhérer.
 | |
| * L'utilisateur⋅rice doit enfin être membre du club Kfet. Un lien est présent pour le faire adhérer ou réadhérer selon le cas.
 | |
| 
 | |
| Si tout est bon, læ GC WEI peut valider. L'utilisateur⋅rice a bien payé son WEI, et son interface est un peu plus grande.
 | |
| Iel peut toujours changer ses paramètres au besoin. Un⋅e 1A ne voit rien de plus avant la fin du WEI.
 | |
| 
 | |
| Un⋅e adhérent⋅e WEI non 1A a accès à la liste des bus, des équipes et de leur descriptions. Les chef⋅fes de bus peuvent gérer
 | |
| les bus et leurs équipes. Les chef⋅fes d'équipe peuvent gérer leurs équipes. Cela inclut avoir accès à la liste des membres
 | |
| de ce bus / de cette équipe.
 | |
| 
 | |
| Un export au format PDF de la liste des membres *visibles* est disponible pour chacun⋅e.
 | |
| 
 | |
| Bon WEI à toustes !
 |