1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-07-20 16:09:12 +02:00

Compare commits

...

18 Commits

Author SHA1 Message Date
2755a5f7ab Minor fail 2025-07-19 17:10:25 +02:00
9ab4df94e6 Minor fixes 2025-07-19 16:55:07 +02:00
edb6abfff5 Add fee field to WEIRegistration to be able to sort on validation status 2025-07-19 16:24:25 +02:00
b1fa1c2cdd Merge branch 'main' into 'wei'
# Conflicts:
#   locale/fr/LC_MESSAGES/django.po
2025-07-15 19:06:58 +02:00
a273dc3eef Translations 2025-07-15 18:23:40 +02:00
852651d126 Rename 'caution' fields into 'deposit' 2025-07-15 18:10:28 +02:00
3af35dc0fc Soge Credit changed 2025-07-15 17:43:21 +02:00
4380414c6b Minor fixes 2025-07-13 18:29:43 +02:00
a94c937c6a Merge branch 'food_traceability' into 'main'
Bugs fixed again (lost in beta)

See merge request bde/nk20!329
2025-07-13 17:12:57 +02:00
0a261e6ad5 Bugs fixed again (lost in beta) 2025-07-13 16:38:39 +02:00
ab9329f62b Merge branch 'beta' into 'main'
translation

See merge request bde/nk20!328
2025-07-12 14:06:27 +02:00
b97b79e2ea translation 2025-07-12 14:05:53 +02:00
483ea26f02 Merge branch 'beta' into 'main'
Django 5.2 and other upgrade

Closes #133

See merge request bde/nk20!327
2025-07-12 13:23:31 +02:00
695ce63e08 Merge branch 'food_traceability' into 'beta'
Easier access to food details

See merge request bde/nk20!326
2025-07-11 17:15:50 +02:00
79f50c27f1 Merge branch 'beta' into 'food_traceability'
# Conflicts:
#   locale/fr/LC_MESSAGES/django.po
2025-07-11 17:00:45 +02:00
5989721bc9 Easier access to food details 2025-07-11 16:35:49 +02:00
bcc3e7cc53 Merge branch 'food_traceability' into beta 2025-07-11 12:26:55 +02:00
608804db30 Bugs fixed 2025-07-10 20:05:27 +02:00
26 changed files with 1326 additions and 2128 deletions

View File

@ -145,7 +145,7 @@ class AddIngredientForms(forms.ModelForm):
polymorphic_ctype__model="transformedfood", polymorphic_ctype__model="transformedfood",
is_ready=False, is_ready=False,
end_of_life='', end_of_life='',
).filter(PermissionBackend.filter_queryset(get_current_request(), TransformedFood, "change")).exclude(pk=pk) ).filter(PermissionBackend.filter_queryset(get_current_request(), Food, "change")).exclude(pk=pk)
class Meta: class Meta:
model = TransformedFood model = TransformedFood

View File

@ -12,18 +12,21 @@ SPDX-License-Identifier: GPL-3.0-or-later
</h3> </h3>
<div class="card-body"> <div class="card-body">
<ul> <ul>
{% if QR_code %}
<li> {{QR_code}} </li>
{% endif %}
{% for field, value in fields %} {% for field, value in fields %}
<li> {{ field }} : {{ value }}</li> <li> {{ field }} : {{ value }}</li>
{% endfor %} {% endfor %}
{% if meals %} {% if meals %}
<li> {% trans "Contained in" %} : <li> {% trans "Contained in" %} :
{% for meal in meals %} {% for meal in meals %}
<a href="{% url "food:transformedfood_view" pk=meal.pk %}">{{ meal.name }}</a>{% if not forloop.last %},{% endif %} <a href="{% url "food:transformedfood_view" pk=meal.pk %}">{{ meal.name }}</a>{% if not forloop.last %},{% endif %}
{% endfor %} {% endfor %}
</li> </li>
{% endif %} {% endif %}
{% if foods %} {% if foods %}
<li> {% trans "Contain" %} : <li> {% trans "Contain" %} :
{% for food in foods %} {% for food in foods %}
<a href="{% url "food:food_view" pk=food.pk %}">{{ food.name }}</a>{% if not forloop.last %},{% endif %} <a href="{% url "food:food_view" pk=food.pk %}">{{ food.name }}</a>{% if not forloop.last %},{% endif %}
{% endfor %} {% endfor %}
@ -31,23 +34,23 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% endif %} {% endif %}
</ul> </ul>
{% if update %} {% if update %}
<a class="btn btn-sm btn-secondary" href="{% url "food:food_update" pk=food.pk %}"> <a class="btn btn-sm btn-secondary" href="{% url "food:food_update" pk=food.pk %}">
{% trans "Update" %} {% trans "Update" %}
</a> </a>
{% endif %} {% endif %}
{% if add_ingredient %} {% if add_ingredient %}
<a class="btn btn-sm btn-primary" href="{% url "food:add_ingredient" pk=food.pk %}"> <a class="btn btn-sm btn-primary" href="{% url "food:add_ingredient" pk=food.pk %}">
{% trans "Add to a meal" %} {% trans "Add to a meal" %}
</a> </a>
{% endif %} {% endif %}
{% if manage_ingredients %} {% if manage_ingredients %}
<a class="btn btn-sm btn-secondary" href="{% url "food:manage_ingredients" pk=food.pk %}"> <a class="btn btn-sm btn-secondary" href="{% url "food:manage_ingredients" pk=food.pk %}">
{% trans "Manage ingredients" %} {% trans "Manage ingredients" %}
</a> </a>
{% endif %} {% endif %}
<a class="btn btn-sm btn-primary" href="{% url "food:food_list" %}"> <a class="btn btn-sm btn-primary" href="{% url "food:food_list" %}">
{% trans "Return to the food list" %} {% trans "Return to the food list" %}
</a> </a>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -7,7 +7,52 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% load i18n %} {% load i18n %}
{% block content %} {% block content %}
{{ block.super }} <div class="card bg-light">
<h3 class="card-header text-center">
{{ title }}
</h3>
<div class="card-body">
<style>
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type=number] {
appearance: textfield;
padding: 6px;
border: 1px solid #ccc;
border-radius: 4px;
width: 100px;
}
</style>
<div class="d-flex align-items-center" style="max-width: 300px;">
<form method="get" action="{% url 'food:redirect_view' %}" class="d-flex w-100">
<input type="number" name="slug" placeholder="QR-code" required class="form-control form-control-sm" style="max-width: 120px;">
<button type="submit" class="btn btn-sm btn-primary">{% trans "View food" %}</button>
</form>
</div>
</div>
<div class="card-body">
<input id="searchbar" type="text" class="form-control"
placeholder="{% trans "Search by attribute such as name..." %}">
</div>
{% block extra_inside_card %}
{% endblock %}
<div id="dynamic-table">
{% if table.data %}
{% render_table table %}
{% else %}
<div class="card-body">
<div class="alert alert-warning">
{% trans "There is no results." %}
</div>
</div>
{% endif %}
</div>
</div>
<br> <br>
<div class="card bg-light mb-3"> <div class="card bg-light mb-3">
<h3 class="card-header text-center"> <h3 class="card-header text-center">
@ -68,4 +113,20 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% endfor %} {% endfor %}
{% endif %} {% endif %}
</div> </div>
{% endblock %}
<script>
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('goButton').addEventListener('click', function(event) {
event.preventDefault();
const slug = document.getElementById('slugInput').value;
if (slug && !isNaN(slug)) {
window.location.href = `/food/${slug}/`;
} else {
alert("Veuillez entrer un nombre valide.");
}
});
});
</script>
{% endblock %}

View File

@ -18,4 +18,5 @@ urlpatterns = [
path('detail/basic/<int:pk>', views.BasicFoodDetailView.as_view(), name='basicfood_view'), path('detail/basic/<int:pk>', views.BasicFoodDetailView.as_view(), name='basicfood_view'),
path('detail/transformed/<int:pk>', views.TransformedFoodDetailView.as_view(), name='transformedfood_view'), path('detail/transformed/<int:pk>', views.TransformedFoodDetailView.as_view(), name='transformedfood_view'),
path('add/ingredient/<int:pk>', views.AddIngredientView.as_view(), name='add_ingredient'), path('add/ingredient/<int:pk>', views.AddIngredientView.as_view(), name='add_ingredient'),
path('redirect/', views.QRCodeRedirectView.as_view(), name='redirect_view'),
] ]

View File

@ -10,6 +10,7 @@ from django.db.models import Q
from django.http import HttpResponseRedirect, Http404 from django.http import HttpResponseRedirect, Http404
from django.views.generic import DetailView, UpdateView, CreateView from django.views.generic import DetailView, UpdateView, CreateView
from django.views.generic.list import ListView from django.views.generic.list import ListView
from django.views.generic.base import RedirectView
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -454,6 +455,8 @@ class FoodDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
context["fields"] = [( context["fields"] = [(
Food._meta.get_field(field).verbose_name.capitalize(), Food._meta.get_field(field).verbose_name.capitalize(),
value) for field, value in fields.items()] value) for field, value in fields.items()]
if self.object.QR_code.exists():
context["QR_code"] = self.object.QR_code.first()
context["meals"] = self.object.transformed_ingredient_inv.all() context["meals"] = self.object.transformed_ingredient_inv.all()
context["update"] = PermissionBackend.check_perm(self.request, "food.change_food") context["update"] = PermissionBackend.check_perm(self.request, "food.change_food")
context["add_ingredient"] = (self.object.end_of_life == '' and PermissionBackend.check_perm(self.request, "food.change_transformedfood")) context["add_ingredient"] = (self.object.end_of_life == '' and PermissionBackend.check_perm(self.request, "food.change_transformedfood"))
@ -507,3 +510,14 @@ class TransformedFoodDetailView(FoodDetailView):
if Food.objects.filter(pk=kwargs['pk']).count() == 1: if Food.objects.filter(pk=kwargs['pk']).count() == 1:
kwargs['stop_redirect'] = (Food.objects.get(pk=kwargs['pk']).polymorphic_ctype.model == 'transformedfood') kwargs['stop_redirect'] = (Food.objects.get(pk=kwargs['pk']).polymorphic_ctype.model == 'transformedfood')
return super().get(*args, **kwargs) return super().get(*args, **kwargs)
class QRCodeRedirectView(RedirectView):
"""
Redirects to the QR code creation page from Food List
"""
def get_redirect_url(self, *args, **kwargs):
slug = self.request.GET.get('slug')
if slug:
return reverse_lazy('food:qrcode_create', kwargs={'slug': slug})
return reverse_lazy('food:list')

View File

@ -6,7 +6,7 @@ from django.conf import settings
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .signals import save_user_profile from .signals import save_user_profile, update_wei_registration_fee_on_membership_creation, update_wei_registration_fee_on_club_change
class MemberConfig(AppConfig): class MemberConfig(AppConfig):
@ -17,7 +17,16 @@ class MemberConfig(AppConfig):
""" """
Define app internal signals to interact with other apps Define app internal signals to interact with other apps
""" """
from .models import Membership, Club
post_save.connect( post_save.connect(
save_user_profile, save_user_profile,
sender=settings.AUTH_USER_MODEL, sender=settings.AUTH_USER_MODEL,
) )
post_save.connect(
update_wei_registration_fee_on_membership_creation,
sender=Membership
)
post_save.connect(
update_wei_registration_fee_on_club_change,
sender=Club
)

View File

@ -438,8 +438,6 @@ class Membership(models.Model):
) )
if hasattr(self, '_force_renew_parent') and self._force_renew_parent: if hasattr(self, '_force_renew_parent') and self._force_renew_parent:
new_membership._force_renew_parent = True new_membership._force_renew_parent = True
if hasattr(self, '_soge') and self._soge:
new_membership._soge = True
if hasattr(self, '_force_save') and self._force_save: if hasattr(self, '_force_save') and self._force_save:
new_membership._force_save = True new_membership._force_save = True
new_membership.save() new_membership.save()
@ -458,8 +456,6 @@ class Membership(models.Model):
# Renew the previous membership of the parent club # Renew the previous membership of the parent club
parent_membership = parent_membership.first() parent_membership = parent_membership.first()
parent_membership._force_renew_parent = True parent_membership._force_renew_parent = True
if hasattr(self, '_soge'):
parent_membership._soge = True
if hasattr(self, '_force_save'): if hasattr(self, '_force_save'):
parent_membership._force_save = True parent_membership._force_save = True
parent_membership.renew() parent_membership.renew()
@ -471,8 +467,6 @@ class Membership(models.Model):
date_start=self.date_start, date_start=self.date_start,
) )
parent_membership._force_renew_parent = True parent_membership._force_renew_parent = True
if hasattr(self, '_soge'):
parent_membership._soge = True
if hasattr(self, '_force_save'): if hasattr(self, '_force_save'):
parent_membership._force_save = True parent_membership._force_save = True
parent_membership.save() parent_membership.save()

View File

@ -13,3 +13,25 @@ def save_user_profile(instance, created, raw, **_kwargs):
instance.profile.email_confirmed = True instance.profile.email_confirmed = True
instance.profile.registration_valid = True instance.profile.registration_valid = True
instance.profile.save() instance.profile.save()
def update_wei_registration_fee_on_membership_creation(sender, instance, created, **kwargs):
if created:
from wei.models import WEIRegistration
if instance.club.id == 1 or instance.club.id == 2:
registrations = WEIRegistration.objects.filter(
user=instance.user,
wei__year=instance.date_start.year,
)
for r in registrations:
r.save()
def update_wei_registration_fee_on_club_change(sender, instance, **kwargs):
from wei.models import WEIRegistration
if instance.id == 1 or instance.id == 2:
registrations = WEIRegistration.objects.filter(
wei__year=instance.membership_start.year,
)
for r in registrations:
r.save()

View File

