1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-08-28 23:56:42 +02:00

Merge branch 'main' into 'family'

# Conflicts:
#   locale/fr/LC_MESSAGES/django.po
This commit is contained in:
ehouarn
2025-08-28 11:23:22 +02:00
6 changed files with 224 additions and 188 deletions

View File

@@ -10,145 +10,183 @@ from django import forms
from django.db import transaction
from django.db.models import Q
from django.utils.translation import gettext_lazy as _
from django.utils.safestring import mark_safe
from .base import WEISurvey, WEISurveyInformation, WEISurveyAlgorithm, WEIBusInformation
from ...models import WEIMembership, Bus
WORDS = {
'list': [
'13 organisé', '3ième mi temps', 'Années 2000', 'Apéro', 'BBQ', 'BP', 'Beauf', 'Binge drinking', 'Bon enfant',
'Cartouche', 'Catacombes', 'Chansons paillardes', 'Chansons populaires', 'Chanteur', 'Chartreuse', 'Chill',
'Core', 'DJ', 'Dancefloor', 'Danse', 'David Guetta', 'Disco', 'Eau de vie', 'Électro', 'Escalade', 'Familial',
'Fanfare', 'Fracassage', 'Féria', 'Hard rock', 'Hoeggarden', 'House', 'Huit-six', 'IPA', 'Inclusif', 'Inferno',
'Introverti', 'Jager bomb', 'Jazz', 'Jeux d\'alcool', 'Jeux de rôles', 'Jeux vidéo', 'Jul', 'Jus de fruit',
'Karaoké', 'LGBTQI+', 'Lady Gaga', 'Loup garou', 'Morning beer', 'Métal', 'Nuit blanche', 'Ovalie', 'Psychedelic',
'Pétanque', 'Rave', 'Reggae', 'Rhum', 'Ricard', 'Rock', 'Rosé', 'Rétro', 'Séducteur', 'Techno', 'Thérapie taxi',
'Théâtre', 'Trap', 'Turn up', 'Underground', 'Volley', 'Wati B', 'Zinédine Zidane',
'Fiesta', 'Graillance', 'Move it move it', 'Calme', 'Nert et geek', 'Jeux de rôles et danse rock',
'Strass et paillettes', 'Spectaculaire', 'Splendide', 'Flow inégalable', 'Rap', 'Battles légendaires',
'Techno', 'Alcool', 'Kiffeur·euse', 'Rugby', 'Médiéval', 'Festif',
'Stylé', 'Chipie', 'Rétro', 'Vache', 'Farfadet', 'Fanfare',
],
'questions': {
'Question 1': [
'Description 1',
"alcool": [
"""Sur une échelle allant de 0 (= 0 alcool ou très peu) à 5 (= la fontaine de jouvence alcoolique),
quel niveau de consommation dalcool souhaiterais-tu ?""",
{
3: 'Réponse 1 Madagas[car]',
4: 'Réponse 1 Y2[KAR]',
2: 'Réponse 1 Tcherno[bus]',
5: 'Réponse 1 [Kar]tier',
1: 'Réponse 1 [Car]cassonne',
6: 'Réponse 1 O[car]ina',
7: 'Réponse 1 Show[bus]',
8: 'Réponse 1 [Car]ioca'
42: "",
47: "",
48: "",
45: "",
44: "",
46: "",
43: "",
49: ""
}
],
'Question 2': [
'Description 2',
"voie_post_bac": [
"""Si la DA du bus de ton choix correspondait à une voie post-bac, laquelle serait-elle ?""",
{
3: 'Réponse 2 Madagas[car]',
4: 'Réponse 2 Y2[KAR]',
2: 'Réponse 2 Tcherno[bus]',
5: 'Réponse 2 [Kar]tier',
1: 'Réponse 2 [Car]cassonne',
6: 'Réponse 2 O[car]ina',
7: 'Réponse 2 Show[bus]',
8: 'Réponse 2 [Car]ioca'
42: "",
47: "",
48: "",
45: "",
44: "",
46: "",
43: "",
49: ""
}
],
'Question 3': [
'Description 3',
"boite": [
"""Tu es seul·e sur une île déserte et devant toi il y a une sombre boîte de taille raisonnable.
Quy a-t-il à lintérieur ?""",
{
3: 'Réponse 3 Madagas[car]',
4: 'Réponse 3 Y2[KAR]',
2: 'Réponse 3 Tcherno[bus]',
5: 'Réponse 3 [Kar]tier',
1: 'Réponse 3 [Car]cassonne',
6: 'Réponse 3 O[car]ina',
7: 'Réponse 3 Show[bus]',
8: 'Réponse 3 [Car]ioca'
42: "",
47: "",
48: "",
45: "",
44: "",
46: "",
43: "",
49: ""
}
],
'Question 4': [
'Description 4',
"tardif": [
"""Il est 00h, tu as passé la journée à la plage avec tes copains et iels te proposent de prolonger parce
quaprès tout, il ny a plus personne sur la plage à cette heure-ci. Tu nhabites pas loin mais tenchaînes
demain avec une journée similaire avec un autre groupe damis parce que tes trop #busy. Que fais-tu ?""",
{
3: 'Réponse 4 Madagas[car]',
4: 'Réponse 4 Y2[KAR]',
2: 'Réponse 4 Tcherno[bus]',
5: 'Réponse 4 [Kar]tier',
1: 'Réponse 4 [Car]cassonne',
6: 'Réponse 4 O[car]ina',
7: 'Réponse 4 Show[bus]',
8: 'Réponse 4 [Car]ioca'
42: "",
47: "",
48: "",
45: "",
44: "",
46: "",
43: "",
49: ""
}
],
'Question 5': [
'Description 5',
"cohesion": [
"""Cest la rentrée de Seconde et tu découvres ta classe, tes camarades et ta prof principale!!!
qui vous propose une activité de cohésion. Laquelle est-elle ?""",
{
3: 'Réponse 5 Madagas[car]',
4: 'Réponse 5 Y2[KAR]',
2: 'Réponse 5 Tcherno[bus]',
5: 'Réponse 5 [Kar]tier',
1: 'Réponse 5 [Car]cassonne',
6: 'Réponse 5 O[car]ina',
7: 'Réponse 5 Show[bus]',
8: 'Réponse 5 [Car]ioca'
42: "",
47: "",
48: "",
45: "",
44: "",
46: "",
43: "",
49: ""
}
],
'Question 6': [
'Description 6',
"artiste": [
"""Cest lété et la saison des festivals a commencé. Tu regardes la programmation du festival
pas loin de chez toi et tu découvres avec joie la présence dun·e artiste. De qui sagit-il ?""",
{
3: 'Réponse 6 Madagas[car]',
4: 'Réponse 6 Y2[KAR]',
2: 'Réponse 6 Tcherno[bus]',
5: 'Réponse 6 [Kar]tier',
1: 'Réponse 6 [Car]cassonne',
6: 'Réponse 6 O[car]ina',
7: 'Réponse 6 Show[bus]',
8: 'Réponse 6 [Car]ioca'
42: "",
47: "",
48: "",
45: "",
44: "",
46: "",
43: "",
49: ""
}
],
'Question 7': [
'Description 7',
"annonce_noel": [
"""Cest Noël et tu revois toute ta famille, oncles, tantes, cousin·e·s, grands-parents, la totale.
Dun coup, tu te lèves, tapotes de manière pompeuse sur ton verre avec un de tes couverts.
Quannonces-tu ?""",
{
3: 'Réponse 7 Madagas[car]',
4: 'Réponse 7 Y2[KAR]',
2: 'Réponse 7 Tcherno[bus]',
5: 'Réponse 7 [Kar]tier',
1: 'Réponse 7 [Car]cassonne',
6: 'Réponse 7 O[car]ina',
7: 'Réponse 7 Show[bus]',
8: 'Réponse 7 [Car]ioca'
42: "",
47: "",
48: "",
45: "",
44: "",
46: "",
43: "",
49: ""
}
],
'Question 8': [
'Description 8',
"vacances": [
"""Les vacances sont là et taimerais bien partir quelque part, mais où ?""",
{
3: 'Réponse 8 Madagas[car]',
4: 'Réponse 8 Y2[KAR]',
2: 'Réponse 8 Tcherno[bus]',
5: 'Réponse 8 [Kar]tier',
1: 'Réponse 8 [Car]cassonne',
6: 'Réponse 8 O[car]ina',
7: 'Réponse 8 Show[bus]',
8: 'Réponse 8 [Car]ioca'
42: "",
47: "",
48: "",
45: "",
44: "",
46: "",
43: "",
49: ""
}
],
'Question 9': [
'Description 9',
"loisir": [
"""Tas fini ta journée de cours et tu tapprêtes à profiter dune activité/hobby/loisir de ton choix.
Laquelle est-ce ?""",
{
3: 'Réponse 9 Madagas[car]',
4: 'Réponse 9 Y2[KAR]',
2: 'Réponse 9 Tcherno[bus]',
5: 'Réponse 9 [Kar]tier',
1: 'Réponse 9 [Car]cassonne',
6: 'Réponse 9 O[car]ina',
7: 'Réponse 9 Show[bus]',
8: 'Réponse 9 [Car]ioca'
42: "",
47: "",
48: "",
45: "",
44: "",
46: "",
43: "",
49: ""
}
],
"plan": [
"""Tu reçois un message sur la conversation de groupe que tu partages avec tes potes :
vous êtes chaud·e·s pour vous retrouver. Quel plan tattire le plus ?""",
{
42: "",
47: "",
48: "",
45: "",
44: "",
46: "",
43: "",
49: ""
}
]
}
}
IMAGES = {
}
NB_WORDS = 5
class OptionalImageRadioSelect(forms.RadioSelect):
def __init__(self, images=None, *args, **kwargs):
self.images = images or {}
super().__init__(*args, **kwargs)
def create_option(self, name, value, label, selected, index, subindex=None, attrs=None):
option = super().create_option(name, value, label, selected, index, subindex=subindex, attrs=attrs)
img_url = self.images.get(value)
if img_url:
option['label'] = mark_safe(f'{label} <img src="{img_url}" style="height:32px;vertical-align:middle;">')
else:
option['label'] = label
return option
class WEISurveyForm2025(forms.Form):
"""
Survey form for the year 2025.
@@ -170,7 +208,7 @@ class WEISurveyForm2025(forms.Form):
if information.step == 0:
self.fields["words"] = forms.MultipleChoiceField(
label=_(f"Choose {NB_WORDS} words:"),
label=_(f"Select {NB_WORDS} words that describe the WEI experience you want to have."),
choices=[(w, w) for w in WORDS['list']],
widget=forms.CheckboxSelectMultiple(),
required=True,
@@ -178,23 +216,7 @@ class WEISurveyForm2025(forms.Form):
if self.is_valid():
return
buses = WEISurveyAlgorithm2025.get_buses()
informations = {bus: WEIBusInformation2025(bus) for bus in buses}
scores = sum((list(informations[bus].scores.values()) for bus in buses), [])
if scores:
average_score = sum(scores) / len(scores)
else:
average_score = 0
preferred_words = {
bus: [word for word in WORDS['list'] if informations[bus].scores[word] >= average_score]
for bus in buses
}
all_preferred_words = set()
for bus_words in preferred_words.values():
all_preferred_words.update(bus_words)
all_preferred_words = list(all_preferred_words)
all_preferred_words = WORDS['list']
rng.shuffle(all_preferred_words)
self.fields["words"].choices = [(w, w) for w in all_preferred_words]
else:
@@ -202,12 +224,15 @@ class WEISurveyForm2025(forms.Form):
idx = information.step - 1
if idx < len(questions):
q, (desc, answers) = questions[idx]
choices = [(k, v) for k, v in answers.items()]
rng.shuffle(choices)
if q == 'alcool':
choices = [(i / 2, str(i / 2)) for i in range(11)]
else:
choices = [(k, v) for k, v in answers.items()]
rng.shuffle(choices)
self.fields[q] = forms.ChoiceField(
label=desc,
choices=choices,
widget=forms.RadioSelect,
widget=OptionalImageRadioSelect(images=IMAGES.get(q, {})),
required=True,
)
@@ -226,8 +251,6 @@ class WEIBusInformation2025(WEIBusInformation):
def __init__(self, bus):
self.scores = {}
for word in WORDS['list']:
self.scores[word] = 0
super().__init__(bus)
@@ -235,7 +258,9 @@ class BusInformationForm2025(forms.ModelForm):
class Meta:
model = Bus
fields = ['information_json']
widgets = {}
widgets = {
'information_json': forms.HiddenInput(),
}
def __init__(self, *args, words=None, **kwargs):
super().__init__(*args, **kwargs)
@@ -257,7 +282,7 @@ class BusInformationForm2025(forms.ModelForm):
label=word,
choices=choices,
coerce=int,
initial=initial_scores.get(word, 0),
initial=initial_scores.get(word, 0) if word in initial_scores else None,
required=True,
widget=forms.RadioSelect,
help_text=_("Rate between 0 and 5."),
@@ -285,7 +310,7 @@ class WEISurveyInformation2025(WEISurveyInformation):
step = 0
def __init__(self, registration):
for i in range(1, 5):
for i in range(1, NB_WORDS + 1):
setattr(self, "word" + str(i), None)
for q in WORDS['questions']:
setattr(self, q, None)
@@ -297,7 +322,7 @@ class WEISurveyInformation2025(WEISurveyInformation):
"""
self.step = 0
self.seed = 0
for i in range(1, 5):
for i in range(1, NB_WORDS + 1):
setattr(self, f"word{i}", None)
for q in WORDS['questions']:
setattr(self, q, None)
@@ -371,8 +396,9 @@ class WEISurvey2025(WEISurvey):
"""
if not self.is_complete():
raise ValueError("Survey is not ended, can't calculate score")
# Score is the given score by the bus subtracted to the mid-score of the buses.
s = sum(1 for q in WORDS['questions'] if getattr(self.information, q) == bus.pk)
s = sum(1 for q in WORDS['questions'] if q != 'alcool' and getattr(self.information, q) == bus.pk)
if 'alcool' in WORDS['questions'] and bus.pk in WORDS['questions']['alcool'][1] and hasattr(self.information, 'alcool'):
s -= abs(float(self.information.alcool) - float(WORDS['questions']['alcool'][1][bus.pk]))
return s
@lru_cache()
@@ -396,7 +422,7 @@ class WEISurvey2025(WEISurvey):
@lru_cache()
def ordered_buses(self):
"""
Force the choice of bus to be in the 3 preferred buses according to the words
Order the buses by the score_questions of the survey.
"""
values = list(self.scores_per_bus().items())
values.sort(key=lambda item: -item[1][0])
@@ -513,7 +539,7 @@ class WEISurveyAlgorithm2025(WEISurveyAlgorithm):
for survey2 in surveys:
if not survey2.information.valid or survey2.information.get_selected_bus() != bus:
continue
score2 = survey2.score_questions(bus)
score2 = survey2.score_words(bus)
if current_scores[1] <= score2: # Ignore better students
continue
if least_preferred_survey is None or score2 < least_score:

View File

@@ -22,8 +22,8 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% endif %}
<a class="btn btn-primary btn-sm my-1" href="{% url 'wei:update_bus' pk=object.pk %}"
data-turbolinks="false">{% trans "Edit" %}</a>
<a class="btn btn-primary btn-sm my-1" href="{% url 'wei:update_bus_info' pk=object.pk %}"
data-turbolinks="false">{% trans "Edit information" %}</a>
<a class="btn btn-primary btn-sm my-1" href="{% url 'wei:update_bus_info' pk=object.pk %}"
data-turbolinks="false">{% trans "Edit information for survey" %}</a>
<a class="btn btn-primary btn-sm my-1" href="{% url 'wei:add_team' pk=object.pk %}"
data-turbolinks="false">{% trans "Add team" %}</a>
</div>

View File

@@ -31,15 +31,22 @@ SPDX-License-Identifier: GPL-3.0-or-later
<a class="btn btn-success" href="{% url "wei:wei_register_1A_myself" wei_pk=club.pk %}" data-turbolinks="false">
{% trans "Register to the WEI! 1A" %}
</a>
{% endif %}
{% else %}
<a class="btn btn-success" href="{% url "wei:wei_register_2A_myself" wei_pk=club.pk %}" data-turbolinks="false">
{% trans "Register to the WEI! 2A+" %}</a>
{% trans "Register to the WEI! 2A+" %}
</a>
{% endif %}
{% else %}
<a class="btn btn-warning" href="{% url "wei:wei_update_registration" pk=my_registration.pk %}"
data-turbolinks="false">
{% trans "Update my registration" %}
</a>
{% if not not_first_year %}
{% if not survey_complete %}
<a class="btn btn-warning" href="{% url "wei:wei_survey" pk=my_registration.pk %}" data-turbolinks="false">
{% trans "Continue survey" %}
</a>
{% endif %}
<a class="btn btn-warning" href="{% url "wei:wei_survey" pk=my_registration.pk %}?reset=true" data-turbolinks="false">
{% trans "Restart survey" %}
</a>

View File

@@ -105,8 +105,6 @@ class TestWEIAlgorithm(TestCase):
survey = WEISurvey2025(r)
chosen_bus = survey.information.get_selected_bus()
buses = survey.ordered_buses()
'''print(buses)
print(chosen_bus)'''
self.assertIn(chosen_bus, [x[0] for x in buses])
score_questions, score_words = next(scores for bus, scores in buses if bus == chosen_bus)
max_score_questions = max(buses[i][1][0] for i in range(len(buses)))

View File

@@ -166,6 +166,7 @@ class WEIDetailView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMixin, D
my_registration = WEIRegistration.objects.filter(wei=club, user=self.request.user)
if my_registration.exists():
my_registration = my_registration.get()
context["survey_complete"] = CurrentSurvey(my_registration).is_complete()
else:
my_registration = None
context["my_registration"] = my_registration
@@ -1231,7 +1232,6 @@ class WEIUpdateMembershipView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateVi
return form
def get_success_url(self):
print("get_success_url")
return reverse_lazy("wei:wei_detail", kwargs={"pk": self.object.registration.wei.pk})

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-08-13 23:48+0200\n"
"POT-Creation-Date: 2025-08-20 23:34+0200\n"
"PO-Revision-Date: 2022-04-11 22:05+0200\n"
"Last-Translator: ehouarn <ehouarn@crans.org>\n"
"Language-Team: French <http://translate.ynerant.fr/projects/nk20/nk20/fr/>\n"
@@ -1753,7 +1753,7 @@ msgstr "Membres du club"
#: apps/member/templates/member/club_detail.html:40
#: apps/member/templates/member/profile_detail.html:32
#: apps/wei/templates/wei/weiclub_detail.html:98
#: apps/wei/templates/wei/weiclub_detail.html:105
msgid "Transaction history"
msgstr "Historique des transactions"
@@ -2295,8 +2295,8 @@ msgstr ""
"mode de paiement et un⋅e utilisateur⋅rice ou un club"
#: apps/note/models/transactions.py:357 apps/note/models/transactions.py:360
#: apps/note/models/transactions.py:363 apps/wei/views.py:1134
#: apps/wei/views.py:1138
#: apps/note/models/transactions.py:363 apps/wei/views.py:1135
#: apps/wei/views.py:1139
msgid "This field is required."
msgstr "Ce champ est requis."
@@ -3364,17 +3364,18 @@ msgstr "Cette équipe n'appartient pas à ce bus."
msgid "Choose a word:"
msgstr "Choisissez un mot :"
#: apps/wei/forms/surveys/wei2025.py:173
#: apps/wei/forms/surveys/wei2025.py:211
#, python-brace-format
msgid "Choose {NB_WORDS} words:"
msgstr "Choisissez {NB_WORDS} mots :"
msgid ""
"Select {NB_WORDS} words that describe the WEI experience you want to have."
msgstr ""
#: apps/wei/forms/surveys/wei2025.py:217
#: apps/wei/forms/surveys/wei2025.py:242
#, python-brace-format
msgid "Please choose exactly {NB_WORDS} words"
msgstr ""
#: apps/wei/forms/surveys/wei2025.py:263
#: apps/wei/forms/surveys/wei2025.py:288
msgid "Rate between 0 and 5."
msgstr "Note entre 0 et 5."
@@ -3409,7 +3410,7 @@ msgid "Information about the survey for new members, encoded in JSON"
msgstr ""
"Informations sur le sondage pour les nouveaux membres, encodées en JSON"
#: apps/wei/models.py:108 apps/wei/templates/wei/weiclub_detail.html:56
#: apps/wei/models.py:108 apps/wei/templates/wei/weiclub_detail.html:63
msgid "Buses"
msgstr "Bus"
@@ -3647,11 +3648,11 @@ msgstr "Prix du WEI (étudiant⋅es)"
msgid "WEI list"
msgstr "Liste des WEI"
#: apps/wei/templates/wei/base.html:79 apps/wei/views.py:584
#: apps/wei/templates/wei/base.html:79 apps/wei/views.py:585
msgid "Register 1A"
msgstr "Inscrire un⋅e 1A"
#: apps/wei/templates/wei/base.html:83 apps/wei/views.py:680
#: apps/wei/templates/wei/base.html:83 apps/wei/views.py:681
msgid "Register 2A+"
msgstr "Inscrire un⋅e 2A+"
@@ -3668,8 +3669,8 @@ msgid "View club"
msgstr "Voir le club"
#: apps/wei/templates/wei/bus_detail.html:26
msgid "Edit information"
msgstr "Modifier les informations"
msgid "Edit information for survey"
msgstr "Modifier les informations du sondage"
#: apps/wei/templates/wei/bus_detail.html:28
#: apps/wei/templates/wei/busteam_detail.html:24
@@ -3718,23 +3719,27 @@ msgstr "M'inscrire au WEI ! 1A"
msgid "Register to the WEI! 2A+"
msgstr "M'inscrire au WEI ! 2A+"
#: apps/wei/templates/wei/weiclub_detail.html:40
#: apps/wei/templates/wei/weiclub_detail.html:42
msgid "Update my registration"
msgstr "Modifier mon inscription"
#: apps/wei/templates/wei/weiclub_detail.html:44
#: apps/wei/templates/wei/weiclub_detail.html:47
msgid "Continue survey"
msgstr "Continuer le questionnaire"
#: apps/wei/templates/wei/weiclub_detail.html:51
msgid "Restart survey"
msgstr "Recommencer le questionnaire"
#: apps/wei/templates/wei/weiclub_detail.html:68
#: apps/wei/templates/wei/weiclub_detail.html:75
msgid "Members of the WEI"
msgstr "Membres du WEI"
#: apps/wei/templates/wei/weiclub_detail.html:80
#: apps/wei/templates/wei/weiclub_detail.html:87
msgid "Unvalidated registrations"
msgstr "Inscriptions non validées"
#: apps/wei/templates/wei/weiclub_detail.html:90
#: apps/wei/templates/wei/weiclub_detail.html:97
msgid "Attribute buses"
msgstr "Répartition dans les bus"
@@ -3770,7 +3775,7 @@ msgstr "Informations brutes du sondage"
msgid "The algorithm didn't run."
msgstr "L'algorithme n'a pas été exécuté."
#: apps/wei/templates/wei/weimembership_form.html:98 apps/wei/views.py:1028
#: apps/wei/templates/wei/weimembership_form.html:98 apps/wei/views.py:1029
msgid "Deposit check given"
msgstr "Chèque de caution donné"
@@ -3896,63 +3901,63 @@ msgstr "Chercher un WEI"
msgid "WEI Detail"
msgstr "Détails du WEI"
#: apps/wei/views.py:229
#: apps/wei/views.py:230
msgid "View members of the WEI"
msgstr "Voir les membres du WEI"
#: apps/wei/views.py:262
#: apps/wei/views.py:263
msgid "Find WEI Membership"
msgstr "Trouver une adhésion au WEI"
#: apps/wei/views.py:272
#: apps/wei/views.py:273
msgid "View registrations to the WEI"
msgstr "Voir les inscriptions au WEI"
#: apps/wei/views.py:318
#: apps/wei/views.py:319
msgid "Find WEI Registration"
msgstr "Trouver une inscription au WEI"
#: apps/wei/views.py:329
#: apps/wei/views.py:330
msgid "Update the WEI"
msgstr "Modifier le WEI"
#: apps/wei/views.py:350
#: apps/wei/views.py:351
msgid "Create new bus"
msgstr "Ajouter un nouveau bus"
#: apps/wei/views.py:388
#: apps/wei/views.py:389
msgid "Update bus"
msgstr "Modifier le bus"
#: apps/wei/views.py:420
#: apps/wei/views.py:421
msgid "Manage bus"
msgstr "Gérer le bus"
#: apps/wei/views.py:447
#: apps/wei/views.py:448
msgid "Create new team"
msgstr "Créer une nouvelle équipe"
#: apps/wei/views.py:491
#: apps/wei/views.py:492
msgid "Update team"
msgstr "Modifier l'équipe"
#: apps/wei/views.py:526
#: apps/wei/views.py:527
msgid "Manage WEI team"
msgstr "Gérer l'équipe WEI"
#: apps/wei/views.py:548
#: apps/wei/views.py:549
msgid "Register first year student to the WEI"
msgstr "Inscrire un⋅e 1A au WEI"
#: apps/wei/views.py:605 apps/wei/views.py:698
#: apps/wei/views.py:606 apps/wei/views.py:699
msgid "Check if you will open a Société Générale account"
msgstr "Cochez cette case si vous ouvrez un compte à la Société Générale."
#: apps/wei/views.py:616 apps/wei/views.py:728
#: apps/wei/views.py:617 apps/wei/views.py:729
msgid "This user is already registered to this WEI."
msgstr "Cette personne est déjà inscrite au WEI."
#: apps/wei/views.py:621
#: apps/wei/views.py:622
msgid ""
"This user can't be in her/his first year since he/she has already "
"participated to a WEI."
@@ -3960,67 +3965,67 @@ msgstr ""
"Cet⋅te utilisateur⋅rice ne peut pas être en première année puisqu'iel a déjà "
"participé à un WEI."
#: apps/wei/views.py:644
#: apps/wei/views.py:645
msgid "Register old student to the WEI"
msgstr "Inscrire un⋅e 2A+ au WEI"
#: apps/wei/views.py:702 apps/wei/views.py:825
#: apps/wei/views.py:703 apps/wei/views.py:826
msgid "You already opened an account in the Société générale."
msgstr "Vous avez déjà ouvert un compte auprès de la société générale."
#: apps/wei/views.py:715 apps/wei/views.py:821
#: apps/wei/views.py:716 apps/wei/views.py:822
msgid "Choose how you want to pay the deposit"
msgstr "Choisissez comment payer la caution"
#: apps/wei/views.py:767
#: apps/wei/views.py:768
msgid "Update WEI Registration"
msgstr "Modifier l'inscription WEI"
#: apps/wei/views.py:811
#: apps/wei/views.py:812
msgid "Tick if the deposit check has been given"
msgstr "Cochez si le chèque de caution a été donné"
#: apps/wei/views.py:850
#: apps/wei/views.py:851
msgid "No membership found for this registration"
msgstr "Pas d'adhésion trouvée pour cette inscription"
#: apps/wei/views.py:859
#: apps/wei/views.py:860
msgid "You don't have the permission to update memberships"
msgstr "Vous n'avez pas la permission de modifier une inscription"
#: apps/wei/views.py:865
#: apps/wei/views.py:866
#, python-format
msgid "You don't have the permission to update the field %(field)s"
msgstr "Vous n'avez pas la permission de modifier le champ %(field)s"
#: apps/wei/views.py:906
#: apps/wei/views.py:907
msgid "Delete WEI registration"
msgstr "Supprimer l'inscription WEI"
#: apps/wei/views.py:917
#: apps/wei/views.py:918
msgid "You don't have the right to delete this WEI registration."
msgstr "Vous n'avez pas la permission de supprimer cette inscription au WEI."
#: apps/wei/views.py:935
#: apps/wei/views.py:936
msgid "Validate WEI registration"
msgstr "Valider l'inscription WEI"
#: apps/wei/views.py:1029
#: apps/wei/views.py:1030
msgid "Only treasurers can validate this field"
msgstr "Seul·e·s les trésorier·ère·s peuvent valider ce champ"
#: apps/wei/views.py:1035
#: apps/wei/views.py:1036
msgid "Create deposit transaction"
msgstr "Créer une transaction de caution"
#: apps/wei/views.py:1036
#: apps/wei/views.py:1037
#, python-format
msgid ""
"A transaction of %(amount).2f€ will be created from the user's Note account"
msgstr ""
"Un transaction de %(amount).2f€ va être créée depuis la note de l'utilisateur"
#: apps/wei/views.py:1124
#: apps/wei/views.py:1125
#, python-format
msgid ""
"This user doesn't have enough money to join this club and pay the deposit. "
@@ -4030,12 +4035,12 @@ msgstr ""
"payer la caution. Solde actuel : %(balance)d€, crédit : %(credit)d€, "
"requis : %(needed)d€"
#: apps/wei/views.py:1177
#: apps/wei/views.py:1178
#, python-format
msgid "Deposit %(name)s"
msgstr "Caution %(name)s"
#: apps/wei/views.py:1202
#: apps/wei/views.py:1203
msgid "Update WEI Membership"
msgstr "Modifier une adhésion au WEI"