@ -4810,18 +4810,6 @@
] ]
} }
}, },
{
"model": "permission.role",
"pk": 16,
"fields": {
"for_club": null,
"name": "\u00c9lectron libre (avec perm)",
"permissions": [
22,
84
]
}
},
{ {
"model": "permission.role", "model": "permission.role",
"pk": 17, "pk": 17,
@ -5093,11 +5081,6 @@
"pk": 15, "pk": 15,
"fields": {} "fields": {}
}, },
{
"model": "wei.weirole",
"pk": 16,
"fields": {}
},
{ {
"model": "wei.weirole", "model": "wei.weirole",
"pk": 17, "pk": 17,

View File

@ -353,7 +353,7 @@ class SogeCredit(models.Model):
def amount(self): def amount(self):
if self.valid: if self.valid:
return self.credit_transaction.total return self.credit_transaction.total
amount = sum(transaction.total for transaction in self.transactions.all()) amount = sum(max(transaction.total - 2000, 0) for transaction in self.transactions.all())
if 'wei' in settings.INSTALLED_APPS: if 'wei' in settings.INSTALLED_APPS:
from wei.models import WEIMembership from wei.models import WEIMembership
if not WEIMembership.objects\ if not WEIMembership.objects\
@ -441,7 +441,7 @@ class SogeCredit(models.Model):
With Great Power Comes Great Responsibility... With Great Power Comes Great Responsibility...
""" """
total_fee = sum(transaction.total for transaction in self.transactions.all() if not transaction.valid) total_fee = sum(max(transaction.total - 2000, 0) for transaction in self.transactions.all() if not transaction.valid)
if self.user.note.balance < total_fee: if self.user.note.balance < total_fee:
raise ValidationError(_("This user doesn't have enough money to pay the memberships with its note. " raise ValidationError(_("This user doesn't have enough money to pay the memberships with its note. "
"Please ask her/him to credit the note before invalidating this credit.")) "Please ask her/him to credit the note before invalidating this credit."))

View File

@ -77,7 +77,7 @@ class WEIRegistrationViewSet(ReadProtectedModelViewSet):
filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter]
filterset_fields = ['user', 'user__username', 'user__first_name', 'user__last_name', 'user__email', filterset_fields = ['user', 'user__username', 'user__first_name', 'user__last_name', 'user__email',
'user__note__alias__name', 'user__note__alias__normalized_name', 'wei', 'wei__name', 'user__note__alias__name', 'user__note__alias__normalized_name', 'wei', 'wei__name',
'wei__email', 'wei__year', 'soge_credit', 'caution_check', 'birth_date', 'gender', 'wei__email', 'wei__year', 'soge_credit', 'deposit_check', 'birth_date', 'gender',
'clothing_cut', 'clothing_size', 'first_year', 'emergency_contact_name', 'clothing_cut', 'clothing_size', 'first_year', 'emergency_contact_name',
'emergency_contact_phone', ] 'emergency_contact_phone', ]
search_fields = ['$user__username', '$user__first_name', '$user__last_name', '$user__email', search_fields = ['$user__username', '$user__first_name', '$user__last_name', '$user__email',

View File

@ -1,11 +1,11 @@
# Copyright (C) 2018-2025 by BDE ENS Paris-Saclay # Copyright (C) 2018-2025 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from .registration import WEIForm, WEIRegistrationForm, WEIRegistration1AForm, WEIRegistration2AForm, WEIMembership1AForm, \ from .registration import WEIForm, WEIRegistrationForm, WEIMembership1AForm, \
WEIMembershipForm, BusForm, BusTeamForm WEIMembershipForm, BusForm, BusTeamForm
from .surveys import WEISurvey, WEISurveyInformation, WEISurveyAlgorithm, CurrentSurvey from .surveys import WEISurvey, WEISurveyInformation, WEISurveyAlgorithm, CurrentSurvey
__all__ = [ __all__ = [
'WEIForm', 'WEIRegistrationForm', 'WEIRegistration1AForm', 'WEIRegistration2AForm', 'WEIMembership1AForm', 'WEIMembershipForm', 'BusForm', 'BusTeamForm', 'WEIForm', 'WEIRegistrationForm', 'WEIMembership1AForm', 'WEIMembershipForm', 'BusForm', 'BusTeamForm',
'WEISurvey', 'WEISurveyInformation', 'WEISurveyAlgorithm', 'CurrentSurvey', 'WEISurvey', 'WEISurveyInformation', 'WEISurveyAlgorithm', 'CurrentSurvey',
] ]

View File

@ -24,7 +24,8 @@ class WEIForm(forms.ModelForm):
"membership_end": DatePickerInput(), "membership_end": DatePickerInput(),
"date_start": DatePickerInput(), "date_start": DatePickerInput(),
"date_end": DatePickerInput(), "date_end": DatePickerInput(),
"caution_amount": AmountInput(), "deposit_amount": AmountInput(),
"fee_soge_credit": AmountInput(),
} }
@ -43,7 +44,7 @@ class WEIRegistrationForm(forms.ModelForm):
fields = [ fields = [
'user', 'soge_credit', 'birth_date', 'gender', 'clothing_size', 'user', 'soge_credit', 'birth_date', 'gender', 'clothing_size',
'health_issues', 'emergency_contact_name', 'emergency_contact_phone', 'health_issues', 'emergency_contact_name', 'emergency_contact_phone',
'first_year', 'information_json', 'caution_check' 'first_year', 'information_json', 'deposit_check', 'deposit_type'
] ]
widgets = { widgets = {
"user": Autocomplete( "user": Autocomplete(
@ -58,26 +59,13 @@ class WEIRegistrationForm(forms.ModelForm):
'minDate': '1900-01-01', 'minDate': '1900-01-01',
'maxDate': '2100-01-01' 'maxDate': '2100-01-01'
}), }),
"caution_check": forms.BooleanField( "deposit_check": forms.BooleanField(
required=False, required=False,
), ),
"deposit_type": forms.RadioSelect(),
} }
class WEIRegistration2AForm(WEIRegistrationForm):
class Meta(WEIRegistrationForm.Meta):
fields = WEIRegistrationForm.Meta.fields + ['caution_type']
widgets = WEIRegistrationForm.Meta.widgets.copy()
widgets.update({
"caution_type": forms.RadioSelect(),
})
class WEIRegistration1AForm(WEIRegistrationForm):
class Meta(WEIRegistrationForm.Meta):
fields = WEIRegistrationForm.Meta.fields
class WEIChooseBusForm(forms.Form): class WEIChooseBusForm(forms.Form):
bus = forms.ModelMultipleChoiceField( bus = forms.ModelMultipleChoiceField(
queryset=Bus.objects, queryset=Bus.objects,
@ -99,7 +87,7 @@ class WEIChooseBusForm(forms.Form):
queryset=WEIRole.objects.filter(~Q(name="1A") & ~Q(name="GC WEI")), queryset=WEIRole.objects.filter(~Q(name="1A") & ~Q(name="GC WEI")),
label=_("WEI Roles"), label=_("WEI Roles"),
help_text=_("Select the roles that you are interested in."), help_text=_("Select the roles that you are interested in."),
initial=WEIRole.objects.filter(name="Adhérent⋅e WEI").all(), initial=WEIRole.objects.filter(Q(name="Adhérent⋅e WEI") | Q(name="\u00c9lectron libre")).all(),
widget=CheckboxSelectMultiple(), widget=CheckboxSelectMultiple(),
) )
@ -173,7 +161,7 @@ class WEIMembership1AForm(WEIMembershipForm):
""" """
Used to confirm registrations of first year members without choosing a bus now. Used to confirm registrations of first year members without choosing a bus now.
""" """
caution_check = None deposit_check = None
roles = None roles = None
def clean(self): def clean(self):

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2.23 on 2025-07-15 14:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wei', '0013_weiclub_caution_amount_weiregistration_caution_type'),
]
operations = [
migrations.AddField(
model_name='weiclub',
name='fee_soge_credit',
field=models.PositiveIntegerField(default=2000, verbose_name='fee soge credit'),
),
]

View File

@ -0,0 +1,40 @@
# Generated by Django 4.2.23 on 2025-07-15 16:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wei', '0014_weiclub_fee_soge_credit'),
]
operations = [
migrations.RemoveField(
model_name='weiclub',
name='caution_amount',
),
migrations.RemoveField(
model_name='weiregistration',
name='caution_check',
),
migrations.RemoveField(
model_name='weiregistration',
name='caution_type',
),
migrations.AddField(
model_name='weiclub',
name='deposit_amount',
field=models.PositiveIntegerField(default=0, verbose_name='deposit amount'),
),
migrations.AddField(
model_name='weiregistration',
name='deposit_check',
field=models.BooleanField(default=False, verbose_name='Deposit check given'),
),
migrations.AddField(
model_name='weiregistration',
name='deposit_type',
field=models.CharField(choices=[('check', 'Check'), ('note', 'Note transaction')], default='check', max_length=16, verbose_name='deposit type'),
),
]

View File

@ -0,0 +1,23 @@
# Generated by Django 5.2.4 on 2025-07-19 12:17
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wei', '0015_remove_weiclub_caution_amount_and_more'),
]
operations = [
migrations.AddField(
model_name='weiregistration',
name='fee',
field=models.PositiveIntegerField(blank=True, default=0, verbose_name='fee'),
),
migrations.AlterField(
model_name='weiclub',
name='fee_soge_credit',
field=models.PositiveIntegerField(default=2000, verbose_name='membership fee (soge credit)'),
),
]

View File

@ -33,11 +33,16 @@ class WEIClub(Club):
verbose_name=_("date end"), verbose_name=_("date end"),
) )
caution_amount = models.PositiveIntegerField( deposit_amount = models.PositiveIntegerField(
verbose_name=_("caution amount"), verbose_name=_("deposit amount"),
default=0, default=0,
) )
fee_soge_credit = models.PositiveIntegerField(
verbose_name=_("membership fee (soge credit)"),
default=2000,
)
class Meta: class Meta:
verbose_name = _("WEI") verbose_name = _("WEI")
verbose_name_plural = _("WEI") verbose_name_plural = _("WEI")
@ -197,19 +202,19 @@ class WEIRegistration(models.Model):
verbose_name=_("Credit from Société générale"), verbose_name=_("Credit from Société générale"),
) )
caution_check = models.BooleanField( deposit_check = models.BooleanField(
default=False, default=False,
verbose_name=_("Caution check given") verbose_name=_("Deposit check given")
) )
caution_type = models.CharField( deposit_type = models.CharField(
max_length=16, max_length=16,
choices=( choices=(
('check', _("Check")), ('check', _("Check")),
('note', _("Note transaction")), ('note', _("Note transaction")),
), ),
default='check', default='check',
verbose_name=_("caution type"), verbose_name=_("deposit type"),
) )
birth_date = models.DateField( birth_date = models.DateField(
@ -280,6 +285,12 @@ class WEIRegistration(models.Model):
"encoded in JSON"), "encoded in JSON"),
) )
fee = models.PositiveIntegerField(
default=0,
verbose_name=_('fee'),
blank=True,
)
class Meta: class Meta:
unique_together = ('user', 'wei',) unique_together = ('user', 'wei',)
verbose_name = _("WEI User") verbose_name = _("WEI User")
@ -304,7 +315,25 @@ class WEIRegistration(models.Model):
self.information_json = json.dumps(information, indent=2) self.information_json = json.dumps(information, indent=2)
@property @property
def fee(self): def is_validated(self):
try:
return self.membership is not None
except AttributeError:
return False
@property
def validation_status(self):
"""
Define an order to have easier access to validatable registrations
"""
if self.fee + (self.wei.deposit_amount if self.deposit_type == 'note' else 0) > self.user.note.balance:
return 2
elif self.first_year:
return 1
else:
return 0
def calculate_fee(self):
bde = Club.objects.get(pk=1) bde = Club.objects.get(pk=1)
kfet = Club.objects.get(pk=2) kfet = Club.objects.get(pk=2)
@ -319,7 +348,8 @@ class WEIRegistration(models.Model):
date_start__gte=bde.membership_start, date_start__gte=bde.membership_start,
).exists() ).exists()
fee = self.wei.membership_fee_paid if self.user.profile.paid \ fee = self.wei.fee_soge_credit if self.soge_credit \
else self.wei.membership_fee_paid if self.user.profile.paid \
else self.wei.membership_fee_unpaid else self.wei.membership_fee_unpaid
if not kfet_member: if not kfet_member:
fee += kfet.membership_fee_paid if self.user.profile.paid \ fee += kfet.membership_fee_paid if self.user.profile.paid \
@ -330,12 +360,9 @@ class WEIRegistration(models.Model):
return fee return fee
@property def save(self, *args, **kwargs):
def is_validated(self): self.fee = self.calculate_fee()
try: super().save(*args, **kwargs)
return self.membership is not None
except AttributeError:
return False
class WEIMembership(Membership): class WEIMembership(Membership):

View File

@ -58,8 +58,8 @@ class WEIRegistrationTable(tables.Table):
validate = tables.Column( validate = tables.Column(
verbose_name=_("Validate"), verbose_name=_("Validate"),
orderable=False, orderable=True,
accessor=A('pk'), accessor='validate_status',
attrs={ attrs={
'th': { 'th': {
'id': 'validate-membership-header' 'id': 'validate-membership-header'
@ -98,12 +98,13 @@ class WEIRegistrationTable(tables.Table):
if not hasperm: if not hasperm:
return format_html("<span class='no-perm'></span>") return format_html("<span class='no-perm'></span>")
url = reverse_lazy('wei:wei_update_registration', args=(record.pk,)) + '?validate=true' url = reverse_lazy('wei:validate_registration', args=(record.pk,))
text = _('Validate') text = _('Validate')
if record.fee > record.user.note.balance and not record.soge_credit: status = record.validation_status
if status == 2:
btn_class = 'btn-secondary' btn_class = 'btn-secondary'
tooltip = _("The user does not have enough money.") tooltip = _("The user does not have enough money.")
elif record.first_year: elif status == 1:
btn_class = 'btn-info' btn_class = 'btn-info'
tooltip = _("The user is in first year. You may validate the credit, the algorithm will run later.") tooltip = _("The user is in first year. You may validate the credit, the algorithm will run later.")
else: else:
@ -121,9 +122,10 @@ class WEIRegistrationTable(tables.Table):
attrs = { attrs = {
'class': 'table table-condensed table-striped table-hover' 'class': 'table table-condensed table-striped table-hover'
} }
order_by = ('validate', 'user',)
model = WEIRegistration model = WEIRegistration
template_name = 'django_tables2/bootstrap4.html' template_name = 'django_tables2/bootstrap4.html'
fields = ('user', 'user__first_name', 'user__last_name', 'first_year', 'caution_check', fields = ('user', 'user__first_name', 'user__last_name', 'first_year', 'deposit_check',
'edit', 'validate', 'delete',) 'edit', 'validate', 'delete',)
row_attrs = { row_attrs = {
'class': 'table-row', 'class': 'table-row',
@ -163,7 +165,7 @@ class WEIMembershipTable(tables.Table):
model = WEIMembership model = WEIMembership
template_name = 'django_tables2/bootstrap4.html' template_name = 'django_tables2/bootstrap4.html'
fields = ('user', 'user__last_name', 'user__first_name', 'registration__gender', 'user__profile__department', fields = ('user', 'user__last_name', 'user__first_name', 'registration__gender', 'user__profile__department',
'year', 'bus', 'team', 'registration__caution_check', ) 'year', 'bus', 'team', 'registration__deposit_check', )
row_attrs = { row_attrs = {
'class': 'table-row', 'class': 'table-row',
'id': lambda record: "row-" + str(record.pk), 'id': lambda record: "row-" + str(record.pk),

View File

@ -49,9 +49,9 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if club.caution_amount > 0 %} {% if club.deposit_amount > 0 %}
<dt class="col-xl-6">{% trans 'Caution amount'|capfirst %}</dt> <dt class="col-xl-6">{% trans 'Deposit amount'|capfirst %}</dt>
<dd class="col-xl-6">{{ club.caution_amount|pretty_money }}</dd> <dd class="col-xl-6">{{ club.deposit_amount|pretty_money }}</dd>
{% endif %} {% endif %}
{% if "note.view_note"|has_perm:club.note %} {% if "note.view_note"|has_perm:club.note %}

View File

@ -67,20 +67,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
</div> </div>
{% endif %} {% endif %}
{% if history_list.data %}
<div class="card bg-white mb-3">
<div class="card-header position-relative" id="historyListHeading">
<a class="stretched-link font-weight-bold text-decoration-none" {% if "note.view_note"|has_perm:club.note %}
href="{% url 'note:transactions' pk=club.note.pk %}" {% endif %}>
<i class="fa fa-euro"></i> {% trans "Transaction history" %}
</a>
</div>
<div id="history_list">
{% render_table history_list %}
</div>
</div>
{% endif %}
{% if pre_registrations.data %} {% if pre_registrations.data %}
<div class="card bg-white mb-3"> <div class="card bg-white mb-3">
<div class="card-header position-relative" id="historyListHeading"> <div class="card-header position-relative" id="historyListHeading">
@ -99,6 +85,19 @@ SPDX-License-Identifier: GPL-3.0-or-later
<a href="{% url 'wei:wei_1A_list' pk=object.pk %}" class="btn btn-block btn-info">{% trans "Attribute buses" %}</a> <a href="{% url 'wei:wei_1A_list' pk=object.pk %}" class="btn btn-block btn-info">{% trans "Attribute buses" %}</a>
{% endif %} {% endif %}
{% if history_list.data %}
<div class="card bg-white mt-3">
<div class="card-header position-relative" id="historyListHeading">
<a class="stretched-link font-weight-bold text-decoration-none" {% if "note.view_note"|has_perm:club.note %}
href="{% url 'note:transactions' pk=club.note.pk %}" {% endif %}>
<i class="fa fa-euro"></i> {% trans "Transaction history" %}
</a>
</div>
<div id="history_list">
{% render_table history_list %}
</div>
</div>
{% endif %}
{% endblock %} {% endblock %}

View File

@ -95,8 +95,8 @@ SPDX-License-Identifier: GPL-3.0-or-later
<dd class="col-xl-6"><em>{% trans "The algorithm didn't run." %}</em></dd> <dd class="col-xl-6"><em>{% trans "The algorithm didn't run." %}</em></dd>
{% endif %} {% endif %}
{% else %} {% else %}
<dt class="col-xl-6">{% trans 'caution check given'|capfirst %}</dt> <dt class="col-xl-6">{% trans 'Deposit check given'|capfirst %}</dt>
<dd class="col-xl-6">{{ registration.caution_check|yesno }}</dd> <dd class="col-xl-6">{{ registration.deposit_check|yesno }}</dd>
{% with information=registration.information %} {% with information=registration.information %}
<dt class="col-xl-6">{% trans 'preferred bus'|capfirst %}</dt> <dt class="col-xl-6">{% trans 'preferred bus'|capfirst %}</dt>
@ -137,41 +137,37 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% if registration.soge_credit %} {% if registration.soge_credit %}
<div class="alert alert-warning"> <div class="alert alert-warning">
{% blocktrans trimmed %} {% blocktrans trimmed %}
The WEI will be paid by Société générale. The membership will be created even if the bank didn't pay the BDE yet. The WEI will partially be paid by Société générale. The membership will be created even if the bank didn't pay the BDE yet.
The membership transaction will be created but will be invalid. You will have to validate it once the bank The membership transaction will be created but will be invalid. You will have to validate it once the bank
validated the creation of the account, or to change the payment method. validated the creation of the account, or to change the payment method.
{% endblocktrans %} {% endblocktrans %}
</div> </div>
{% else %}
<div class="alert {% if registration.user.note.balance < fee %}alert-danger{% else %}alert-success{% endif %}">
<h5>{% trans "Required payments:" %}</h5>
<ul>
<li>{% blocktrans trimmed with amount=fee|pretty_money %}
Membership fees: {{ amount }}
{% endblocktrans %}</li>
{% if registration.caution_type == 'note' %}
<li>{% blocktrans trimmed with amount=club.caution_amount|pretty_money %}
Deposit (by Note transaction): {{ amount }}
{% endblocktrans %}</li>
<li><strong>{% blocktrans trimmed with total=total_needed|pretty_money %}
Total needed: {{ total }}
{% endblocktrans %}</strong></li>
{% else %}
<li>{% blocktrans trimmed with amount=club.caution_amount|pretty_money %}
Deposit (by check): {{ amount }}
{% endblocktrans %}</li>
<li><strong>{% blocktrans trimmed with total=fee|pretty_money %}
Total needed: {{ total }}
{% endblocktrans %}</strong></li>
{% endif %}
</ul>
<p>{% blocktrans trimmed with balance=registration.user.note.balance|pretty_money %}
Current balance: {{ balance }}
{% endblocktrans %}</p>
</div>
{% endif %} {% endif %}
<div class="alert {% if registration.user.note.balance < fee %}alert-danger{% else %}alert-success{% endif %}">
<h5>{% trans "Required payments:" %}</h5>
<ul>
<li>{% blocktrans trimmed with amount=fee|pretty_money %}
Membership fees: {{ amount }}
{% endblocktrans %}</li>
{% if registration.deposit_type == 'note' %}
<li>{% blocktrans trimmed with amount=club.deposit_amount|pretty_money %}
Deposit (by Note transaction): {{ amount }}
{% endblocktrans %}</li>
{% else %}
<li>{% blocktrans trimmed with amount=club.deposit_amount|pretty_money %}
Deposit (by check): {{ amount }}
{% endblocktrans %}</li>
{% endif %}
<li><strong>{% blocktrans trimmed with total=total_needed|pretty_money %}
Total needed: {{ total }}
{% endblocktrans %}</strong></li>
</ul>
<p>{% blocktrans trimmed with balance=registration.user.note.balance|pretty_money %}
Current balance: {{ balance }}
{% endblocktrans %}</p>
</div>
{% if not registration.caution_check and not registration.first_year and registration.caution_type == 'check' %} {% if not registration.deposit_check and not registration.first_year and registration.caution_type == 'check' %}
<div class="alert alert-danger"> <div class="alert alert-danger">
{% trans "The user didn't give her/his caution check." %} {% trans "The user didn't give her/his caution check." %}
</div> </div>

View File

@ -101,7 +101,7 @@ class TestWEIRegistration(TestCase):
user_id=self.user.id, user_id=self.user.id,
wei_id=self.wei.id, wei_id=self.wei.id,
soge_credit=True, soge_credit=True,
caution_check=True, deposit_check=True,
birth_date=date(2000, 1, 1), birth_date=date(2000, 1, 1),
gender="nonbinary", gender="nonbinary",
clothing_cut="male", clothing_cut="male",
@ -121,12 +121,13 @@ class TestWEIRegistration(TestCase):
email="gc.wei@example.com", email="gc.wei@example.com",
membership_fee_paid=12500, membership_fee_paid=12500,
membership_fee_unpaid=5500, membership_fee_unpaid=5500,
fee_soge_credit=2000,
membership_start=str(self.year + 1) + "-08-01", membership_start=str(self.year + 1) + "-08-01",
membership_end=str(self.year + 1) + "-09-30", membership_end=str(self.year + 1) + "-09-30",
year=self.year + 1, year=self.year + 1,
date_start=str(self.year + 1) + "-09-01", date_start=str(self.year + 1) + "-09-01",
date_end=str(self.year + 1) + "-09-03", date_end=str(self.year + 1) + "-09-03",
caution_amount=12000, deposit_amount=12000,
)) ))
qs = WEIClub.objects.filter(name="Create WEI Test", year=self.year + 1) qs = WEIClub.objects.filter(name="Create WEI Test", year=self.year + 1)
self.assertTrue(qs.exists()) self.assertTrue(qs.exists())
@ -157,11 +158,12 @@ class TestWEIRegistration(TestCase):
email="wei-updated@example.com", email="wei-updated@example.com",
membership_fee_paid=0, membership_fee_paid=0,
membership_fee_unpaid=0, membership_fee_unpaid=0,
fee_soge_credit=0,
membership_start="2000-08-01", membership_start="2000-08-01",
membership_end="2000-09-30", membership_end="2000-09-30",
date_start="2000-09-01", date_start="2000-09-01",
date_end="2000-09-03", date_end="2000-09-03",
caution_amount=12000, deposit_amount=12000,
)) ))
qs = WEIClub.objects.filter(name="Update WEI Test", id=self.wei.id) qs = WEIClub.objects.filter(name="Update WEI Test", id=self.wei.id)
self.assertRedirects(response, reverse("wei:wei_detail", kwargs=dict(pk=self.wei.pk)), 302, 200) self.assertRedirects(response, reverse("wei:wei_detail", kwargs=dict(pk=self.wei.pk)), 302, 200)
@ -320,7 +322,7 @@ class TestWEIRegistration(TestCase):
bus=[], bus=[],
team=[], team=[],
roles=[], roles=[],
caution_type='check' deposit_type='check'
)) ))
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertFalse(response.context["membership_form"].is_valid()) self.assertFalse(response.context["membership_form"].is_valid())
@ -338,7 +340,7 @@ class TestWEIRegistration(TestCase):
bus=[self.bus.id], bus=[self.bus.id],
team=[self.team.id], team=[self.team.id],
roles=[role.id for role in WEIRole.objects.filter(~Q(name="1A") & ~Q(name="GC WEI")).all()], roles=[role.id for role in WEIRole.objects.filter(~Q(name="1A") & ~Q(name="GC WEI")).all()],
caution_type='check' deposit_type='check'
)) ))
qs = WEIRegistration.objects.filter(user_id=user.id) qs = WEIRegistration.objects.filter(user_id=user.id)
self.assertTrue(qs.exists()) self.assertTrue(qs.exists())
@ -358,7 +360,7 @@ class TestWEIRegistration(TestCase):
bus=[self.bus.id], bus=[self.bus.id],
team=[self.team.id], team=[self.team.id],
roles=[role.id for role in WEIRole.objects.filter(~Q(name="1A")).all()], roles=[role.id for role in WEIRole.objects.filter(~Q(name="1A")).all()],
caution_type='check' deposit_type='check'
)) ))
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertTrue("This user is already registered to this WEI." in str(response.context["form"].errors)) self.assertTrue("This user is already registered to this WEI." in str(response.context["form"].errors))
@ -511,7 +513,7 @@ class TestWEIRegistration(TestCase):
team=[self.team.id], team=[self.team.id],
roles=[role.id for role in WEIRole.objects.filter(name="Adhérent⋅e WEI").all()], roles=[role.id for role in WEIRole.objects.filter(name="Adhérent⋅e WEI").all()],
information_json=self.registration.information_json, information_json=self.registration.information_json,
caution_type='check' deposit_type='check'
) )
) )
qs = WEIRegistration.objects.filter(user_id=self.user.id, soge_credit=False, clothing_size="M") qs = WEIRegistration.objects.filter(user_id=self.user.id, soge_credit=False, clothing_size="M")
@ -566,7 +568,7 @@ class TestWEIRegistration(TestCase):
team=[self.team.id], team=[self.team.id],
roles=[role.id for role in WEIRole.objects.filter(name="Adhérent⋅e WEI").all()], roles=[role.id for role in WEIRole.objects.filter(name="Adhérent⋅e WEI").all()],
information_json=self.registration.information_json, information_json=self.registration.information_json,
caution_type='check' deposit_type='check'
) )
) )
qs = WEIRegistration.objects.filter(user_id=self.user.id, clothing_size="L") qs = WEIRegistration.objects.filter(user_id=self.user.id, clothing_size="L")
@ -590,7 +592,7 @@ class TestWEIRegistration(TestCase):
team=[], team=[],
roles=[], roles=[],
information_json=self.registration.information_json, information_json=self.registration.information_json,
caution_type='check' deposit_type='check'
) )
) )
self.assertFalse(response.context["membership_form"].is_valid()) self.assertFalse(response.context["membership_form"].is_valid())
@ -640,7 +642,7 @@ class TestWEIRegistration(TestCase):
last_name="admin", last_name="admin",
first_name="admin", first_name="admin",
bank="Société générale", bank="Société générale",
caution_check=True, deposit_check=True,
)) ))
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertFalse(response.context["form"].is_valid()) self.assertFalse(response.context["form"].is_valid())
@ -655,7 +657,7 @@ class TestWEIRegistration(TestCase):
last_name="admin", last_name="admin",
first_name="admin", first_name="admin",
bank="Société générale", bank="Société générale",
caution_check=True, deposit_check=True,
)) ))
self.assertRedirects(response, reverse("wei:wei_registrations", kwargs=dict(pk=self.registration.wei.pk)), 302, 200) self.assertRedirects(response, reverse("wei:wei_registrations", kwargs=dict(pk=self.registration.wei.pk)), 302, 200)
@ -678,11 +680,7 @@ class TestWEIRegistration(TestCase):
self.assertTrue(soge_credit.exists()) self.assertTrue(soge_credit.exists())
soge_credit = soge_credit.get() soge_credit = soge_credit.get()
self.assertTrue(membership.transaction in soge_credit.transactions.all()) self.assertTrue(membership.transaction in soge_credit.transactions.all())
self.assertTrue(kfet_membership.transaction in soge_credit.transactions.all())
self.assertTrue(bde_membership.transaction in soge_credit.transactions.all())
self.assertFalse(membership.transaction.valid) self.assertFalse(membership.transaction.valid)
self.assertFalse(kfet_membership.transaction.valid)
self.assertFalse(bde_membership.transaction.valid)
# Check that if the WEI is started, we can't update a wei # Check that if the WEI is started, we can't update a wei
self.wei.date_start = date(2000, 1, 1) self.wei.date_start = date(2000, 1, 1)
@ -815,7 +813,7 @@ class TestWeiAPI(TestAPI):
user_id=self.user.id, user_id=self.user.id,
wei_id=self.wei.id, wei_id=self.wei.id,
soge_credit=True, soge_credit=True,
caution_check=True, deposit_check=True,
birth_date=date(2000, 1, 1), birth_date=date(2000, 1, 1),
gender="nonbinary", gender="nonbinary",
clothing_cut="male", clothing_cut="male",

View File

@ -13,7 +13,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.db import transaction from django.db import transaction
from django.db.models import Q, Count from django.db.models import Q, Count, Case, When, Value, IntegerField, F
from django.db.models.functions.text import Lower from django.db.models.functions.text import Lower
from django import forms from django import forms
from django.http import HttpResponse, Http404 from django.http import HttpResponse, Http404
@ -27,7 +27,7 @@ from django.views.generic.edit import BaseFormView, DeleteView
from django_tables2 import SingleTableView, MultiTableMixin from django_tables2 import SingleTableView, MultiTableMixin
from api.viewsets import is_regex from api.viewsets import is_regex
from member.models import Membership, Club from member.models import Membership, Club
from note.models import Transaction, NoteClub, Alias, SpecialTransaction, NoteSpecial from note.models import Transaction, NoteClub, Alias, SpecialTransaction
from note.tables import HistoryTable from note.tables import HistoryTable
from note_kfet.settings import BASE_DIR from note_kfet.settings import BASE_DIR
from permission.backends import PermissionBackend from permission.backends import PermissionBackend
@ -35,7 +35,7 @@ from permission.views import ProtectQuerysetMixin, ProtectedCreateView
from .forms.registration import WEIChooseBusForm from .forms.registration import WEIChooseBusForm
from .models import WEIClub, WEIRegistration, WEIMembership, Bus, BusTeam, WEIRole from .models import WEIClub, WEIRegistration, WEIMembership, Bus, BusTeam, WEIRole
from .forms import WEIForm, WEIRegistrationForm, WEIRegistration1AForm, WEIRegistration2AForm, BusForm, BusTeamForm, WEIMembership1AForm, \ from .forms import WEIForm, WEIRegistrationForm, BusForm, BusTeamForm, WEIMembership1AForm, \
WEIMembershipForm, CurrentSurvey WEIMembershipForm, CurrentSurvey
from .tables import BusRepartitionTable, BusTable, BusTeamTable, WEITable, WEIRegistrationTable, \ from .tables import BusRepartitionTable, BusTable, BusTeamTable, WEITable, WEIRegistrationTable, \
WEIRegistration1ATable, WEIMembershipTable WEIRegistration1ATable, WEIMembershipTable
@ -133,6 +133,23 @@ class WEIDetailView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMixin, D
membership=None, membership=None,
wei=club wei=club
) )
# Annotate the query to be able to sort registrations on validate status
pre_registrations = pre_registrations.annotate(
deposit=Case(
When(deposit_type='note', then=F('wei__deposit_amount')),
default=Value(0),
output_field=IntegerField()
)
).annotate(
total_fee=F('fee') + F('deposit')
).annotate(
validate_status=Case(
When(total_fee__gt=F('user__note__balance'), then=Value(2)),
When(first_year=True, then=Value(1)),
default=Value(0),
output_field=IntegerField(),
)
)
buses = Bus.objects.filter(PermissionBackend.filter_queryset(self.request, Bus, "view")) \ buses = Bus.objects.filter(PermissionBackend.filter_queryset(self.request, Bus, "view")) \
.filter(wei=self.object).annotate(count=Count("memberships")).order_by("name") .filter(wei=self.object).annotate(count=Count("memberships")).order_by("name")
return [club_transactions, club_member, pre_registrations, buses, ] return [club_transactions, club_member, pre_registrations, buses, ]
@ -260,6 +277,23 @@ class WEIRegistrationsView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTable
def get_queryset(self, **kwargs): def get_queryset(self, **kwargs):
qs = super().get_queryset(**kwargs).filter(wei=self.club, membership=None).distinct() qs = super().get_queryset(**kwargs).filter(wei=self.club, membership=None).distinct()
# Annotate the query to be able to sort registrations on validate status
qs = qs.annotate(
deposit=Case(
When(deposit_type='note', then=F('wei__deposit_amount')),
default=Value(0),
output_field=IntegerField()
)
).annotate(
total_fee=F('fee') + F('deposit')
).annotate(
validate_status=Case(
When(total_fee__gt=F('user__note__balance'), then=Value(2)),
When(first_year=True, then=Value(1)),
default=Value(0),
output_field=IntegerField(),
)
)
pattern = self.request.GET.get("search", "") pattern = self.request.GET.get("search", "")
@ -510,7 +544,7 @@ class WEIRegister1AView(ProtectQuerysetMixin, ProtectedCreateView):
Register a new user to the WEI Register a new user to the WEI
""" """
model = WEIRegistration model = WEIRegistration
form_class = WEIRegistration1AForm form_class = WEIRegistrationForm
extra_context = {"title": _("Register first year student to the WEI")} extra_context = {"title": _("Register first year student to the WEI")}
def get_sample_object(self): def get_sample_object(self):
@ -560,13 +594,15 @@ class WEIRegister1AView(ProtectQuerysetMixin, ProtectedCreateView):
# Cacher les champs pendant l'inscription initiale # Cacher les champs pendant l'inscription initiale
if "first_year" in form.fields: if "first_year" in form.fields:
del form.fields["first_year"] del form.fields["first_year"]
if "caution_check" in form.fields: if "deposit_check" in form.fields:
del form.fields["caution_check"] del form.fields["deposit_check"]
if "information_json" in form.fields: if "information_json" in form.fields:
del form.fields["information_json"] del form.fields["information_json"]
if "caution_type" in form.fields: if "deposit_type" in form.fields:
del form.fields["caution_type"] del form.fields["deposit_type"]
if "soge_credit" in form.fields:
form.fields["soge_credit"].help_text = _('Check if you will open a Société Générale account')
return form return form
@transaction.atomic @transaction.atomic
@ -604,7 +640,7 @@ class WEIRegister2AView(ProtectQuerysetMixin, ProtectedCreateView):
Register an old user to the WEI Register an old user to the WEI
""" """
model = WEIRegistration model = WEIRegistration
form_class = WEIRegistration2AForm form_class = WEIRegistrationForm
extra_context = {"title": _("Register old student to the WEI")} extra_context = {"title": _("Register old student to the WEI")}
def get_sample_object(self): def get_sample_object(self):
@ -658,6 +694,9 @@ class WEIRegister2AView(ProtectQuerysetMixin, ProtectedCreateView):
def get_form(self, form_class=None): def get_form(self, form_class=None):
form = super().get_form(form_class) form = super().get_form(form_class)
form.fields["user"].initial = self.request.user form.fields["user"].initial = self.request.user
if "soge_credit" in form.fields:
form.fields["soge_credit"].help_text = _('Check if you will open a Société Générale account')
if "myself" in self.request.path and self.request.user.profile.soge: if "myself" in self.request.path and self.request.user.profile.soge:
form.fields["soge_credit"].disabled = True form.fields["soge_credit"].disabled = True
form.fields["soge_credit"].help_text = _("You already opened an account in the Société générale.") form.fields["soge_credit"].help_text = _("You already opened an account in the Société générale.")
@ -665,16 +704,16 @@ class WEIRegister2AView(ProtectQuerysetMixin, ProtectedCreateView):
# Cacher les champs pendant l'inscription initiale # Cacher les champs pendant l'inscription initiale
if "first_year" in form.fields: if "first_year" in form.fields:
del form.fields["first_year"] del form.fields["first_year"]
if "caution_check" in form.fields: if "deposit_check" in form.fields:
del form.fields["caution_check"] del form.fields["deposit_check"]
if "information_json" in form.fields: if "information_json" in form.fields:
del form.fields["information_json"] del form.fields["information_json"]
# S'assurer que le champ caution_type est obligatoire # S'assurer que le champ deposit_type est obligatoire
if "caution_type" in form.fields: if "deposit_type" in form.fields:
form.fields["caution_type"].required = True form.fields["deposit_type"].required = True
form.fields["caution_type"].help_text = _("Choose how you want to pay the deposit") form.fields["deposit_type"].help_text = _("Choose how you want to pay the deposit")
form.fields["caution_type"].widget = forms.RadioSelect(choices=form.fields["caution_type"].choices) form.fields["deposit_type"].widget = forms.RadioSelect(choices=form.fields["deposit_type"].choices)
return form return form
@ -703,7 +742,7 @@ class WEIRegister2AView(ProtectQuerysetMixin, ProtectedCreateView):
form.instance.information = information form.instance.information = information
# Sauvegarder le type de caution # Sauvegarder le type de caution
form.instance.caution_type = form.cleaned_data["caution_type"] form.instance.deposit_type = form.cleaned_data["deposit_type"]
form.instance.save() form.instance.save()
if 'treasury' in settings.INSTALLED_APPS: if 'treasury' in settings.INSTALLED_APPS:
@ -734,14 +773,11 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update
if today >= wei.date_start or today < wei.membership_start: if today >= wei.date_start or today < wei.membership_start:
return redirect(reverse_lazy('wei:wei_closed', args=(wei.pk,))) return redirect(reverse_lazy('wei:wei_closed', args=(wei.pk,)))
# Store the validate parameter in the view's state # Store the validate parameter in the view's state
self.should_validate = request.GET.get('validate', False)
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context["club"] = self.object.wei context["club"] = self.object.wei
# Pass the validate parameter to the template
context["should_validate"] = self.should_validate
if self.object.is_validated: if self.object.is_validated:
membership_form = self.get_membership_form(instance=self.object.membership, membership_form = self.get_membership_form(instance=self.object.membership,
@ -773,17 +809,16 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update
form = super().get_form(form_class) form = super().get_form(form_class)
form.fields["user"].disabled = True form.fields["user"].disabled = True
# The auto-json-format may cause issues with the default field remove # The auto-json-format may cause issues with the default field remove
if not PermissionBackend.check_perm(self.request, 'wei.change_weiregistration_information_json', self.object): if "information_json" in form.fields:
del form.fields["information_json"] del form.fields["information_json"]
# Masquer le champ caution_check pour tout le monde dans le formulaire de modification # Masquer le champ deposit_check pour tout le monde dans le formulaire de modification
if "caution_check" in form.fields: if "deposit_check" in form.fields:
del form.fields["caution_check"] del form.fields["deposit_check"]
# S'assurer que le champ caution_type est obligatoire pour les 2A+ # S'assurer que le champ deposit_type est obligatoire pour les 2A+
if not self.object.first_year and "caution_type" in form.fields: if not self.object.first_year and "deposit_type" in form.fields:
form.fields["caution_type"].required = True form.fields["deposit_type"].required = True
form.fields["caution_type"].help_text = _("Choose how you want to pay the deposit") form.fields["deposit_type"].help_text = _("Choose how you want to pay the deposit")
form.fields["caution_type"].widget = forms.RadioSelect(choices=form.fields["caution_type"].choices)
return form return form
@ -845,8 +880,8 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update
form.instance.information = information form.instance.information = information
# Sauvegarder le type de caution pour les 2A+ # Sauvegarder le type de caution pour les 2A+
if "caution_type" in form.cleaned_data: if "deposit_type" in form.cleaned_data:
form.instance.caution_type = form.cleaned_data["caution_type"] form.instance.deposit_type = form.cleaned_data["deposit_type"]
form.instance.save() form.instance.save()
return super().form_valid(form) return super().form_valid(form)
@ -857,9 +892,6 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update
survey = CurrentSurvey(self.object) survey = CurrentSurvey(self.object)
if not survey.is_complete(): if not survey.is_complete():
return reverse_lazy("wei:wei_survey", kwargs={"pk": self.object.pk}) return reverse_lazy("wei:wei_survey", kwargs={"pk": self.object.pk})
# On redirige vers la validation uniquement si c'est explicitement demandé (et stocké dans la vue)
if self.should_validate and self.request.user.has_perm("wei.add_weimembership"):
return reverse_lazy("wei:validate_registration", kwargs={"pk": self.object.pk})
return reverse_lazy("wei:wei_detail", kwargs={"pk": self.object.wei.pk}) return reverse_lazy("wei:wei_detail", kwargs={"pk": self.object.wei.pk})
@ -952,15 +984,15 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView):
# Calculer le montant total nécessaire (frais + caution si transaction) # Calculer le montant total nécessaire (frais + caution si transaction)
total_needed = fee total_needed = fee
if registration.caution_type == 'note': if registration.deposit_type == 'note':
total_needed += registration.wei.caution_amount total_needed += registration.wei.deposit_amount
context["total_needed"] = total_needed context["total_needed"] = total_needed
form = context["form"] form = context["form"]
if registration.soge_credit: if registration.soge_credit:
form.fields["credit_amount"].initial = registration.fee form.fields["credit_amount"].initial = fee
else: else:
form.fields["credit_amount"].initial = max(0, registration.fee - registration.user.note.balance) form.fields["credit_amount"].initial = max(0, fee - registration.user.note.balance)
return context return context
@ -983,34 +1015,25 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView):
form.fields["last_name"].initial = registration.user.last_name form.fields["last_name"].initial = registration.user.last_name
form.fields["first_name"].initial = registration.user.first_name form.fields["first_name"].initial = registration.user.first_name
# Ajouter le champ caution_check uniquement pour les non-première année et le rendre obligatoire # Ajouter le champ deposit_check uniquement pour les non-première année et le rendre obligatoire
if not registration.first_year: if not registration.first_year:
if registration.caution_type == 'check': if registration.deposit_type == 'check':
form.fields["caution_check"] = forms.BooleanField( form.fields["deposit_check"] = forms.BooleanField(
required=True, required=True,
initial=registration.caution_check, initial=registration.deposit_check,
label=_("Caution check given"), label=_("Deposit check given"),
help_text=_("Please make sure the check is given before validating the registration") help_text=_("Please make sure the check is given before validating the registration")
) )
else: else:
form.fields["caution_check"] = forms.BooleanField( form.fields["deposit_check"] = forms.BooleanField(
required=True, required=True,
initial=False, initial=False,
label=_("Create deposit transaction"), label=_("Create deposit transaction"),
help_text=_("A transaction of %(amount).2f€ will be created from the user's Note account") % { help_text=_("A transaction of %(amount).2f€ will be created from the user's Note account") % {
'amount': registration.wei.caution_amount / 100 'amount': registration.wei.deposit_amount / 100
} }
) )
if registration.soge_credit:
form.fields["credit_type"].disabled = True
form.fields["credit_type"].initial = NoteSpecial.objects.get(special_type="Virement bancaire")
form.fields["credit_amount"].disabled = True
form.fields["last_name"].disabled = True
form.fields["first_name"].disabled = True
form.fields["bank"].disabled = True
form.fields["bank"].initial = "Société générale"
if 'bus' in form.fields: if 'bus' in form.fields:
# For 2A+ and hardcoded 1A # For 2A+ and hardcoded 1A
form.fields["bus"].widget.attrs["api_url"] = "/api/wei/bus/?wei=" + str(registration.wei.pk) form.fields["bus"].widget.attrs["api_url"] = "/api/wei/bus/?wei=" + str(registration.wei.pk)
@ -1043,8 +1066,8 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView):
club = registration.wei club = registration.wei
user = registration.user user = registration.user
if "caution_check" in form.data: if "deposit_check" in form.data:
registration.caution_check = form.data["caution_check"] == "on" registration.deposit_check = form.data["deposit_check"] == "on"
registration.save() registration.save()
membership = form.instance membership = form.instance
membership.user = user membership.user = user
@ -1055,6 +1078,8 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView):
membership._force_renew_parent = True membership._force_renew_parent = True
fee = club.membership_fee_paid if user.profile.paid else club.membership_fee_unpaid fee = club.membership_fee_paid if user.profile.paid else club.membership_fee_unpaid
if registration.soge_credit:
fee = registration.wei.fee_soge_credit
kfet = club.parent_club kfet = club.parent_club
bde = kfet.parent_club bde = kfet.parent_club
@ -1081,16 +1106,16 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView):
first_name = form.cleaned_data["first_name"] first_name = form.cleaned_data["first_name"]
bank = form.cleaned_data["bank"] bank = form.cleaned_data["bank"]
if credit_type is None or registration.soge_credit: if credit_type is None:
credit_amount = 0 credit_amount = 0
# Calculer le montant total nécessaire (frais + caution si transaction) # Calculer le montant total nécessaire (frais + caution si transaction)
total_needed = fee total_needed = fee
if registration.caution_type == 'note': if registration.deposit_type == 'note':
total_needed += club.caution_amount total_needed += club.deposit_amount
# Vérifier que l'utilisateur a assez d'argent pour tout payer # Vérifier que l'utilisateur a assez d'argent pour tout payer
if not registration.soge_credit and user.note.balance + credit_amount < total_needed: if user.note.balance + credit_amount < total_needed:
form.add_error('credit_type', form.add_error('credit_type',
_("This user doesn't have enough money to join this club and pay the deposit. " _("This user doesn't have enough money to join this club and pay the deposit. "
"Current balance: %(balance)d€, credit: %(credit)d€, needed: %(needed)d") % { "Current balance: %(balance)d€, credit: %(credit)d€, needed: %(needed)d") % {
@ -1138,14 +1163,14 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView):
membership.roles.add(WEIRole.objects.get(name="Adhérent⋅e WEI")) membership.roles.add(WEIRole.objects.get(name="Adhérent⋅e WEI"))
# Créer la transaction de caution si nécessaire # Créer la transaction de caution si nécessaire
if registration.caution_type == 'note': if registration.deposit_type == 'note':
from note.models import Transaction from note.models import Transaction
Transaction.objects.create( Transaction.objects.create(
source=user.note, source=user.note,
destination=club.note, destination=club.note,
quantity=1, quantity=1,
amount=club.caution_amount, amount=club.deposit_amount,
reason=_("Caution %(name)s") % {'name': club.name}, reason=_("Deposit %(name)s") % {'name': club.name},
valid=True, valid=True,
) )

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-06-20 14:02+0200\n" "POT-Creation-Date: 2025-07-15 18:18+0200\n"
"PO-Revision-Date: 2022-04-11 23:12+0200\n" "PO-Revision-Date: 2022-04-11 23:12+0200\n"
"Last-Translator: bleizi <bleizi@crans.org>\n" "Last-Translator: bleizi <bleizi@crans.org>\n"
"Language-Team: \n" "Language-Team: \n"
@ -65,7 +65,7 @@ msgstr "Usted no puede invitar más de 3 persona a esta actividad."
#: apps/note/models/transactions.py:46 apps/note/models/transactions.py:299 #: apps/note/models/transactions.py:46 apps/note/models/transactions.py:299
#: apps/permission/models.py:329 #: apps/permission/models.py:329
#: apps/registration/templates/registration/future_profile_detail.html:16 #: apps/registration/templates/registration/future_profile_detail.html:16
#: apps/wei/models.py:72 apps/wei/models.py:145 apps/wei/tables.py:282 #: apps/wei/models.py:77 apps/wei/models.py:150 apps/wei/tables.py:282
#: apps/wei/templates/wei/base.html:26 #: apps/wei/templates/wei/base.html:26
#: apps/wei/templates/wei/weimembership_form.html:14 apps/wrapped/models.py:16 #: apps/wei/templates/wei/weimembership_form.html:14 apps/wrapped/models.py:16
msgid "name" msgid "name"
@ -100,7 +100,7 @@ msgstr "tipos de actividad"
#: apps/activity/models.py:68 #: apps/activity/models.py:68
#: apps/activity/templates/activity/includes/activity_info.html:19 #: apps/activity/templates/activity/includes/activity_info.html:19
#: apps/note/models/transactions.py:82 apps/permission/models.py:109 #: apps/note/models/transactions.py:82 apps/permission/models.py:109
#: apps/permission/models.py:188 apps/wei/models.py:92 apps/wei/models.py:156 #: apps/permission/models.py:188 apps/wei/models.py:97 apps/wei/models.py:161
msgid "description" msgid "description"
msgstr "descripción" msgstr "descripción"
@ -121,7 +121,7 @@ msgstr "tipo"
#: apps/activity/models.py:91 apps/logs/models.py:22 apps/member/models.py:325 #: apps/activity/models.py:91 apps/logs/models.py:22 apps/member/models.py:325
#: apps/note/models/notes.py:148 apps/treasury/models.py:294 #: apps/note/models/notes.py:148 apps/treasury/models.py:294
#: apps/wei/models.py:185 apps/wei/templates/wei/attribute_bus_1A.html:13 #: apps/wei/models.py:190 apps/wei/templates/wei/attribute_bus_1A.html:13
#: apps/wei/templates/wei/survey.html:15 #: apps/wei/templates/wei/survey.html:15
msgid "user" msgid "user"
msgstr "usuario" msgstr "usuario"
@ -1297,7 +1297,7 @@ msgid "add to registration form"
msgstr "Validar la afiliación" msgstr "Validar la afiliación"
#: apps/member/models.py:268 apps/member/models.py:331 #: apps/member/models.py:268 apps/member/models.py:331
#: apps/note/models/notes.py:176 apps/wei/models.py:86 #: apps/note/models/notes.py:176 apps/wei/models.py:91
msgid "club" msgid "club"
msgstr "club" msgstr "club"
@ -2017,8 +2017,8 @@ msgstr ""
"pago y un usuario o un club" "pago y un usuario o un club"
#: apps/note/models/transactions.py:357 apps/note/models/transactions.py:360 #: apps/note/models/transactions.py:357 apps/note/models/transactions.py:360
#: apps/note/models/transactions.py:363 apps/wei/views.py:1097 #: apps/note/models/transactions.py:363 apps/wei/views.py:1103
#: apps/wei/views.py:1101 #: apps/wei/views.py:1107
msgid "This field is required." msgid "This field is required."
msgstr "Este campo es obligatorio." msgstr "Este campo es obligatorio."
@ -2515,7 +2515,7 @@ msgstr "El usuario declara que ya abrió una cuenta a la Société Générale."
#: apps/registration/templates/registration/future_profile_detail.html:73 #: apps/registration/templates/registration/future_profile_detail.html:73
#: apps/wei/templates/wei/weimembership_form.html:127 #: apps/wei/templates/wei/weimembership_form.html:127
#: apps/wei/templates/wei/weimembership_form.html:196 #: apps/wei/templates/wei/weimembership_form.html:192
msgid "Validate registration" msgid "Validate registration"
msgstr "Validar la afiliación" msgstr "Validar la afiliación"
@ -3043,8 +3043,8 @@ msgstr "Lista de los créditos de la Société Générale"
msgid "Manage credits from the Société générale" msgid "Manage credits from the Société générale"
msgstr "Gestionar los créditos de la Société Générale" msgstr "Gestionar los créditos de la Société Générale"
#: apps/wei/apps.py:10 apps/wei/models.py:42 apps/wei/models.py:43 #: apps/wei/apps.py:10 apps/wei/models.py:47 apps/wei/models.py:48
#: apps/wei/models.py:67 apps/wei/models.py:192 #: apps/wei/models.py:72 apps/wei/models.py:197
#: note_kfet/templates/base.html:108 #: note_kfet/templates/base.html:108
msgid "WEI" msgid "WEI"
msgstr "WEI" msgstr "WEI"
@ -3054,8 +3054,8 @@ msgid "The selected user is not validated. Please validate its account first"
msgstr "" msgstr ""
"El usuario seleccionado no ha sido validado. Validar esta cuenta primero" "El usuario seleccionado no ha sido validado. Validar esta cuenta primero"
#: apps/wei/forms/registration.py:84 apps/wei/models.py:140 #: apps/wei/forms/registration.py:84 apps/wei/models.py:145
#: apps/wei/models.py:348 #: apps/wei/models.py:354
msgid "bus" msgid "bus"
msgstr "bus" msgstr "bus"
@ -3081,7 +3081,7 @@ msgstr ""
"electrón libre)" "electrón libre)"
#: apps/wei/forms/registration.py:100 apps/wei/forms/registration.py:110 #: apps/wei/forms/registration.py:100 apps/wei/forms/registration.py:110
#: apps/wei/models.py:174 #: apps/wei/models.py:179
msgid "WEI Roles" msgid "WEI Roles"
msgstr "Papeles en el WEI" msgstr "Papeles en el WEI"
@ -3089,14 +3089,19 @@ msgstr "Papeles en el WEI"
msgid "Select the roles that you are interested in." msgid "Select the roles that you are interested in."
msgstr "Elegir los papeles que le interesa." msgstr "Elegir los papeles que le interesa."
#: apps/wei/forms/registration.py:147 #: apps/wei/forms/registration.py:160
msgid "This team doesn't belong to the given bus." msgid "This team doesn't belong to the given bus."
msgstr "Este equipo no pertenece al bus dado." msgstr "Este equipo no pertenece al bus dado."
#: apps/wei/forms/surveys/wei2021.py:35 apps/wei/forms/surveys/wei2022.py:38 #: apps/wei/forms/surveys/wei2021.py:35 apps/wei/forms/surveys/wei2022.py:38
#: apps/wei/forms/surveys/wei2025.py:36
msgid "Choose a word:" msgid "Choose a word:"
msgstr "Elegir una palabra :" msgstr "Elegir una palabra :"
#: apps/wei/forms/surveys/wei2025.py:123
msgid "Rate between 0 and 5."
msgstr ""
#: apps/wei/models.py:25 apps/wei/templates/wei/base.html:36 #: apps/wei/models.py:25 apps/wei/templates/wei/base.html:36
msgid "year" msgid "year"
msgstr "año" msgstr "año"
@ -3113,138 +3118,147 @@ msgstr "fecha de fin"
#: apps/wei/models.py:37 #: apps/wei/models.py:37
#, fuzzy #, fuzzy
#| msgid "total amount" #| msgid "Credit amount"
msgid "caution amount" msgid "deposit amount"
msgstr "monto total" msgstr "Valor del crédito"
#: apps/wei/models.py:76 apps/wei/tables.py:305 #: apps/wei/models.py:42
#, fuzzy
#| msgid "No credit"
msgid "membership fee (soge credit)"
msgstr "No crédito"
#: apps/wei/models.py:81 apps/wei/tables.py:305
msgid "seat count in the bus" msgid "seat count in the bus"
msgstr "cantidad de asientos en el bus" msgstr "cantidad de asientos en el bus"
#: apps/wei/models.py:97 #: apps/wei/models.py:102
msgid "survey information" msgid "survey information"
msgstr "informaciones sobre el cuestionario" msgstr "informaciones sobre el cuestionario"
#: apps/wei/models.py:98 #: apps/wei/models.py:103
msgid "Information about the survey for new members, encoded in JSON" msgid "Information about the survey for new members, encoded in JSON"
msgstr "" msgstr ""
"Informaciones sobre el cuestionario para los nuevos miembros, registrado en " "Informaciones sobre el cuestionario para los nuevos miembros, registrado en "
"JSON" "JSON"
#: apps/wei/models.py:102 #: apps/wei/models.py:107
msgid "Bus" msgid "Bus"
msgstr "Bus" msgstr "Bus"
#: apps/wei/models.py:103 apps/wei/templates/wei/weiclub_detail.html:51 #: apps/wei/models.py:108 apps/wei/templates/wei/weiclub_detail.html:51
msgid "Buses" msgid "Buses"
msgstr "Bus" msgstr "Bus"
#: apps/wei/models.py:149 #: apps/wei/models.py:154
msgid "color" msgid "color"
msgstr "color" msgstr "color"
#: apps/wei/models.py:150 #: apps/wei/models.py:155
msgid "The color of the T-Shirt, stored with its number equivalent" msgid "The color of the T-Shirt, stored with its number equivalent"
msgstr "El color de la camiseta, registrado con su número equivalente" msgstr "El color de la camiseta, registrado con su número equivalente"
#: apps/wei/models.py:161 #: apps/wei/models.py:166
msgid "Bus team" msgid "Bus team"
msgstr "Equipo de bus" msgstr "Equipo de bus"
#: apps/wei/models.py:162 #: apps/wei/models.py:167
msgid "Bus teams" msgid "Bus teams"
msgstr "Equipos de bus" msgstr "Equipos de bus"
#: apps/wei/models.py:173 #: apps/wei/models.py:178
msgid "WEI Role" msgid "WEI Role"
msgstr "Papeles en el WEI" msgstr "Papeles en el WEI"
#: apps/wei/models.py:197 #: apps/wei/models.py:202
msgid "Credit from Société générale" msgid "Credit from Société générale"
msgstr "Crédito de la Société Générale" msgstr "Crédito de la Société Générale"
#: apps/wei/models.py:202 apps/wei/views.py:984 #: apps/wei/models.py:207 apps/wei/templates/wei/weimembership_form.html:98
msgid "Caution check given" #: apps/wei/views.py:997
#, fuzzy
#| msgid "Caution check given"
msgid "Deposit check given"
msgstr "Cheque de garantía dado" msgstr "Cheque de garantía dado"
#: apps/wei/models.py:208 #: apps/wei/models.py:213
msgid "Check" msgid "Check"
msgstr "" msgstr ""
#: apps/wei/models.py:209 #: apps/wei/models.py:214
#, fuzzy #, fuzzy
#| msgid "transactions" #| msgid "transactions"
msgid "Note transaction" msgid "Note transaction"
msgstr "Transacción" msgstr "Transacción"
#: apps/wei/models.py:212 #: apps/wei/models.py:217
#, fuzzy #, fuzzy
#| msgid "created at" #| msgid "Credit type"
msgid "caution type" msgid "deposit type"
msgstr "tipo de fianza" msgstr "Tipo de crédito"
#: apps/wei/models.py:216 apps/wei/templates/wei/weimembership_form.html:64 #: apps/wei/models.py:221 apps/wei/templates/wei/weimembership_form.html:64
msgid "birth date" msgid "birth date"
msgstr "fecha de nacimiento" msgstr "fecha de nacimiento"
#: apps/wei/models.py:222 apps/wei/models.py:232 #: apps/wei/models.py:227 apps/wei/models.py:237
msgid "Male" msgid "Male"
msgstr "Hombre" msgstr "Hombre"
#: apps/wei/models.py:223 apps/wei/models.py:233 #: apps/wei/models.py:228 apps/wei/models.py:238
msgid "Female" msgid "Female"
msgstr "Mujer" msgstr "Mujer"
#: apps/wei/models.py:224 #: apps/wei/models.py:229
msgid "Non binary" msgid "Non binary"
msgstr "No binari@" msgstr "No binari@"
#: apps/wei/models.py:226 apps/wei/templates/wei/attribute_bus_1A.html:22 #: apps/wei/models.py:231 apps/wei/templates/wei/attribute_bus_1A.html:22
#: apps/wei/templates/wei/weimembership_form.html:55 #: apps/wei/templates/wei/weimembership_form.html:55
msgid "gender" msgid "gender"
msgstr "género" msgstr "género"
#: apps/wei/models.py:234 #: apps/wei/models.py:239
msgid "Unisex" msgid "Unisex"
msgstr "Unisex" msgstr "Unisex"
#: apps/wei/models.py:237 apps/wei/templates/wei/weimembership_form.html:58 #: apps/wei/models.py:242 apps/wei/templates/wei/weimembership_form.html:58
msgid "clothing cut" msgid "clothing cut"
msgstr "forma de ropa" msgstr "forma de ropa"
#: apps/wei/models.py:250 apps/wei/templates/wei/weimembership_form.html:61 #: apps/wei/models.py:255 apps/wei/templates/wei/weimembership_form.html:61
msgid "clothing size" msgid "clothing size"
msgstr "medida de ropa" msgstr "medida de ropa"
#: apps/wei/models.py:256 #: apps/wei/models.py:261
msgid "health issues" msgid "health issues"
msgstr "problemas de salud" msgstr "problemas de salud"
#: apps/wei/models.py:261 apps/wei/templates/wei/weimembership_form.html:70 #: apps/wei/models.py:266 apps/wei/templates/wei/weimembership_form.html:70
msgid "emergency contact name" msgid "emergency contact name"
msgstr "nombre del contacto de emergencia" msgstr "nombre del contacto de emergencia"
#: apps/wei/models.py:262 #: apps/wei/models.py:267
msgid "The emergency contact must not be a WEI participant" msgid "The emergency contact must not be a WEI participant"
msgstr "El contacto de emergencia no debe ser un participante de WEI" msgstr "El contacto de emergencia no debe ser un participante de WEI"
#: apps/wei/models.py:267 apps/wei/templates/wei/weimembership_form.html:73 #: apps/wei/models.py:272 apps/wei/templates/wei/weimembership_form.html:73
msgid "emergency contact phone" msgid "emergency contact phone"
msgstr "teléfono del contacto de emergencia" msgstr "teléfono del contacto de emergencia"
#: apps/wei/models.py:272 apps/wei/templates/wei/weimembership_form.html:52 #: apps/wei/models.py:277 apps/wei/templates/wei/weimembership_form.html:52
msgid "first year" msgid "first year"
msgstr "primer año" msgstr "primer año"
#: apps/wei/models.py:273 #: apps/wei/models.py:278
msgid "Tells if the user is new in the school." msgid "Tells if the user is new in the school."
msgstr "Indica si el usuario es nuevo en la escuela." msgstr "Indica si el usuario es nuevo en la escuela."
#: apps/wei/models.py:278 #: apps/wei/models.py:283
msgid "registration information" msgid "registration information"
msgstr "informaciones sobre la afiliación" msgstr "informaciones sobre la afiliación"
#: apps/wei/models.py:279 #: apps/wei/models.py:284
msgid "" msgid ""
"Information about the registration (buses for old members, survey for the " "Information about the registration (buses for old members, survey for the "
"new members), encoded in JSON" "new members), encoded in JSON"
@ -3252,27 +3266,27 @@ msgstr ""
"Informaciones sobre la afiliacion (bus para miembros ancianos, cuestionario " "Informaciones sobre la afiliacion (bus para miembros ancianos, cuestionario "
"para los nuevos miembros), registrado en JSON" "para los nuevos miembros), registrado en JSON"
#: apps/wei/models.py:285 #: apps/wei/models.py:290
msgid "WEI User" msgid "WEI User"
msgstr "Participante WEI" msgstr "Participante WEI"
#: apps/wei/models.py:286 #: apps/wei/models.py:291
msgid "WEI Users" msgid "WEI Users"
msgstr "Participantes WEI" msgstr "Participantes WEI"
#: apps/wei/models.py:358 #: apps/wei/models.py:364
msgid "team" msgid "team"
msgstr "equipo" msgstr "equipo"
#: apps/wei/models.py:368 #: apps/wei/models.py:374
msgid "WEI registration" msgid "WEI registration"
msgstr "Apuntación al WEI" msgstr "Apuntación al WEI"
#: apps/wei/models.py:372 #: apps/wei/models.py:378
msgid "WEI membership" msgid "WEI membership"
msgstr "Afiliación al WEI" msgstr "Afiliación al WEI"
#: apps/wei/models.py:373 #: apps/wei/models.py:379
msgid "WEI memberships" msgid "WEI memberships"
msgstr "Afiliaciones al WEI" msgstr "Afiliaciones al WEI"
@ -3300,7 +3314,7 @@ msgstr "Año"
msgid "preferred bus" msgid "preferred bus"
msgstr "bus preferido" msgstr "bus preferido"
#: apps/wei/tables.py:210 apps/wei/templates/wei/bus_detail.html:36 #: apps/wei/tables.py:210 apps/wei/templates/wei/bus_detail.html:38
#: apps/wei/templates/wei/busteam_detail.html:52 #: apps/wei/templates/wei/busteam_detail.html:52
msgid "Teams" msgid "Teams"
msgstr "Equipos" msgstr "Equipos"
@ -3372,9 +3386,9 @@ msgstr "Pago de entrada del WEI (estudiantes no pagados)"
#: apps/wei/templates/wei/base.html:53 #: apps/wei/templates/wei/base.html:53
#, fuzzy #, fuzzy
#| msgid "total amount" #| msgid "Credit amount"
msgid "Caution amount" msgid "Deposit amount"
msgstr "monto total" msgstr "Valor del crédito"
#: apps/wei/templates/wei/base.html:74 #: apps/wei/templates/wei/base.html:74
msgid "WEI list" msgid "WEI list"
@ -3384,7 +3398,7 @@ msgstr "Lista de los WEI"
msgid "Register 1A" msgid "Register 1A"
msgstr "Apuntar un 1A" msgstr "Apuntar un 1A"
#: apps/wei/templates/wei/base.html:83 apps/wei/views.py:644 #: apps/wei/templates/wei/base.html:83 apps/wei/views.py:646
msgid "Register 2A+" msgid "Register 2A+"
msgstr "Apuntar un 2A+" msgstr "Apuntar un 2A+"
@ -3401,15 +3415,21 @@ msgid "View club"
msgstr "Ver club" msgstr "Ver club"
#: apps/wei/templates/wei/bus_detail.html:26 #: apps/wei/templates/wei/bus_detail.html:26
#, fuzzy
#| msgid "survey information"
msgid "Edit information"
msgstr "informaciones sobre el cuestionario"
#: apps/wei/templates/wei/bus_detail.html:28
#: apps/wei/templates/wei/busteam_detail.html:24 #: apps/wei/templates/wei/busteam_detail.html:24
msgid "Add team" msgid "Add team"
msgstr "Añadir un equipo" msgstr "Añadir un equipo"
#: apps/wei/templates/wei/bus_detail.html:49 #: apps/wei/templates/wei/bus_detail.html:51
msgid "Members" msgid "Members"
msgstr "Miembros" msgstr "Miembros"
#: apps/wei/templates/wei/bus_detail.html:58 #: apps/wei/templates/wei/bus_detail.html:60
#: apps/wei/templates/wei/busteam_detail.html:62 #: apps/wei/templates/wei/busteam_detail.html:62
#: apps/wei/templates/wei/weimembership_list.html:31 #: apps/wei/templates/wei/weimembership_list.html:31
msgid "View as PDF" msgid "View as PDF"
@ -3417,8 +3437,8 @@ msgstr "Descargar un PDF"
#: apps/wei/templates/wei/survey.html:11 #: apps/wei/templates/wei/survey.html:11
#: apps/wei/templates/wei/survey_closed.html:11 #: apps/wei/templates/wei/survey_closed.html:11
#: apps/wei/templates/wei/survey_end.html:11 apps/wei/views.py:1159 #: apps/wei/templates/wei/survey_end.html:11 apps/wei/views.py:1165
#: apps/wei/views.py:1214 apps/wei/views.py:1261 #: apps/wei/views.py:1220 apps/wei/views.py:1267
msgid "Survey WEI" msgid "Survey WEI"
msgstr "Cuestionario WEI" msgstr "Cuestionario WEI"
@ -3494,10 +3514,6 @@ msgstr "Informaciones crudas del cuestionario"
msgid "The algorithm didn't run." msgid "The algorithm didn't run."
msgstr "El algoritmo no funcionó." msgstr "El algoritmo no funcionó."
#: apps/wei/templates/wei/weimembership_form.html:98
msgid "caution check given"
msgstr "cheque de garantía dado"
#: apps/wei/templates/wei/weimembership_form.html:105 #: apps/wei/templates/wei/weimembership_form.html:105
msgid "preferred team" msgid "preferred team"
msgstr "equipo preferido" msgstr "equipo preferido"
@ -3532,11 +3548,18 @@ msgid "with the following roles:"
msgstr "con los papeles :" msgstr "con los papeles :"
#: apps/wei/templates/wei/weimembership_form.html:139 #: apps/wei/templates/wei/weimembership_form.html:139
#, fuzzy
#| msgid ""
#| "The WEI will be paid by Société générale. The membership will be created "
#| "even if the bank didn't pay the BDE yet. The membership transaction will "
#| "be created but will be invalid. You will have to validate it once the "
#| "bank validated the creation of the account, or to change the payment "
#| "method."
msgid "" msgid ""
"The WEI will be paid by Société générale. The membership will be created " "The WEI will partially be paid by Société générale. The membership will be "
"even if the bank didn't pay the BDE yet. The membership transaction will be " "created even if the bank didn't pay the BDE yet. The membership transaction "
"created but will be invalid. You will have to validate it once the bank " "will be created but will be invalid. You will have to validate it once the "
"validated the creation of the account, or to change the payment method." "bank validated the creation of the account, or to change the payment method."
msgstr "" msgstr ""
"El WEI será pagado por la Société Générale. La afiliación será creada aunque " "El WEI será pagado por la Société Générale. La afiliación será creada aunque "
"el banco no pago el BDE ya. La transacción de afiliación será creada pero " "el banco no pago el BDE ya. La transacción de afiliación será creada pero "
@ -3558,27 +3581,26 @@ msgstr "Pagos de afiliación (estudiantes pagados)"
msgid "Deposit (by Note transaction): %(amount)s" msgid "Deposit (by Note transaction): %(amount)s"
msgstr "Fianza (transacción) : %(amount)s" msgstr "Fianza (transacción) : %(amount)s"
#: apps/wei/templates/wei/weimembership_form.html:156 #: apps/wei/templates/wei/weimembership_form.html:157
#: apps/wei/templates/wei/weimembership_form.html:163
#, python-format
msgid "Total needed: %(total)s"
msgstr "Total necesario : %(total)s"
#: apps/wei/templates/wei/weimembership_form.html:160
#, python-format #, python-format
msgid "Deposit (by check): %(amount)s" msgid "Deposit (by check): %(amount)s"
msgstr "Fianza (cheque) : %(amount)s" msgstr "Fianza (cheque) : %(amount)s"
#: apps/wei/templates/wei/weimembership_form.html:168 #: apps/wei/templates/wei/weimembership_form.html:161
#, python-format
msgid "Total needed: %(total)s"
msgstr "Total necesario : %(total)s"
#: apps/wei/templates/wei/weimembership_form.html:165
#, python-format #, python-format
msgid "Current balance: %(balance)s" msgid "Current balance: %(balance)s"
msgstr "Saldo actual : %(balance)s" msgstr "Saldo actual : %(balance)s"
#: apps/wei/templates/wei/weimembership_form.html:176 #: apps/wei/templates/wei/weimembership_form.html:172
msgid "The user didn't give her/his caution check." msgid "The user didn't give her/his caution check."
msgstr "El usuario no dio su cheque de garantía." msgstr "El usuario no dio su cheque de garantía."
#: apps/wei/templates/wei/weimembership_form.html:184 #: apps/wei/templates/wei/weimembership_form.html:180
msgid "" msgid ""
"This user is not a member of the Kfet club for the coming year. The " "This user is not a member of the Kfet club for the coming year. The "
"membership will be processed automatically, the WEI registration includes " "membership will be processed automatically, the WEI registration includes "
@ -3668,110 +3690,109 @@ msgstr "Gestionar el equipo"
msgid "Register first year student to the WEI" msgid "Register first year student to the WEI"
msgstr "Registrar un 1A al WEI" msgstr "Registrar un 1A al WEI"
#: apps/wei/views.py:580 apps/wei/views.py:689 #: apps/wei/views.py:571 apps/wei/views.py:664
#, fuzzy
#| msgid "Check this case if the Société Générale paid the inscription."
msgid "Check if you will open a Société Générale account"
msgstr "Marcar esta casilla si Société Générale pagó la registración."
#: apps/wei/views.py:582 apps/wei/views.py:694
msgid "This user is already registered to this WEI." msgid "This user is already registered to this WEI."
msgstr "Este usuario ya afilió a este WEI." msgstr "Este usuario ya afilió a este WEI."
#: apps/wei/views.py:585 #: apps/wei/views.py:587
msgid "" msgid ""
"This user can't be in her/his first year since he/she has already " "This user can't be in her/his first year since he/she has already "
"participated to a WEI." "participated to a WEI."
msgstr "Este usuario no puede ser un 1A porque ya participó en un WEI." msgstr "Este usuario no puede ser un 1A porque ya participó en un WEI."
#: apps/wei/views.py:608 #: apps/wei/views.py:610
msgid "Register old student to the WEI" msgid "Register old student to the WEI"
msgstr "Registrar un 2A+ al WEI" msgstr "Registrar un 2A+ al WEI"
#: apps/wei/views.py:663 apps/wei/views.py:768 #: apps/wei/views.py:668 apps/wei/views.py:773
msgid "You already opened an account in the Société générale." msgid "You already opened an account in the Société générale."
msgstr "Usted ya abrió una cuenta a la Société Générale." msgstr "Usted ya abrió una cuenta a la Société Générale."
#: apps/wei/views.py:676 apps/wei/views.py:785 #: apps/wei/views.py:681 apps/wei/views.py:790
msgid "Choose how you want to pay the deposit" msgid "Choose how you want to pay the deposit"
msgstr "" msgstr ""
#: apps/wei/views.py:728 #: apps/wei/views.py:733
msgid "Update WEI Registration" msgid "Update WEI Registration"
msgstr "Modificar la inscripción WEI" msgstr "Modificar la inscripción WEI"
#: apps/wei/views.py:810 #: apps/wei/views.py:816
#, fuzzy #, fuzzy
#| msgid "The BDE membership is included in the WEI registration." #| msgid "The BDE membership is included in the WEI registration."
msgid "No membership found for this registration" msgid "No membership found for this registration"
msgstr "La afiliación al BDE esta incluida en la afiliación WEI." msgstr "La afiliación al BDE esta incluida en la afiliación WEI."
#: apps/wei/views.py:819 #: apps/wei/views.py:825
#| msgid ""
#| "You don't have the permission to add an instance of model {app_label}."
#| "{model_name}."
msgid "You don't have the permission to update memberships" msgid "You don't have the permission to update memberships"
msgstr "" msgstr ""
"Usted no tiene permiso a añadir una instancia al modelo {app_label}." "Usted no tiene permiso a añadir una instancia al modelo {app_label}."
"{model_name}." "{model_name}."
#: apps/wei/views.py:825 #: apps/wei/views.py:831
#, python-format #, python-format
#| msgid ""
#| "You don't have the permission to delete this instance of model "
#| "{app_label}.{model_name}."
msgid "You don't have the permission to update the field %(field)s" msgid "You don't have the permission to update the field %(field)s"
msgstr "Usted no tiene permiso a modificar el campo %(field)s" msgstr "Usted no tiene permiso a modificar el campo %(field)s"
#: apps/wei/views.py:870 #: apps/wei/views.py:876
msgid "Delete WEI registration" msgid "Delete WEI registration"
msgstr "Suprimir la inscripción WEI" msgstr "Suprimir la inscripción WEI"
#: apps/wei/views.py:881 #: apps/wei/views.py:887
msgid "You don't have the right to delete this WEI registration." msgid "You don't have the right to delete this WEI registration."
msgstr "Usted no tiene derecho a suprimir esta inscripción WEI." msgstr "Usted no tiene derecho a suprimir esta inscripción WEI."
#: apps/wei/views.py:899 #: apps/wei/views.py:905
msgid "Validate WEI registration" msgid "Validate WEI registration"
msgstr "Validar la inscripción WEI" msgstr "Validar la inscripción WEI"
#: apps/wei/views.py:985 #: apps/wei/views.py:998
msgid "Please make sure the check is given before validating the registration" msgid "Please make sure the check is given before validating the registration"
msgstr "" msgstr ""
"Por favor asegúrese de que el cheque se entrega antes de validar el registro" "Por favor asegúrese de que el cheque se entrega antes de validar el registro"
#: apps/wei/views.py:991 #: apps/wei/views.py:1004
#| msgid "credit transaction"
msgid "Create deposit transaction" msgid "Create deposit transaction"
msgstr "Crear transacción de crédito" msgstr "Crear transacción de crédito"
#: apps/wei/views.py:992 #: apps/wei/views.py:1005
#, python-format #, python-format
msgid "" msgid ""
"A transaction of %(amount).2f€ will be created from the user's Note account" "A transaction of %(amount).2f€ will be created from the user's Note account"
msgstr "" msgstr ""
#: apps/wei/views.py:1087 #: apps/wei/views.py:1093
#, python-format #, fuzzy, python-format
#| msgid "" #| msgid ""
#| "This user don't have enough money to join this club, and can't have a " #| "This user doesn't have enough money. Current balance: %(balance)d€, "
#| "negative balance." #| "credit: %(credit)d€, needed: %(needed)d€"
msgid "" msgid ""
"This user doesn't have enough money. " "This user doesn't have enough money to join this club and pay the deposit. "
"Current balance: %(balance)d€, credit: %(credit)d€, needed: %(needed)d€" "Current balance: %(balance)d€, credit: %(credit)d€, needed: %(needed)d€"
msgstr "" msgstr ""
"Este usuario no tiene suficiente dinero. " "Este usuario no tiene suficiente dinero. Saldo actual : %(balance)d€, "
"Saldo actual : %(balance)d€, crédito: %(credit)d€, requerido: %(needed)d€" "crédito: %(credit)d€, requerido: %(needed)d€"
#: apps/wei/views.py:1140 #: apps/wei/views.py:1146
#, python-format #, fuzzy, python-format
#| msgid "created at" #| msgid "Caution %(name)s"
msgid "Caution %(name)s" msgid "Deposit %(name)s"
msgstr "Fianza %(name)s" msgstr "Fianza %(name)s"
#: apps/wei/views.py:1354 #: apps/wei/views.py:1360
msgid "Attribute buses to first year members" msgid "Attribute buses to first year members"
msgstr "Repartir los primer años en los buses" msgstr "Repartir los primer años en los buses"
#: apps/wei/views.py:1379 #: apps/wei/views.py:1386
msgid "Attribute bus" msgid "Attribute bus"
msgstr "Repartir en un bus" msgstr "Repartir en un bus"
#: apps/wei/views.py:1419 #: apps/wei/views.py:1426
msgid "" msgid ""
"No first year student without a bus found. Either all of them have a bus, or " "No first year student without a bus found. Either all of them have a bus, or "
"none has filled the survey yet." "none has filled the survey yet."
@ -4337,6 +4358,24 @@ msgstr ""
"pagar su afiliación. Tambien tiene que validar su correo electronico con el " "pagar su afiliación. Tambien tiene que validar su correo electronico con el "
"enlace que recibió." "enlace que recibió."
#, fuzzy
#~| msgid "total amount"
#~ msgid "caution amount"
#~ msgstr "monto total"
#, fuzzy
#~| msgid "created at"
#~ msgid "caution type"
#~ msgstr "tipo de fianza"
#, fuzzy
#~| msgid "total amount"
#~ msgid "Caution amount"
#~ msgstr "monto total"
#~ msgid "caution check given"
#~ msgstr "cheque de garantía dado"
#, fuzzy #, fuzzy
#~| msgid "Invitation" #~| msgid "Invitation"
#~ msgid "Syndication" #~ msgid "Syndication"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-06 16:04+0200\n" "POT-Creation-Date: 2025-07-15 18:17+0200\n"
"PO-Revision-Date: 2022-04-11 22:05+0200\n" "PO-Revision-Date: 2022-04-11 22:05+0200\n"
"Last-Translator: bleizi <bleizi@crans.org>\n" "Last-Translator: bleizi <bleizi@crans.org>\n"
"Language-Team: French <http://translate.ynerant.fr/projects/nk20/nk20/fr/>\n" "Language-Team: French <http://translate.ynerant.fr/projects/nk20/nk20/fr/>\n"
@ -66,7 +66,7 @@ msgstr "Vous ne pouvez pas inviter plus de 3 personnes à cette activité."
#: apps/note/models/transactions.py:46 apps/note/models/transactions.py:299 #: apps/note/models/transactions.py:46 apps/note/models/transactions.py:299
#: apps/permission/models.py:329 #: apps/permission/models.py:329
#: apps/registration/templates/registration/future_profile_detail.html:16 #: apps/registration/templates/registration/future_profile_detail.html:16
#: apps/wei/models.py:72 apps/wei/models.py:145 apps/wei/tables.py:282 #: apps/wei/models.py:77 apps/wei/models.py:150 apps/wei/tables.py:282
#: apps/wei/templates/wei/base.html:26 #: apps/wei/templates/wei/base.html:26
#: apps/wei/templates/wei/weimembership_form.html:14 apps/wrapped/models.py:16 #: apps/wei/templates/wei/weimembership_form.html:14 apps/wrapped/models.py:16
msgid "name" msgid "name"
@ -101,7 +101,7 @@ msgstr "types d'activité"
#: apps/activity/models.py:68 #: apps/activity/models.py:68
#: apps/activity/templates/activity/includes/activity_info.html:19 #: apps/activity/templates/activity/includes/activity_info.html:19
#: apps/note/models/transactions.py:82 apps/permission/models.py:109 #: apps/note/models/transactions.py:82 apps/permission/models.py:109
#: apps/permission/models.py:188 apps/wei/models.py:92 apps/wei/models.py:156 #: apps/permission/models.py:188 apps/wei/models.py:97 apps/wei/models.py:161
msgid "description" msgid "description"
msgstr "description" msgstr "description"
@ -122,7 +122,7 @@ msgstr "type"
#: apps/activity/models.py:91 apps/logs/models.py:22 apps/member/models.py:325 #: apps/activity/models.py:91 apps/logs/models.py:22 apps/member/models.py:325
#: apps/note/models/notes.py:148 apps/treasury/models.py:294 #: apps/note/models/notes.py:148 apps/treasury/models.py:294
#: apps/wei/models.py:185 apps/wei/templates/wei/attribute_bus_1A.html:13 #: apps/wei/models.py:190 apps/wei/templates/wei/attribute_bus_1A.html:13
#: apps/wei/templates/wei/survey.html:15 #: apps/wei/templates/wei/survey.html:15
msgid "user" msgid "user"
msgstr "utilisateur⋅rice" msgstr "utilisateur⋅rice"
@ -563,7 +563,7 @@ msgstr "Nom"
#, fuzzy #, fuzzy
#| msgid "QR-code number" #| msgid "QR-code number"
msgid "QR code number" msgid "QR code number"
msgstr "numéro de QR-code" msgstr "Numéro de QR-code"
#: apps/food/models.py:23 #: apps/food/models.py:23
msgid "Allergen" msgid "Allergen"
@ -597,8 +597,8 @@ msgstr "est prêt"
msgid "order" msgid "order"
msgstr "consigne" msgstr "consigne"
#: apps/food/models.py:107 apps/food/views.py:34 #: apps/food/models.py:107 apps/food/views.py:35
#: note_kfet/templates/base.html:73 #: note_kfet/templates/base.html:72
msgid "Food" msgid "Food"
msgstr "Bouffe" msgstr "Bouffe"
@ -657,61 +657,75 @@ msgstr "QR-codes"
#: apps/food/models.py:286 #: apps/food/models.py:286
#: apps/food/templates/food/transformedfood_update.html:24 #: apps/food/templates/food/transformedfood_update.html:24
msgid "QR-code number" msgid "QR-code number"
msgstr "numéro de QR-code" msgstr "Numéro de QR-code"
#: apps/food/templates/food/food_detail.html:19 #: apps/food/templates/food/food_detail.html:22
msgid "Contained in" msgid "Contained in"
msgstr "Contenu dans" msgstr "Contenu dans"
#: apps/food/templates/food/food_detail.html:26 #: apps/food/templates/food/food_detail.html:29
msgid "Contain" msgid "Contain"
msgstr "Contient" msgstr "Contient"
#: apps/food/templates/food/food_detail.html:35 #: apps/food/templates/food/food_detail.html:38
msgid "Update" msgid "Update"
msgstr "Modifier" msgstr "Modifier"
#: apps/food/templates/food/food_detail.html:40 #: apps/food/templates/food/food_detail.html:43
msgid "Add to a meal" msgid "Add to a meal"
msgstr "Ajouter à un plat" msgstr "Ajouter à un plat"
#: apps/food/templates/food/food_detail.html:45 #: apps/food/templates/food/food_detail.html:48
msgid "Manage ingredients" msgid "Manage ingredients"
msgstr "Gérer les ingrédients" msgstr "Gérer les ingrédients"
#: apps/food/templates/food/food_detail.html:49 #: apps/food/templates/food/food_detail.html:52
msgid "Return to the food list" msgid "Return to the food list"
msgstr "Retour à la liste de nourriture" msgstr "Retour à la liste de nourriture"
#: apps/food/templates/food/food_list.html:14 #: apps/food/templates/food/food_list.html:32
msgid "View food"
msgstr "Voir l'aliment"
#: apps/food/templates/food/food_list.html:37
#: note_kfet/templates/base_search.html:15
msgid "Search by attribute such as name..."
msgstr "Chercher par un attribut tel que le nom..."
#: apps/food/templates/food/food_list.html:49
#: note_kfet/templates/base_search.html:23
msgid "There is no results."
msgstr "Il n'y a pas de résultat."
#: apps/food/templates/food/food_list.html:58
msgid "Meal served" msgid "Meal served"
msgstr "Plat servis" msgstr "Plat servis"
#: apps/food/templates/food/food_list.html:19 #: apps/food/templates/food/food_list.html:63
msgid "New meal" msgid "New meal"
msgstr "Nouveau plat" msgstr "Nouveau plat"
#: apps/food/templates/food/food_list.html:28 #: apps/food/templates/food/food_list.html:72
msgid "There is no meal served." msgid "There is no meal served."
msgstr "Il n'y a pas de plat servi." msgstr "Il n'y a pas de plat servi."
#: apps/food/templates/food/food_list.html:35 #: apps/food/templates/food/food_list.html:79
msgid "Free food" msgid "Free food"
msgstr "Open" msgstr "Open"
#: apps/food/templates/food/food_list.html:42 #: apps/food/templates/food/food_list.html:86
msgid "There is no free food." msgid "There is no free food."
msgstr "Il n'y a pas de bouffe en open" msgstr "Il n'y a pas de bouffe en open"
#: apps/food/templates/food/food_list.html:50 #: apps/food/templates/food/food_list.html:94
msgid "Food of your clubs" msgid "Food of your clubs"
msgstr "Bouffe de tes clubs" msgstr "Bouffe de tes clubs"
#: apps/food/templates/food/food_list.html:56 #: apps/food/templates/food/food_list.html:100
msgid "Food of club" msgid "Food of club"
msgstr "Bouffe du club" msgstr "Bouffe du club"
#: apps/food/templates/food/food_list.html:63 #: apps/food/templates/food/food_list.html:107
msgid "Yours club has not food yet." msgid "Yours club has not food yet."
msgstr "Ton club n'a pas de bouffe pour l'instant" msgstr "Ton club n'a pas de bouffe pour l'instant"
@ -785,49 +799,49 @@ msgstr "semaines"
msgid "and" msgid "and"
msgstr "et" msgstr "et"
#: apps/food/views.py:119 #: apps/food/views.py:120
msgid "Add a new QRCode" msgid "Add a new QRCode"
msgstr "Ajouter un nouveau QR-code" msgstr "Ajouter un nouveau QR-code"
#: apps/food/views.py:168 #: apps/food/views.py:169
msgid "Add an aliment" msgid "Add an aliment"
msgstr "Ajouter un nouvel aliment" msgstr "Ajouter un nouvel aliment"
#: apps/food/views.py:236 #: apps/food/views.py:228
msgid "Add a meal" msgid "Add a meal"
msgstr "Ajouter un plat" msgstr "Ajouter un plat"
#: apps/food/views.py:276 #: apps/food/views.py:259
msgid "Manage ingredients of:" msgid "Manage ingredients of:"
msgstr "Gestion des ingrédienrs de :" msgstr "Gestion des ingrédienrs de :"
#: apps/food/views.py:290 apps/food/views.py:298 #: apps/food/views.py:273 apps/food/views.py:281
#, python-brace-format #, python-brace-format
msgid "Fully used in {meal}" msgid "Fully used in {meal}"
msgstr "Aliment entièrement utilisé dans : {meal}" msgstr "Aliment entièrement utilisé dans : {meal}"
#: apps/food/views.py:345 #: apps/food/views.py:320
msgid "Add the ingredient:" msgid "Add the ingredient:"
msgstr "Ajouter l'ingrédient" msgstr "Ajouter l'ingrédient"
#: apps/food/views.py:371 #: apps/food/views.py:346
#, python-brace-format #, python-brace-format
msgid "Food fully used in : {meal.name}" msgid "Food fully used in : {meal.name}"
msgstr "Aliment entièrement utilisé dans : {meal.name}" msgstr "Aliment entièrement utilisé dans : {meal.name}"
#: apps/food/views.py:390 #: apps/food/views.py:365
msgid "Update an aliment" msgid "Update an aliment"
msgstr "Modifier un aliment" msgstr "Modifier un aliment"
#: apps/food/views.py:438 #: apps/food/views.py:413
msgid "Details of:" msgid "Details of:"
msgstr "Détails de :" msgstr "Détails de :"
#: apps/food/views.py:448 apps/treasury/tables.py:149 #: apps/food/views.py:423 apps/treasury/tables.py:149
msgid "Yes" msgid "Yes"
msgstr "Oui" msgstr "Oui"
#: apps/food/views.py:450 apps/member/models.py:99 apps/treasury/tables.py:149 #: apps/food/views.py:425 apps/member/models.py:99 apps/treasury/tables.py:149
msgid "No" msgid "No"
msgstr "Non" msgstr "Non"
@ -1240,7 +1254,7 @@ msgid "add to registration form"
msgstr "ajouter au formulaire d'inscription" msgstr "ajouter au formulaire d'inscription"
#: apps/member/models.py:268 apps/member/models.py:331 #: apps/member/models.py:268 apps/member/models.py:331
#: apps/note/models/notes.py:176 apps/wei/models.py:86 #: apps/note/models/notes.py:176 apps/wei/models.py:91
msgid "club" msgid "club"
msgstr "club" msgstr "club"
@ -1962,8 +1976,8 @@ msgstr ""
"mode de paiement et un⋅e utilisateur⋅rice ou un club" "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:357 apps/note/models/transactions.py:360
#: apps/note/models/transactions.py:363 apps/wei/views.py:1105 #: apps/note/models/transactions.py:363 apps/wei/views.py:1103
#: apps/wei/views.py:1109 #: apps/wei/views.py:1107
msgid "This field is required." msgid "This field is required."
msgstr "Ce champ est requis." msgstr "Ce champ est requis."
@ -2470,7 +2484,7 @@ msgstr ""
#: apps/registration/templates/registration/future_profile_detail.html:73 #: apps/registration/templates/registration/future_profile_detail.html:73
#: apps/wei/templates/wei/weimembership_form.html:127 #: apps/wei/templates/wei/weimembership_form.html:127
#: apps/wei/templates/wei/weimembership_form.html:196 #: apps/wei/templates/wei/weimembership_form.html:192
msgid "Validate registration" msgid "Validate registration"
msgstr "Valider l'inscription" msgstr "Valider l'inscription"
@ -2996,9 +3010,9 @@ msgstr "Liste des crédits de la Société générale"
msgid "Manage credits from the Société générale" msgid "Manage credits from the Société générale"
msgstr "Gérer les crédits de la Société générale" msgstr "Gérer les crédits de la Société générale"
#: apps/wei/apps.py:10 apps/wei/models.py:42 apps/wei/models.py:43 #: apps/wei/apps.py:10 apps/wei/models.py:47 apps/wei/models.py:48
#: apps/wei/models.py:67 apps/wei/models.py:192 #: apps/wei/models.py:72 apps/wei/models.py:197
#: note_kfet/templates/base.html:109 #: note_kfet/templates/base.html:108
msgid "WEI" msgid "WEI"
msgstr "WEI" msgstr "WEI"
@ -3008,8 +3022,8 @@ msgstr ""
"L'utilisateur·rice sélectionné·e n'est pas validé·e. Merci de d'abord " "L'utilisateur·rice sélectionné·e n'est pas validé·e. Merci de d'abord "
"valider son compte" "valider son compte"
#: apps/wei/forms/registration.py:84 apps/wei/models.py:140 #: apps/wei/forms/registration.py:84 apps/wei/models.py:145
#: apps/wei/models.py:348 #: apps/wei/models.py:354
msgid "bus" msgid "bus"
msgstr "bus" msgstr "bus"
@ -3035,7 +3049,7 @@ msgstr ""
"bus ou électron libre)" "bus ou électron libre)"
#: apps/wei/forms/registration.py:100 apps/wei/forms/registration.py:110 #: apps/wei/forms/registration.py:100 apps/wei/forms/registration.py:110
#: apps/wei/models.py:174 #: apps/wei/models.py:179
msgid "WEI Roles" msgid "WEI Roles"
msgstr "Rôles au WEI" msgstr "Rôles au WEI"
@ -3071,137 +3085,142 @@ msgid "date end"
msgstr "fin" msgstr "fin"
#: apps/wei/models.py:37 #: apps/wei/models.py:37
#, fuzzy msgid "deposit amount"
#| msgid "total amount" msgstr "montant de la caution"
msgid "caution amount"
msgstr "montant total"
#: apps/wei/models.py:76 apps/wei/tables.py:305 #: apps/wei/models.py:42
msgid "membership fee (soge credit)"
msgstr "Cotisation pour adhérer (crédit sogé)"
#: apps/wei/models.py:81 apps/wei/tables.py:305
msgid "seat count in the bus" msgid "seat count in the bus"
msgstr "nombre de sièges dans le bus" msgstr "nombre de sièges dans le bus"
#: apps/wei/models.py:97 #: apps/wei/models.py:102
msgid "survey information" msgid "survey information"
msgstr "informations sur le questionnaire" msgstr "informations sur le questionnaire"
#: apps/wei/models.py:98 #: apps/wei/models.py:103
msgid "Information about the survey for new members, encoded in JSON" msgid "Information about the survey for new members, encoded in JSON"
msgstr "" msgstr ""
"Informations sur le sondage pour les nouveaux membres, encodées en JSON" "Informations sur le sondage pour les nouveaux membres, encodées en JSON"
#: apps/wei/models.py:102 #: apps/wei/models.py:107
msgid "Bus" msgid "Bus"
msgstr "Bus" msgstr "Bus"
#: apps/wei/models.py:103 apps/wei/templates/wei/weiclub_detail.html:51 #: apps/wei/models.py:108 apps/wei/templates/wei/weiclub_detail.html:51
msgid "Buses" msgid "Buses"
msgstr "Bus" msgstr "Bus"
#: apps/wei/models.py:149 #: apps/wei/models.py:154
msgid "color" msgid "color"
msgstr "couleur" msgstr "couleur"
#: apps/wei/models.py:150 #: apps/wei/models.py:155
msgid "The color of the T-Shirt, stored with its number equivalent" msgid "The color of the T-Shirt, stored with its number equivalent"
msgstr "" msgstr ""
"La couleur du T-Shirt, stocké sous la forme de son équivalent numérique" "La couleur du T-Shirt, stocké sous la forme de son équivalent numérique"
#: apps/wei/models.py:161 #: apps/wei/models.py:166
msgid "Bus team" msgid "Bus team"
msgstr "Équipe de bus" msgstr "Équipe de bus"
#: apps/wei/models.py:162 #: apps/wei/models.py:167
msgid "Bus teams" msgid "Bus teams"
msgstr "Équipes de bus" msgstr "Équipes de bus"
#: apps/wei/models.py:173 #: apps/wei/models.py:178
msgid "WEI Role" msgid "WEI Role"
msgstr "Rôle au WEI" msgstr "Rôle au WEI"
#: apps/wei/models.py:197 #: apps/wei/models.py:202
msgid "Credit from Société générale" msgid "Credit from Société générale"
msgstr "Crédit de la Société générale" msgstr "Crédit de la Société générale"
#: apps/wei/models.py:202 apps/wei/views.py:992 #: apps/wei/models.py:207 apps/wei/templates/wei/weimembership_form.html:98
msgid "Caution check given" #: apps/wei/views.py:997
msgid "Deposit check given"
msgstr "Chèque de caution donné" msgstr "Chèque de caution donné"
#: apps/wei/models.py:208 #: apps/wei/models.py:213
msgid "Check" msgid "Check"
msgstr "" msgstr "Chèque"
#: apps/wei/models.py:209 #: apps/wei/models.py:214
msgid "Note transaction" msgid "Note transaction"
msgstr "Transaction Note" msgstr "Transaction Note"
#: apps/wei/models.py:212 #: apps/wei/models.py:217
msgid "caution type" #, fuzzy
msgstr "date de création" #| msgid "Credit type"
msgid "deposit type"
msgstr "Type de rechargement"
#: apps/wei/models.py:216 apps/wei/templates/wei/weimembership_form.html:64 #: apps/wei/models.py:221 apps/wei/templates/wei/weimembership_form.html:64
msgid "birth date" msgid "birth date"
msgstr "date de naissance" msgstr "date de naissance"
#: apps/wei/models.py:222 apps/wei/models.py:232 #: apps/wei/models.py:227 apps/wei/models.py:237
msgid "Male" msgid "Male"
msgstr "Homme" msgstr "Homme"
#: apps/wei/models.py:223 apps/wei/models.py:233 #: apps/wei/models.py:228 apps/wei/models.py:238
msgid "Female" msgid "Female"
msgstr "Femme" msgstr "Femme"
#: apps/wei/models.py:224 #: apps/wei/models.py:229
msgid "Non binary" msgid "Non binary"
msgstr "Non-binaire" msgstr "Non-binaire"
#: apps/wei/models.py:226 apps/wei/templates/wei/attribute_bus_1A.html:22 #: apps/wei/models.py:231 apps/wei/templates/wei/attribute_bus_1A.html:22
#: apps/wei/templates/wei/weimembership_form.html:55 #: apps/wei/templates/wei/weimembership_form.html:55
msgid "gender" msgid "gender"
msgstr "genre" msgstr "genre"
#: apps/wei/models.py:234 #: apps/wei/models.py:239
msgid "Unisex" msgid "Unisex"
msgstr "Unisexe" msgstr "Unisexe"
#: apps/wei/models.py:237 apps/wei/templates/wei/weimembership_form.html:58 #: apps/wei/models.py:242 apps/wei/templates/wei/weimembership_form.html:58
msgid "clothing cut" msgid "clothing cut"
msgstr "coupe de vêtement" msgstr "coupe de vêtement"
#: apps/wei/models.py:250 apps/wei/templates/wei/weimembership_form.html:61 #: apps/wei/models.py:255 apps/wei/templates/wei/weimembership_form.html:61
msgid "clothing size" msgid "clothing size"
msgstr "taille de vêtement" msgstr "taille de vêtement"
#: apps/wei/models.py:256 #: apps/wei/models.py:261
msgid "health issues" msgid "health issues"
msgstr "problèmes de santé" msgstr "problèmes de santé"
#: apps/wei/models.py:261 apps/wei/templates/wei/weimembership_form.html:70 #: apps/wei/models.py:266 apps/wei/templates/wei/weimembership_form.html:70
msgid "emergency contact name" msgid "emergency contact name"
msgstr "nom du contact en cas d'urgence" msgstr "nom du contact en cas d'urgence"
#: apps/wei/models.py:262 #: apps/wei/models.py:267
msgid "The emergency contact must not be a WEI participant" msgid "The emergency contact must not be a WEI participant"
msgstr "" msgstr ""
"Le contact en cas d'urgence ne doit pas être une personne qui participe au " "Le contact en cas d'urgence ne doit pas être une personne qui participe au "
"WEI" "WEI"
#: apps/wei/models.py:267 apps/wei/templates/wei/weimembership_form.html:73 #: apps/wei/models.py:272 apps/wei/templates/wei/weimembership_form.html:73
msgid "emergency contact phone" msgid "emergency contact phone"
msgstr "téléphone du contact en cas d'urgence" msgstr "téléphone du contact en cas d'urgence"
#: apps/wei/models.py:272 apps/wei/templates/wei/weimembership_form.html:52 #: apps/wei/models.py:277 apps/wei/templates/wei/weimembership_form.html:52
msgid "first year" msgid "first year"
msgstr "première année" msgstr "première année"
#: apps/wei/models.py:273 #: apps/wei/models.py:278
msgid "Tells if the user is new in the school." msgid "Tells if the user is new in the school."
msgstr "Indique si l'utilisateur⋅rice est nouvelleeau dans l'école." msgstr "Indique si l'utilisateur⋅rice est nouvelleeau dans l'école."
#: apps/wei/models.py:278 #: apps/wei/models.py:283
msgid "registration information" msgid "registration information"
msgstr "informations sur l'inscription" msgstr "informations sur l'inscription"
#: apps/wei/models.py:279 #: apps/wei/models.py:284
msgid "" msgid ""
"Information about the registration (buses for old members, survey for the " "Information about the registration (buses for old members, survey for the "
"new members), encoded in JSON" "new members), encoded in JSON"
@ -3209,27 +3228,27 @@ msgstr ""
"Informations sur l'inscription (bus pour les 2A+, questionnaire pour les " "Informations sur l'inscription (bus pour les 2A+, questionnaire pour les "
"1A), encodées en JSON" "1A), encodées en JSON"
#: apps/wei/models.py:285 #: apps/wei/models.py:290
msgid "WEI User" msgid "WEI User"
msgstr "Participant·e au WEI" msgstr "Participant·e au WEI"
#: apps/wei/models.py:286 #: apps/wei/models.py:291
msgid "WEI Users" msgid "WEI Users"
msgstr "Participant·e·s au WEI" msgstr "Participant·e·s au WEI"
#: apps/wei/models.py:358 #: apps/wei/models.py:364
msgid "team" msgid "team"
msgstr "équipe" msgstr "équipe"
#: apps/wei/models.py:368 #: apps/wei/models.py:374
msgid "WEI registration" msgid "WEI registration"
msgstr "Inscription au WEI" msgstr "Inscription au WEI"
#: apps/wei/models.py:372 #: apps/wei/models.py:378
msgid "WEI membership" msgid "WEI membership"
msgstr "Adhésion au WEI" msgstr "Adhésion au WEI"
#: apps/wei/models.py:373 #: apps/wei/models.py:379
msgid "WEI memberships" msgid "WEI memberships"
msgstr "Adhésions au WEI" msgstr "Adhésions au WEI"
@ -3324,10 +3343,8 @@ msgid "WEI fee (unpaid students)"
msgstr "Prix du WEI (étudiant⋅es)" msgstr "Prix du WEI (étudiant⋅es)"
#: apps/wei/templates/wei/base.html:53 #: apps/wei/templates/wei/base.html:53
#, fuzzy msgid "Deposit amount"
#| msgid "total amount" msgstr "Caution"
msgid "Caution amount"
msgstr "montant total"
#: apps/wei/templates/wei/base.html:74 #: apps/wei/templates/wei/base.html:74
msgid "WEI list" msgid "WEI list"
@ -3337,7 +3354,7 @@ msgstr "Liste des WEI"
msgid "Register 1A" msgid "Register 1A"
msgstr "Inscrire un⋅e 1A" msgstr "Inscrire un⋅e 1A"
#: apps/wei/templates/wei/base.html:83 apps/wei/views.py:644 #: apps/wei/templates/wei/base.html:83 apps/wei/views.py:646
msgid "Register 2A+" msgid "Register 2A+"
msgstr "Inscrire un⋅e 2A+" msgstr "Inscrire un⋅e 2A+"
@ -3374,8 +3391,8 @@ msgstr "Télécharger au format PDF"
#: apps/wei/templates/wei/survey.html:11 #: apps/wei/templates/wei/survey.html:11
#: apps/wei/templates/wei/survey_closed.html:11 #: apps/wei/templates/wei/survey_closed.html:11
#: apps/wei/templates/wei/survey_end.html:11 apps/wei/views.py:1167 #: apps/wei/templates/wei/survey_end.html:11 apps/wei/views.py:1165
#: apps/wei/views.py:1222 apps/wei/views.py:1269 #: apps/wei/views.py:1220 apps/wei/views.py:1267
msgid "Survey WEI" msgid "Survey WEI"
msgstr "Questionnaire WEI" msgstr "Questionnaire WEI"
@ -3452,10 +3469,6 @@ msgstr "Informations brutes du sondage"
msgid "The algorithm didn't run." msgid "The algorithm didn't run."
msgstr "L'algorithme n'a pas été exécuté." msgstr "L'algorithme n'a pas été exécuté."
#: apps/wei/templates/wei/weimembership_form.html:98
msgid "caution check given"
msgstr "chèque de caution donné"
#: apps/wei/templates/wei/weimembership_form.html:105 #: apps/wei/templates/wei/weimembership_form.html:105
msgid "preferred team" msgid "preferred team"
msgstr "équipe préférée" msgstr "équipe préférée"
@ -3491,52 +3504,53 @@ msgstr "avec les rôles suivants :"
#: apps/wei/templates/wei/weimembership_form.html:139 #: apps/wei/templates/wei/weimembership_form.html:139
msgid "" msgid ""
"The WEI will be paid by Société générale. The membership will be created " "The WEI will partially be paid by Société générale. The membership will be "
"even if the bank didn't pay the BDE yet. The membership transaction will be " "created even if the bank didn't pay the BDE yet. The membership transaction "
"created but will be invalid. You will have to validate it once the bank " "will be created but will be invalid. You will have to validate it once the "
"validated the creation of the account, or to change the payment method." "bank validated the creation of the account, or to change the payment method."
msgstr "" msgstr ""
"Le WEI va être payé par la Société générale. L'adhésion sera créée même si " "Le WEI va être partiellement payé par la Société générale. L'adhésion sera "
"la banque n'a pas encore payé le BDE. La transaction d'adhésion sera créée " "créée même si la banque n'a pas encore payé le BDE. La transaction "
"mais invalide. Vous devrez la valider une fois que la banque aura validé la " "d'adhésion sera créée mais invalide. Vous devrez la valider une fois que la "
"création du compte, ou bien changer de moyen de paiement." "banque aura validé la création du compte, ou bien changer de moyen de "
"paiement."
#: apps/wei/templates/wei/weimembership_form.html:147 #: apps/wei/templates/wei/weimembership_form.html:147
msgid "Required payments:" msgid "Required payments:"
msgstr "Paiements requis" msgstr "Paiements requis"
#: apps/wei/templates/wei/weimembership_form.html:149 #: apps/wei/templates/wei/weimembership_form.html:149
#, fuzzy, python-format #, python-format
#| msgid "membership fee (paid students)"
msgid "Membership fees: %(amount)s" msgid "Membership fees: %(amount)s"
msgstr "cotisation pour adhérer (normalien·ne élève)" msgstr "Frais d'inscription : %(amount)s"
#: apps/wei/templates/wei/weimembership_form.html:153 #: apps/wei/templates/wei/weimembership_form.html:153
#, python-format #, python-format
msgid "Deposit (by Note transaction): %(amount)s" msgid "Deposit (by Note transaction): %(amount)s"
msgstr "Caution (par transaction) : %(amount)s" msgstr "Caution (par transaction) : %(amount)s"
#: apps/wei/templates/wei/weimembership_form.html:156 #: apps/wei/templates/wei/weimembership_form.html:157
#: apps/wei/templates/wei/weimembership_form.html:163
#, python-format
msgid "Total needed: %(total)s"
msgstr "Total nécessaire : %(total)s"
#: apps/wei/templates/wei/weimembership_form.html:160
#, python-format #, python-format
msgid "Deposit (by check): %(amount)s" msgid "Deposit (by check): %(amount)s"
msgstr "Caution (par chèque) : %(amount)s" msgstr "Caution (par chèque) : %(amount)s"
#: apps/wei/templates/wei/weimembership_form.html:168 #: apps/wei/templates/wei/weimembership_form.html:161
#, python-format
msgid "Total needed: %(total)s"
msgstr "Total nécessaire : %(total)s"
#: apps/wei/templates/wei/weimembership_form.html:165
#, python-format #, python-format
msgid "Current balance: %(balance)s" msgid "Current balance: %(balance)s"
msgstr "Solde actuel : %(balance)s" msgstr "Solde actuel : %(balance)s"
#: apps/wei/templates/wei/weimembership_form.html:176 #: apps/wei/templates/wei/weimembership_form.html:172
#, fuzzy
#| msgid "The user didn't give her/his deposit check."
msgid "The user didn't give her/his caution check." msgid "The user didn't give her/his caution check."
msgstr "L'utilisateur⋅rice n'a pas donné son chèque de caution." msgstr "L'utilisateur⋅rice n'a pas donné son chèque de caution."
#: apps/wei/templates/wei/weimembership_form.html:184 #: apps/wei/templates/wei/weimembership_form.html:180
msgid "" msgid ""
"This user is not a member of the Kfet club for the coming year. The " "This user is not a member of the Kfet club for the coming year. The "
"membership will be processed automatically, the WEI registration includes " "membership will be processed automatically, the WEI registration includes "
@ -3627,11 +3641,15 @@ msgstr "Gérer l'équipe WEI"
msgid "Register first year student to the WEI" msgid "Register first year student to the WEI"
msgstr "Inscrire un⋅e 1A au WEI" msgstr "Inscrire un⋅e 1A au WEI"
#: apps/wei/views.py:580 apps/wei/views.py:689 #: apps/wei/views.py:571 apps/wei/views.py:664
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:582 apps/wei/views.py:694
msgid "This user is already registered to this WEI." msgid "This user is already registered to this WEI."
msgstr "Cette personne est déjà inscrite au WEI." msgstr "Cette personne est déjà inscrite au WEI."
#: apps/wei/views.py:585 #: apps/wei/views.py:587
msgid "" msgid ""
"This user can't be in her/his first year since he/she has already " "This user can't be in her/his first year since he/she has already "
"participated to a WEI." "participated to a WEI."
@ -3639,95 +3657,94 @@ msgstr ""
"Cet⋅te utilisateur⋅rice ne peut pas être en première année puisqu'iel a déjà " "Cet⋅te utilisateur⋅rice ne peut pas être en première année puisqu'iel a déjà "
"participé à un WEI." "participé à un WEI."
#: apps/wei/views.py:608 #: apps/wei/views.py:610
msgid "Register old student to the WEI" msgid "Register old student to the WEI"
msgstr "Inscrire un⋅e 2A+ au WEI" msgstr "Inscrire un⋅e 2A+ au WEI"
#: apps/wei/views.py:663 apps/wei/views.py:768 #: apps/wei/views.py:668 apps/wei/views.py:773
msgid "You already opened an account in the Société générale." 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." msgstr "Vous avez déjà ouvert un compte auprès de la société générale."
#: apps/wei/views.py:676 apps/wei/views.py:785 #: apps/wei/views.py:681 apps/wei/views.py:790
msgid "Choose how you want to pay the deposit" msgid "Choose how you want to pay the deposit"
msgstr "" msgstr "Choisissez comment payer la caution"
#: apps/wei/views.py:728 #: apps/wei/views.py:733
msgid "Update WEI Registration" msgid "Update WEI Registration"
msgstr "Modifier l'inscription WEI" msgstr "Modifier l'inscription WEI"
#: apps/wei/views.py:811 #: apps/wei/views.py:816
msgid "No membership found for this registration" msgid "No membership found for this registration"
msgstr "Pas d'adhésion trouvée pour cette inscription" msgstr "Pas d'adhésion trouvée pour cette inscription"
#: apps/wei/views.py:820 #: apps/wei/views.py:825
msgid "You don't have the permission to update memberships" msgid "You don't have the permission to update memberships"
msgstr "" msgstr "Vous n'avez pas la permission de modifier une inscription"
"Vous n'avez pas la permission d'ajouter une instance du modèle {app_label}."
"{model_name}."
#: apps/wei/views.py:826 #: apps/wei/views.py:831
#, python-format #, python-format
msgid "You don't have the permission to update the field %(field)s" 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" msgstr "Vous n'avez pas la permission de modifier le champ %(field)s"
#: apps/wei/views.py:871 #: apps/wei/views.py:876
msgid "Delete WEI registration" msgid "Delete WEI registration"
msgstr "Supprimer l'inscription WEI" msgstr "Supprimer l'inscription WEI"
#: apps/wei/views.py:882 #: apps/wei/views.py:887
msgid "You don't have the right to delete this WEI registration." 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." msgstr "Vous n'avez pas la permission de supprimer cette inscription au WEI."
#: apps/wei/views.py:900 #: apps/wei/views.py:905
msgid "Validate WEI registration" msgid "Validate WEI registration"
msgstr "Valider l'inscription WEI" msgstr "Valider l'inscription WEI"
#: apps/wei/views.py:993 #: apps/wei/views.py:998
msgid "Please make sure the check is given before validating the registration" msgid "Please make sure the check is given before validating the registration"
msgstr "" msgstr ""
"Merci de vous assurer que le chèque a bien été donné avant de valider " "Merci de vous assurer que le chèque a bien été donné avant de valider "
"l'adhésion" "l'adhésion"
#: apps/wei/views.py:999 #: apps/wei/views.py:1004
msgid "Create deposit transaction" msgid "Create deposit transaction"
msgstr "Créer une transaction de caution" msgstr "Créer une transaction de caution"
#: apps/wei/views.py:1000 #: apps/wei/views.py:1005
#, python-format #, python-format
msgid "" msgid ""
"A transaction of %(amount).2f€ will be created from the user's Note account" "A transaction of %(amount).2f€ will be created from the user's Note account"
msgstr "" msgstr ""
"Un transaction de %(amount).2f€ va être créée depuis la note de l'utilisateur" "Un transaction de %(amount).2f€ va être créée depuis la note de l'utilisateur"
#: apps/wei/views.py:1095 #: apps/wei/views.py:1093
#, python-format #, python-format
msgid "" msgid ""
"This user doesn't have enough money to join this club and pay the deposit. " "This user doesn't have enough money to join this club and pay the deposit. "
"Current balance: %(balance)d€, credit: %(credit)d€, needed: %(needed)d€" "Current balance: %(balance)d€, credit: %(credit)d€, needed: %(needed)d€"
msgstr "" msgstr ""
"Cet⋅te utilisateur⋅rice n'a pas assez d'argent pour rejoindre ce club et " "Cet⋅te utilisateur⋅rice n'a pas assez d'argent pour rejoindre ce club et "
"payer la cautionSolde actuel : %(balance)d€, crédit : %(credit)d€, requis : " "payer la caution. Solde actuel : %(balance)d€, crédit : %(credit)d€, "
"%(needed)d€" "requis : %(needed)d€"
#: apps/wei/views.py:1148 #: apps/wei/views.py:1146
#, fuzzy, python-format #, python-format
#| msgid "total amount" msgid "Deposit %(name)s"
msgid "Caution %(name)s" msgstr "Caution %(name)s"
msgstr "montant total"
#: apps/wei/views.py:1362 #: apps/wei/views.py:1360
msgid "Attribute buses to first year members" msgid "Attribute buses to first year members"
msgstr "Répartir les 1A dans les bus" msgstr "Répartir les 1A dans les bus"
#: apps/wei/views.py:1388 #: apps/wei/views.py:1386
msgid "Attribute bus" msgid "Attribute bus"
msgstr "Attribuer un bus" msgstr "Attribuer un bus"
#: apps/wei/views.py:1428 #: apps/wei/views.py:1426
msgid "" msgid ""
"No first year student without a bus found. Either all of them have a bus, or " "No first year student without a bus found. Either all of them have a bus, or "
"none has filled the survey yet." "none has filled the survey yet."
msgstr "" msgstr ""
"Aucun 1A sans bus trouvé. Soit ils ont tous été attribués, soitaucun n'a "
"encore rempli le sondage."
#: apps/wrapped/apps.py:10 #: apps/wrapped/apps.py:10
msgid "wrapped" msgid "wrapped"
@ -4064,7 +4081,7 @@ msgstr "FAQ (FR)"
#: note_kfet/templates/base.html:222 #: note_kfet/templates/base.html:222
msgid "Managed by BDE" msgid "Managed by BDE"
msgstr "Gérer par le BDE" msgstr "Géré par le BDE"
#: note_kfet/templates/base.html:224 #: note_kfet/templates/base.html:224
msgid "Hosted by Cr@ns" msgid "Hosted by Cr@ns"
@ -4341,9 +4358,20 @@ msgstr ""
"d'adhésion. Vous devez également valider votre adresse email en suivant le " "d'adhésion. Vous devez également valider votre adresse email en suivant le "
"lien que vous avez reçu." "lien que vous avez reçu."
#, fuzzy, python-format #~ msgid "caution amount"
#~| msgid "Creation date" #~ msgstr "montant de la caution"
#~ msgid "Deposit %(name)s"
#~ msgid "caution type"
#~ msgstr "type de caution"
#~ msgid "Caution amount"
#~ msgstr "Montant de la caution"
#~ msgid "caution check given"
#~ msgstr "chèque de caution donné"
#, python-format
#~ msgid "Caution %(name)s"
#~ msgstr "Caution %(name)s" #~ msgstr "Caution %(name)s"
#, fuzzy #, fuzzy
@ -4727,9 +4755,6 @@ msgstr ""
#~ msgid "Application requires the following permissions" #~ msgid "Application requires the following permissions"
#~ msgstr "L'application requiert les permissions suivantes :" #~ msgstr "L'application requiert les permissions suivantes :"
#~ msgid "Deposit amount"
#~ msgstr "Caution"
#~ msgid "The BDE membership is included in the WEI registration." #~ msgid "The BDE membership is included in the WEI registration."
#~ msgstr "L'adhésion au BDE est offerte avec l'inscription au WEI." #~ msgstr "L'adhésion au BDE est offerte avec l'inscription au WEI."
@ -4758,7 +4783,7 @@ msgstr ""
#, python-brace-format #, python-brace-format
#~ msgid "QR-code number {qr_code_number}" #~ msgid "QR-code number {qr_code_number}"
#~ msgstr "numéro du QR-code {qr_code_number}" #~ msgstr "Numéro du QR-code {qr_code_number}"
#~ msgid "was eaten" #~ msgid "was eaten"
#~ msgstr "a été mangé" #~ msgstr "a été mangé"