mirror of
https://gitlab.crans.org/bde/nk20
synced 2024-12-23 16:02:25 +00:00
Merge branch 'wei' into 'beta'
[WEI] Belle UI pour attribuer les 1A dans les bus See merge request bde/nk20!178
This commit is contained in:
commit
780f78b385
@ -74,7 +74,7 @@ class Profile(models.Model):
|
||||
|
||||
promotion = models.PositiveSmallIntegerField(
|
||||
null=True,
|
||||
default=datetime.date.today().year,
|
||||
default=datetime.date.today().year if datetime.date.today().month >= 8 else datetime.date.today().year - 1,
|
||||
verbose_name=_("promotion"),
|
||||
help_text=_("Year of entry to the school (None if not ENS student)"),
|
||||
)
|
||||
|
@ -1,10 +1,10 @@
|
||||
# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from .registration import WEIForm, WEIRegistrationForm, WEIMembershipForm, BusForm, BusTeamForm
|
||||
from .registration import WEIForm, WEIRegistrationForm, WEIMembership1AForm, WEIMembershipForm, BusForm, BusTeamForm
|
||||
from .surveys import WEISurvey, WEISurveyInformation, WEISurveyAlgorithm, CurrentSurvey
|
||||
|
||||
__all__ = [
|
||||
'WEIForm', 'WEIRegistrationForm', 'WEIMembershipForm', 'BusForm', 'BusTeamForm',
|
||||
'WEIForm', 'WEIRegistrationForm', 'WEIMembership1AForm', 'WEIMembershipForm', 'BusForm', 'BusTeamForm',
|
||||
'WEISurvey', 'WEISurveyInformation', 'WEISurveyAlgorithm', 'CurrentSurvey',
|
||||
]
|
||||
|
@ -48,8 +48,7 @@ class WEIRegistrationForm(forms.ModelForm):
|
||||
'placeholder': 'Nom ...',
|
||||
},
|
||||
),
|
||||
"birth_date": DatePickerInput(options={'defaultDate': '2000-01-01',
|
||||
'minDate': '1900-01-01',
|
||||
"birth_date": DatePickerInput(options={'minDate': '1900-01-01',
|
||||
'maxDate': '2100-01-01'}),
|
||||
}
|
||||
|
||||
@ -118,7 +117,8 @@ class WEIMembershipForm(forms.ModelForm):
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
if cleaned_data["team"] is not None and cleaned_data["team"].bus != cleaned_data["bus"]:
|
||||
if 'team' in cleaned_data and cleaned_data["team"] is not None \
|
||||
and cleaned_data["team"].bus != cleaned_data["bus"]:
|
||||
self.add_error('bus', _("This team doesn't belong to the given bus."))
|
||||
return cleaned_data
|
||||
|
||||
@ -144,6 +144,20 @@ class WEIMembershipForm(forms.ModelForm):
|
||||
}
|
||||
|
||||
|
||||
class WEIMembership1AForm(WEIMembershipForm):
|
||||
"""
|
||||
Used to confirm registrations of first year members without choosing a bus now.
|
||||
"""
|
||||
roles = None
|
||||
|
||||
def clean(self):
|
||||
return super(forms.ModelForm, self).clean()
|
||||
|
||||
class Meta:
|
||||
model = WEIMembership
|
||||
fields = ('credit_type', 'credit_amount', 'last_name', 'first_name', 'bank',)
|
||||
|
||||
|
||||
class BusForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Bus
|
||||
|
@ -7,6 +7,7 @@ from datetime import date
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from phonenumber_field.modelfields import PhoneNumberField
|
||||
from member.models import Club, Membership
|
||||
@ -98,6 +99,13 @@ class Bus(models.Model):
|
||||
"""
|
||||
self.information_json = json.dumps(information, indent=2)
|
||||
|
||||
@property
|
||||
def suggested_first_year(self):
|
||||
registrations = WEIRegistration.objects.filter(Q(membership__isnull=True) | Q(membership__bus__isnull=True),
|
||||
first_year=True, wei=self.wei)
|
||||
registrations = [r for r in registrations if 'selected_bus_pk' in r.information]
|
||||
return sum(1 for r in registrations if r.information['selected_bus_pk'] == self.pk)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
from datetime import date
|
||||
|
||||
import django_tables2 as tables
|
||||
from django.db.models import Q
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.html import format_html
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
@ -102,9 +103,9 @@ class WEIRegistrationTable(tables.Table):
|
||||
if record.fee > record.user.note.balance and not record.soge_credit:
|
||||
btn_class = 'btn-secondary'
|
||||
tooltip = _("The user does not have enough money.")
|
||||
elif record.first_year and 'selected_bus_pk' not in record.information:
|
||||
elif record.first_year:
|
||||
btn_class = 'btn-info'
|
||||
tooltip = _("The user is in first year, and the repartition algorithm didn't run.")
|
||||
tooltip = _("The user is in first year. You may validate the credit, the algorithm will run later.")
|
||||
else:
|
||||
btn_class = 'btn-success'
|
||||
tooltip = _("The user has enough money, you can validate the registration.")
|
||||
@ -169,6 +170,35 @@ class WEIMembershipTable(tables.Table):
|
||||
}
|
||||
|
||||
|
||||
class WEIRegistration1ATable(tables.Table):
|
||||
user = tables.LinkColumn(
|
||||
'wei:wei_bus_1A',
|
||||
args=[A('pk')],
|
||||
)
|
||||
|
||||
preferred_bus = tables.Column(
|
||||
verbose_name=_('preferred bus').capitalize,
|
||||
accessor='pk',
|
||||
orderable=False,
|
||||
)
|
||||
|
||||
def render_preferred_bus(self, record):
|
||||
information = record.information
|
||||
return information['selected_bus_name'] if 'selected_bus_name' in information else "—"
|
||||
|
||||
class Meta:
|
||||
attrs = {
|
||||
'class': 'table table-condensed table-striped table-hover'
|
||||
}
|
||||
model = WEIRegistration
|
||||
template_name = 'django_tables2/bootstrap4.html'
|
||||
fields = ('user', 'user__last_name', 'user__first_name', 'gender',
|
||||
'user__profile__department', 'preferred_bus', 'membership__bus', )
|
||||
row_attrs = {
|
||||
'class': lambda record: '' if 'selected_bus_pk' in record.information else 'bg-danger',
|
||||
}
|
||||
|
||||
|
||||
class BusTable(tables.Table):
|
||||
name = tables.LinkColumn(
|
||||
'wei:manage_bus',
|
||||
@ -245,3 +275,66 @@ class BusTeamTable(tables.Table):
|
||||
'id': lambda record: "row-" + str(record.pk),
|
||||
'data-href': lambda record: reverse_lazy('wei:manage_bus_team', args=(record.pk, ))
|
||||
}
|
||||
|
||||
|
||||
class BusRepartitionTable(tables.Table):
|
||||
name = tables.Column(
|
||||
verbose_name=_("name").capitalize,
|
||||
accessor='name',
|
||||
)
|
||||
|
||||
suggested_first_year = tables.Column(
|
||||
verbose_name=_("suggested first year").capitalize,
|
||||
accessor='pk',
|
||||
orderable=False,
|
||||
)
|
||||
|
||||
validated_first_year = tables.Column(
|
||||
verbose_name=_("validated first year").capitalize,
|
||||
accessor='pk',
|
||||
orderable=False,
|
||||
)
|
||||
|
||||
validated_staff = tables.Column(
|
||||
verbose_name=_("validated staff").capitalize,
|
||||
accessor='pk',
|
||||
orderable=False,
|
||||
)
|
||||
|
||||
size = tables.Column(
|
||||
verbose_name=_("seat count in the bus").capitalize,
|
||||
accessor='size',
|
||||
)
|
||||
|
||||
free_seats = tables.Column(
|
||||
verbose_name=_("free seats").capitalize,
|
||||
accessor='pk',
|
||||
orderable=False,
|
||||
)
|
||||
|
||||
def render_suggested_first_year(self, record):
|
||||
registrations = WEIRegistration.objects.filter(Q(membership__isnull=True) | Q(membership__bus__isnull=True),
|
||||
first_year=True, wei=record.wei)
|
||||
registrations = [r for r in registrations if 'selected_bus_pk' in r.information]
|
||||
return sum(1 for r in registrations if r.information['selected_bus_pk'] == record.pk)
|
||||
|
||||
def render_validated_first_year(self, record):
|
||||
return WEIRegistration.objects.filter(first_year=True, membership__bus=record).count()
|
||||
|
||||
def render_validated_staff(self, record):
|
||||
return WEIRegistration.objects.filter(first_year=False, membership__bus=record).count()
|
||||
|
||||
def render_free_seats(self, record):
|
||||
return record.size - self.render_validated_staff(record) - self.render_validated_first_year(record)
|
||||
|
||||
class Meta:
|
||||
attrs = {
|
||||
'class': 'table table-condensed table-striped table-hover'
|
||||
}
|
||||
models = Bus
|
||||
template_name = 'django_tables2/bootstrap4.html'
|
||||
fields = ('name', )
|
||||
row_attrs = {
|
||||
'class': 'table-row',
|
||||
'id': lambda record: "row-" + str(record.pk),
|
||||
}
|
||||
|
20
apps/wei/templates/wei/1A_list.html
Normal file
20
apps/wei/templates/wei/1A_list.html
Normal file
@ -0,0 +1,20 @@
|
||||
{% extends "wei/base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load render_table from django_tables2 %}
|
||||
|
||||
{% block profile_content %}
|
||||
<div class="card">
|
||||
<div class="card-header text-center">
|
||||
<h3>{% trans "Attribute first year members into buses" %}</h3>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
{% render_table bus_repartition_table %}
|
||||
<hr>
|
||||
<a href="{% url 'wei:wei_bus_1A_next' pk=club.pk %}" class="btn btn-block btn-success">{% trans "Start attribution!" %}</a>
|
||||
<hr>
|
||||
{% render_table table %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
88
apps/wei/templates/wei/attribute_bus_1A.html
Normal file
88
apps/wei/templates/wei/attribute_bus_1A.html
Normal file
@ -0,0 +1,88 @@
|
||||
{% extends "wei/base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% block profile_content %}
|
||||
<div class="card">
|
||||
<div class="card-header text-center">
|
||||
<h3>{% trans "Bus attribution" %}</h3>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<dl class="row">
|
||||
<dt class="col-xl-6">{% trans 'user'|capfirst %}</dt>
|
||||
<dd class="col-xl-6">{{ object.user }}</dd>
|
||||
|
||||
<dt class="col-xl-6">{% trans 'last name'|capfirst %}</dt>
|
||||
<dd class="col-xl-6">{{ object.user.last_name }}</dd>
|
||||
|
||||
<dt class="col-xl-6">{% trans 'first name'|capfirst %}</dt>
|
||||
<dd class="col-xl-6">{{ object.user.first_name }}</dd>
|
||||
|
||||
<dt class="col-xl-6">{% trans 'gender'|capfirst %}</dt>
|
||||
<dd class="col-xl-6">{{ object.get_gender_display }}</dd>
|
||||
|
||||
<dt class="col-xl-6">{% trans 'department'|capfirst %}</dt>
|
||||
<dd class="col-xl-6">{{ object.user.profile.get_department_display }}</dd>
|
||||
|
||||
<dt class="col-xl-6">{% trans 'health issues'|capfirst %}</dt>
|
||||
<dd class="col-xl-6">{{ object.health_issues|default:"—" }}</dd>
|
||||
|
||||
<dt class="col-xl-6">{% trans 'suggested bus'|capfirst %}</dt>
|
||||
<dd class="col-xl-6">{{ survey.information.selected_bus_name }}</dd>
|
||||
</dl>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<button class="btn btn-link" data-toggle="collapse" data-target="#raw-survey">{% trans "View raw survey information" %}</button>
|
||||
</div>
|
||||
<div class="collapse" id="raw-survey">
|
||||
<dl class="row">
|
||||
{% for key, value in survey.registration.information.items %}
|
||||
<dt class="col-xl-6">{{ key }}</dt>
|
||||
<dd class="col-xl-6">{{ value }}</dd>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
{% for bus, score in survey.ordered_buses %}
|
||||
<button class="btn btn-{% if bus.pk == survey.information.selected_bus_pk %}success{% else %}light{% endif %}" onclick="choose_bus({{ bus.pk }})">
|
||||
{{ bus }} ({{ score|floatformat:2 }}) : {{ bus.memberships.count }}+{{ bus.suggested_first_year }} / {{ bus.size }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
|
||||
<a href="{% url 'wei:wei_1A_list' pk=object.wei.pk %}" class="btn btn-block btn-info">{% trans "Back to main list" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extrajavascript %}
|
||||
<script>
|
||||
function choose_bus(bus_id) {
|
||||
let valid_buses = [{% for bus, score in survey.ordered_buses %}{{ bus.pk }}, {% endfor %}];
|
||||
if (valid_buses.indexOf(bus_id) === -1) {
|
||||
console.log("Invalid chosen bus")
|
||||
return
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: "/api/wei/membership/{{ object.membership.id }}/",
|
||||
type: "PATCH",
|
||||
dataType: "json",
|
||||
headers: {
|
||||
"X-CSRFTOKEN": CSRF_TOKEN
|
||||
},
|
||||
data: {
|
||||
bus: bus_id,
|
||||
}
|
||||
}).done(function () {
|
||||
window.location = "{% url 'wei:wei_bus_1A_next' pk=object.wei.pk %}"
|
||||
}).fail(function (xhr) {
|
||||
errMsg(xhr.responseJSON)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
@ -94,6 +94,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if can_validate_1a or True %}
|
||||
<a href="{% url 'wei:wei_1A_list' pk=object.pk %}" class="btn btn-block btn-info">{% trans "Attribute buses" %}</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extrajavascript %}
|
||||
|
@ -53,7 +53,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
<dd class="col-xl-6">{{ registration.first_year|yesno }}</dd>
|
||||
|
||||
<dt class="col-xl-6">{% trans 'gender'|capfirst %}</dt>
|
||||
<dd class="col-xl-6">{{ registration.gender }}</dd>
|
||||
<dd class="col-xl-6">{{ registration.get_gender_display }}</dd>
|
||||
|
||||
<dt class="col-xl-6">{% trans 'clothing cut'|capfirst %}</dt>
|
||||
<dd class="col-xl-6">{{ registration.clothing_cut }}</dd>
|
||||
|
@ -3,12 +3,11 @@
|
||||
|
||||
from django.urls import path
|
||||
|
||||
from .views import CurrentWEIDetailView, WEIListView, WEICreateView, WEIDetailView, WEIUpdateView,\
|
||||
WEIRegistrationsView, WEIMembershipsView, MemberListRenderView,\
|
||||
BusCreateView, BusManageView, BusUpdateView, BusTeamCreateView, BusTeamManageView, BusTeamUpdateView,\
|
||||
WEIRegister1AView, WEIRegister2AView, WEIUpdateRegistrationView, WEIDeleteRegistrationView,\
|
||||
WEIValidateRegistrationView, WEISurveyView, WEISurveyEndView, WEIClosedView
|
||||
|
||||
from .views import CurrentWEIDetailView, WEI1AListView, WEIListView, WEICreateView, WEIDetailView, WEIUpdateView, \
|
||||
WEIRegistrationsView, WEIMembershipsView, MemberListRenderView, \
|
||||
BusCreateView, BusManageView, BusUpdateView, BusTeamCreateView, BusTeamManageView, BusTeamUpdateView, \
|
||||
WEIAttributeBus1AView, WEIAttributeBus1ANextView, WEIRegister1AView, WEIRegister2AView, WEIUpdateRegistrationView, \
|
||||
WEIDeleteRegistrationView, WEIValidateRegistrationView, WEISurveyView, WEISurveyEndView, WEIClosedView
|
||||
|
||||
app_name = 'wei'
|
||||
urlpatterns = [
|
||||
@ -24,6 +23,7 @@ urlpatterns = [
|
||||
name="wei_memberships_bus_pdf"),
|
||||
path('detail/<int:wei_pk>/memberships/pdf/<int:bus_pk>/<int:team_pk>/', MemberListRenderView.as_view(),
|
||||
name="wei_memberships_team_pdf"),
|
||||
path('bus-1A/list/<int:pk>/', WEI1AListView.as_view(), name="wei_1A_list"),
|
||||
path('add-bus/<int:pk>/', BusCreateView.as_view(), name="add_bus"),
|
||||
path('manage-bus/<int:pk>/', BusManageView.as_view(), name="manage_bus"),
|
||||
path('update-bus/<int:pk>/', BusUpdateView.as_view(), name="update_bus"),
|
||||
@ -40,4 +40,6 @@ urlpatterns = [
|
||||
path('survey/<int:pk>/', WEISurveyView.as_view(), name="wei_survey"),
|
||||
path('survey/<int:pk>/end/', WEISurveyEndView.as_view(), name="wei_survey_end"),
|
||||
path('detail/<int:pk>/closed/', WEIClosedView.as_view(), name="wei_closed"),
|
||||
path('bus-1A/<int:pk>/', WEIAttributeBus1AView.as_view(), name="wei_bus_1A"),
|
||||
path('bus-1A/next/<int:pk>/', WEIAttributeBus1ANextView.as_view(), name="wei_bus_1A_next"),
|
||||
]
|
||||
|
@ -13,8 +13,7 @@ from django.core.exceptions import PermissionDenied
|
||||
from django.db import transaction
|
||||
from django.db.models import Q, Count
|
||||
from django.db.models.functions.text import Lower
|
||||
from django.forms import HiddenInput
|
||||
from django.http import HttpResponse
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.shortcuts import redirect
|
||||
from django.template.loader import render_to_string
|
||||
from django.urls import reverse_lazy
|
||||
@ -32,8 +31,10 @@ from permission.views import ProtectQuerysetMixin, ProtectedCreateView
|
||||
|
||||
from .forms.registration import WEIChooseBusForm
|
||||
from .models import WEIClub, WEIRegistration, WEIMembership, Bus, BusTeam, WEIRole
|
||||
from .forms import WEIForm, WEIRegistrationForm, BusForm, BusTeamForm, WEIMembershipForm, CurrentSurvey
|
||||
from .tables import WEITable, WEIRegistrationTable, BusTable, BusTeamTable, WEIMembershipTable
|
||||
from .forms import WEIForm, WEIRegistrationForm, BusForm, BusTeamForm, WEIMembership1AForm, \
|
||||
WEIMembershipForm, CurrentSurvey
|
||||
from .tables import BusRepartitionTable, BusTable, BusTeamTable, WEITable, WEIRegistrationTable, \
|
||||
WEIRegistration1ATable, WEIMembershipTable
|
||||
|
||||
|
||||
class CurrentWEIDetailView(LoginRequiredMixin, RedirectView):
|
||||
@ -511,7 +512,8 @@ class WEIRegister1AView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
if today >= wei.date_start or today < wei.membership_start:
|
||||
return redirect(reverse_lazy('wei:wei_closed', args=(wei.pk,)))
|
||||
# Don't register twice
|
||||
if 'myself' in self.request.path and WEIRegistration.objects.filter(wei=wei, user=self.request.user).exists():
|
||||
if 'myself' in self.request.path and not self.request.user.is_anonymous \
|
||||
and WEIRegistration.objects.filter(wei=wei, user=self.request.user).exists():
|
||||
obj = WEIRegistration.objects.get(wei=wei, user=self.request.user)
|
||||
return redirect(reverse_lazy('wei:wei_update_registration', args=(obj.pk,)))
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
@ -590,7 +592,8 @@ class WEIRegister2AView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
if today >= wei.date_start or today < wei.membership_start:
|
||||
return redirect(reverse_lazy('wei:wei_closed', args=(wei.pk,)))
|
||||
# Don't register twice
|
||||
if 'myself' in self.request.path and WEIRegistration.objects.filter(wei=wei, user=self.request.user).exists():
|
||||
if 'myself' in self.request.path and not self.request.user.is_anonymous \
|
||||
and WEIRegistration.objects.filter(wei=wei, user=self.request.user).exists():
|
||||
obj = WEIRegistration.objects.get(wei=wei, user=self.request.user)
|
||||
return redirect(reverse_lazy('wei:wei_update_registration', args=(obj.pk,)))
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
@ -677,17 +680,8 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update
|
||||
context["club"] = self.object.wei
|
||||
|
||||
if self.object.is_validated:
|
||||
membership_form = WEIMembershipForm(instance=self.object.membership,
|
||||
data=self.request.POST if self.request.POST else None)
|
||||
for field_name, field in membership_form.fields.items():
|
||||
if not PermissionBackend.check_perm(
|
||||
self.request, "wei.change_membership_" + field_name, self.object.membership):
|
||||
field.widget = HiddenInput()
|
||||
del membership_form.fields["credit_type"]
|
||||
del membership_form.fields["credit_amount"]
|
||||
del membership_form.fields["first_name"]
|
||||
del membership_form.fields["last_name"]
|
||||
del membership_form.fields["bank"]
|
||||
membership_form = self.get_membership_form(instance=self.object.membership,
|
||||
data=self.request.POST)
|
||||
context["membership_form"] = membership_form
|
||||
elif not self.object.first_year and PermissionBackend.check_perm(
|
||||
self.request, "wei.change_weiregistration_information_json", self.object):
|
||||
@ -719,11 +713,24 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update
|
||||
del form.fields["information_json"]
|
||||
return form
|
||||
|
||||
def get_membership_form(self, data=None, instance=None):
|
||||
membership_form = WEIMembershipForm(data if data else None, instance=instance)
|
||||
del membership_form.fields["credit_type"]
|
||||
del membership_form.fields["credit_amount"]
|
||||
del membership_form.fields["first_name"]
|
||||
del membership_form.fields["last_name"]
|
||||
del membership_form.fields["bank"]
|
||||
for field_name, _field in list(membership_form.fields.items()):
|
||||
if not PermissionBackend.check_perm(
|
||||
self.request, "wei.change_weimembership_" + field_name, self.object.membership):
|
||||
del membership_form.fields[field_name]
|
||||
return membership_form
|
||||
|
||||
@transaction.atomic
|
||||
def form_valid(self, form):
|
||||
# If the membership is already validated, then we update the bus and the team (and the roles)
|
||||
if form.instance.is_validated:
|
||||
membership_form = WEIMembershipForm(self.request.POST, instance=form.instance.membership)
|
||||
membership_form = self.get_membership_form(self.request.POST, form.instance.membership)
|
||||
if not membership_form.is_valid():
|
||||
return self.form_invalid(form)
|
||||
membership_form.save()
|
||||
@ -797,7 +804,6 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
Validate WEI Registration
|
||||
"""
|
||||
model = WEIMembership
|
||||
form_class = WEIMembershipForm
|
||||
extra_context = {"title": _("Validate WEI registration")}
|
||||
|
||||
def get_sample_object(self):
|
||||
@ -853,6 +859,12 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
|
||||
return context
|
||||
|
||||
def get_form_class(self):
|
||||
registration = WEIRegistration.objects.get(pk=self.kwargs["pk"])
|
||||
if registration.first_year and 'sleected_bus_pk' not in registration.information:
|
||||
return WEIMembership1AForm
|
||||
return WEIMembershipForm
|
||||
|
||||
def get_form(self, form_class=None):
|
||||
form = super().get_form(form_class)
|
||||
registration = WEIRegistration.objects.get(pk=self.kwargs["pk"])
|
||||
@ -868,25 +880,27 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
form.fields["bank"].disabled = True
|
||||
form.fields["bank"].initial = "Société générale"
|
||||
|
||||
form.fields["bus"].widget.attrs["api_url"] = "/api/wei/bus/?wei=" + str(registration.wei.pk)
|
||||
if registration.first_year:
|
||||
# Use the results of the survey to fill initial data
|
||||
# A first year has no other role than "1A"
|
||||
del form.fields["roles"]
|
||||
survey = CurrentSurvey(registration)
|
||||
if survey.information.valid:
|
||||
form.fields["bus"].initial = survey.information.get_selected_bus()
|
||||
else:
|
||||
# Use the choice of the member to fill initial data
|
||||
information = registration.information
|
||||
if "preferred_bus_pk" in information and len(information["preferred_bus_pk"]) == 1:
|
||||
form["bus"].initial = Bus.objects.get(pk=information["preferred_bus_pk"][0])
|
||||
if "preferred_team_pk" in information and len(information["preferred_team_pk"]) == 1:
|
||||
form["team"].initial = BusTeam.objects.get(pk=information["preferred_team_pk"][0])
|
||||
if "preferred_roles_pk" in information:
|
||||
form["roles"].initial = WEIRole.objects.filter(
|
||||
Q(pk__in=information["preferred_roles_pk"]) | Q(name="Adhérent WEI")
|
||||
).all()
|
||||
if 'bus' in form.fields:
|
||||
# For 2A+ and hardcoded 1A
|
||||
form.fields["bus"].widget.attrs["api_url"] = "/api/wei/bus/?wei=" + str(registration.wei.pk)
|
||||
if registration.first_year:
|
||||
# Use the results of the survey to fill initial data
|
||||
# A first year has no other role than "1A"
|
||||
del form.fields["roles"]
|
||||
survey = CurrentSurvey(registration)
|
||||
if survey.information.valid:
|
||||
form.fields["bus"].initial = survey.information.get_selected_bus()
|
||||
else:
|
||||
# Use the choice of the member to fill initial data
|
||||
information = registration.information
|
||||
if "preferred_bus_pk" in information and len(information["preferred_bus_pk"]) == 1:
|
||||
form["bus"].initial = Bus.objects.get(pk=information["preferred_bus_pk"][0])
|
||||
if "preferred_team_pk" in information and len(information["preferred_team_pk"]) == 1:
|
||||
form["team"].initial = BusTeam.objects.get(pk=information["preferred_team_pk"][0])
|
||||
if "preferred_roles_pk" in information:
|
||||
form["roles"].initial = WEIRole.objects.filter(
|
||||
Q(pk__in=information["preferred_roles_pk"]) | Q(name="Adhérent WEI")
|
||||
).all()
|
||||
return form
|
||||
|
||||
@transaction.atomic
|
||||
@ -1146,3 +1160,62 @@ class MemberListRenderView(LoginRequiredMixin, View):
|
||||
shutil.rmtree(tmp_dir)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
class WEI1AListView(LoginRequiredMixin, ProtectQuerysetMixin, SingleTableView):
|
||||
model = WEIRegistration
|
||||
template_name = "wei/1A_list.html"
|
||||
table_class = WEIRegistration1ATable
|
||||
extra_context = {"title": _("Attribute buses to first year members")}
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.club = WEIClub.objects.get(pk=self.kwargs["pk"])
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_queryset(self, filter_permissions=True, **kwargs):
|
||||
qs = super().get_queryset(filter_permissions, **kwargs)
|
||||
qs = qs.filter(first_year=True, membership__isnull=False)
|
||||
qs = qs.order_by('-membership__bus')
|
||||
return qs
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['club'] = self.club
|
||||
context['bus_repartition_table'] = BusRepartitionTable(Bus.objects.filter(wei=self.club, size__gt=0).all())
|
||||
return context
|
||||
|
||||
|
||||
class WEIAttributeBus1AView(ProtectQuerysetMixin, DetailView):
|
||||
model = WEIRegistration
|
||||
template_name = "wei/attribute_bus_1A.html"
|
||||
extra_context = {"title": _("Attribute bus")}
|
||||
|
||||
def get_queryset(self, filter_permissions=True, **kwargs):
|
||||
qs = super().get_queryset(filter_permissions, **kwargs)
|
||||
qs = qs.filter(first_year=True)
|
||||
return qs
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
obj = self.get_object()
|
||||
if 'selected_bus_pk' not in obj.information:
|
||||
return redirect(reverse_lazy('wei:wei_survey', args=(obj.pk,)))
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['club'] = self.object.wei
|
||||
context['survey'] = CurrentSurvey(self.object)
|
||||
return context
|
||||
|
||||
|
||||
class WEIAttributeBus1ANextView(LoginRequiredMixin, RedirectView):
|
||||
def get_redirect_url(self, *args, **kwargs):
|
||||
wei = WEIClub.objects.filter(pk=self.kwargs['pk'])
|
||||
if not wei.exists():
|
||||
raise Http404
|
||||
wei = wei.get()
|
||||
qs = WEIRegistration.objects.filter(wei=wei, membership__isnull=False, membership__bus__isnull=True)
|
||||
qs = qs.filter(information_json__contains='selected_bus_pk') # not perfect, but works...
|
||||
if qs.exists():
|
||||
return reverse_lazy('wei:wei_bus_1A', args=(qs.first().pk, ))
|
||||
return reverse_lazy('wei_1A_list', args=(wei.pk, ))
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-08 18:46+0200\n"
|
||||
"POT-Creation-Date: 2021-09-12 19:30+0200\n"
|
||||
"PO-Revision-Date: 2020-11-16 20:02+0000\n"
|
||||
"Last-Translator: Yohann D'ANELLO <ynerant@crans.org>\n"
|
||||
"Language-Team: French <http://translate.ynerant.fr/projects/nk20/nk20/fr/>\n"
|
||||
@ -56,7 +56,7 @@ msgstr "Vous ne pouvez pas inviter plus de 3 personnes à cette activité."
|
||||
#: apps/note/models/transactions.py:46 apps/note/models/transactions.py:301
|
||||
#: apps/permission/models.py:330
|
||||
#: apps/registration/templates/registration/future_profile_detail.html:16
|
||||
#: apps/wei/models.py:66 apps/wei/models.py:123
|
||||
#: apps/wei/models.py:66 apps/wei/models.py:123 apps/wei/tables.py:283
|
||||
#: apps/wei/templates/wei/base.html:26
|
||||
#: apps/wei/templates/wei/weimembership_form.html:14
|
||||
msgid "name"
|
||||
@ -111,8 +111,9 @@ msgid "type"
|
||||
msgstr "type"
|
||||
|
||||
#: apps/activity/models.py:89 apps/logs/models.py:22 apps/member/models.py:305
|
||||
#: apps/note/models/notes.py:148 apps/treasury/models.py:286
|
||||
#: apps/wei/models.py:165 apps/wei/templates/wei/survey.html:15
|
||||
#: apps/note/models/notes.py:148 apps/treasury/models.py:285
|
||||
#: apps/wei/models.py:165 apps/wei/templates/wei/attribute_bus_1A.html:13
|
||||
#: apps/wei/templates/wei/survey.html:15
|
||||
msgid "user"
|
||||
msgstr "utilisateur"
|
||||
|
||||
@ -204,6 +205,7 @@ msgstr "La note est en négatif."
|
||||
|
||||
#: apps/activity/models.py:240
|
||||
#: apps/treasury/templates/treasury/sogecredit_detail.html:14
|
||||
#: apps/wei/templates/wei/attribute_bus_1A.html:16
|
||||
msgid "last name"
|
||||
msgstr "nom de famille"
|
||||
|
||||
@ -211,6 +213,7 @@ msgstr "nom de famille"
|
||||
#: apps/member/templates/member/includes/profile_info.html:4
|
||||
#: apps/registration/templates/registration/future_profile_detail.html:16
|
||||
#: apps/treasury/templates/treasury/sogecredit_detail.html:17
|
||||
#: apps/wei/templates/wei/attribute_bus_1A.html:19
|
||||
#: apps/wei/templates/wei/weimembership_form.html:14
|
||||
msgid "first name"
|
||||
msgstr "prénom"
|
||||
@ -251,20 +254,20 @@ msgstr "Entré le "
|
||||
msgid "remove"
|
||||
msgstr "supprimer"
|
||||
|
||||
#: apps/activity/tables.py:80 apps/note/forms.py:68 apps/treasury/models.py:200
|
||||
#: apps/activity/tables.py:80 apps/note/forms.py:68 apps/treasury/models.py:199
|
||||
msgid "Type"
|
||||
msgstr "Type"
|
||||
|
||||
#: apps/activity/tables.py:82 apps/member/forms.py:186
|
||||
#: apps/registration/forms.py:90 apps/treasury/forms.py:131
|
||||
#: apps/wei/forms/registration.py:105
|
||||
#: apps/wei/forms/registration.py:104
|
||||
msgid "Last name"
|
||||
msgstr "Nom de famille"
|
||||
|
||||
#: apps/activity/tables.py:84 apps/member/forms.py:191
|
||||
#: apps/note/templates/note/transaction_form.html:134
|
||||
#: apps/registration/forms.py:95 apps/treasury/forms.py:133
|
||||
#: apps/wei/forms/registration.py:110
|
||||
#: apps/wei/forms/registration.py:109
|
||||
msgid "First name"
|
||||
msgstr "Prénom"
|
||||
|
||||
@ -461,7 +464,7 @@ msgstr "créer"
|
||||
|
||||
#: apps/logs/models.py:65 apps/note/tables.py:165 apps/note/tables.py:201
|
||||
#: apps/permission/models.py:127 apps/treasury/tables.py:38
|
||||
#: apps/wei/tables.py:73
|
||||
#: apps/wei/tables.py:74
|
||||
msgid "delete"
|
||||
msgstr "supprimer"
|
||||
|
||||
@ -508,7 +511,7 @@ msgstr "rôles"
|
||||
msgid "fee"
|
||||
msgstr "cotisation"
|
||||
|
||||
#: apps/member/apps.py:14 apps/wei/tables.py:196 apps/wei/tables.py:227
|
||||
#: apps/member/apps.py:14 apps/wei/tables.py:227 apps/wei/tables.py:258
|
||||
msgid "member"
|
||||
msgstr "adhérent"
|
||||
|
||||
@ -554,12 +557,12 @@ msgid "Check this case if the Société Générale paid the inscription."
|
||||
msgstr "Cochez cette case si la Société Générale a payé l'inscription."
|
||||
|
||||
#: apps/member/forms.py:172 apps/registration/forms.py:77
|
||||
#: apps/wei/forms/registration.py:92
|
||||
#: apps/wei/forms/registration.py:91
|
||||
msgid "Credit type"
|
||||
msgstr "Type de rechargement"
|
||||
|
||||
#: apps/member/forms.py:173 apps/registration/forms.py:78
|
||||
#: apps/wei/forms/registration.py:93
|
||||
#: apps/wei/forms/registration.py:92
|
||||
msgid "No credit"
|
||||
msgstr "Pas de rechargement"
|
||||
|
||||
@ -568,13 +571,13 @@ msgid "You can credit the note of the user."
|
||||
msgstr "Vous pouvez créditer la note de l'utilisateur avant l'adhésion."
|
||||
|
||||
#: apps/member/forms.py:179 apps/registration/forms.py:83
|
||||
#: apps/wei/forms/registration.py:98
|
||||
#: apps/wei/forms/registration.py:97
|
||||
msgid "Credit amount"
|
||||
msgstr "Montant à créditer"
|
||||
|
||||
#: apps/member/forms.py:196 apps/note/templates/note/transaction_form.html:140
|
||||
#: apps/registration/forms.py:100 apps/treasury/forms.py:135
|
||||
#: apps/wei/forms/registration.py:115
|
||||
#: apps/wei/forms/registration.py:114
|
||||
msgid "Bank"
|
||||
msgstr "Banque"
|
||||
|
||||
@ -620,7 +623,8 @@ msgstr "section"
|
||||
msgid "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
|
||||
msgstr "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
|
||||
|
||||
#: apps/member/models.py:54 apps/wei/templates/wei/weimembership_form.html:32
|
||||
#: apps/member/models.py:54 apps/wei/templates/wei/attribute_bus_1A.html:25
|
||||
#: apps/wei/templates/wei/weimembership_form.html:32
|
||||
msgid "department"
|
||||
msgstr "département"
|
||||
|
||||
@ -1188,7 +1192,7 @@ msgstr "Modifier le club"
|
||||
msgid "Add new member to the club"
|
||||
msgstr "Ajouter un nouveau membre au club"
|
||||
|
||||
#: apps/member/views.py:642 apps/wei/views.py:932
|
||||
#: apps/member/views.py:642 apps/wei/views.py:956
|
||||
msgid ""
|
||||
"This user don't have enough money to join this club, and can't have a "
|
||||
"negative balance."
|
||||
@ -1494,8 +1498,8 @@ msgstr ""
|
||||
"mode de paiement et un utilisateur ou un club"
|
||||
|
||||
#: apps/note/models/transactions.py:355 apps/note/models/transactions.py:358
|
||||
#: apps/note/models/transactions.py:361 apps/wei/views.py:937
|
||||
#: apps/wei/views.py:941
|
||||
#: apps/note/models/transactions.py:361 apps/wei/views.py:961
|
||||
#: apps/wei/views.py:965
|
||||
msgid "This field is required."
|
||||
msgstr "Ce champ est requis."
|
||||
|
||||
@ -1511,7 +1515,7 @@ msgstr "Transactions de crédit/retrait"
|
||||
msgid "membership transaction"
|
||||
msgstr "transaction d'adhésion"
|
||||
|
||||
#: apps/note/models/transactions.py:385 apps/treasury/models.py:293
|
||||
#: apps/note/models/transactions.py:385 apps/treasury/models.py:292
|
||||
msgid "membership transactions"
|
||||
msgstr "transactions d'adhésion"
|
||||
|
||||
@ -1530,7 +1534,7 @@ msgstr "Pas de motif spécifié"
|
||||
#: apps/note/tables.py:169 apps/note/tables.py:203 apps/treasury/tables.py:39
|
||||
#: apps/treasury/templates/treasury/invoice_confirm_delete.html:30
|
||||
#: apps/treasury/templates/treasury/sogecredit_detail.html:65
|
||||
#: apps/wei/tables.py:74 apps/wei/tables.py:117
|
||||
#: apps/wei/tables.py:75 apps/wei/tables.py:118
|
||||
#: apps/wei/templates/wei/weiregistration_confirm_delete.html:31
|
||||
#: note_kfet/templates/oauth2_provider/application_confirm_delete.html:18
|
||||
#: note_kfet/templates/oauth2_provider/application_detail.html:39
|
||||
@ -1539,7 +1543,7 @@ msgid "Delete"
|
||||
msgstr "Supprimer"
|
||||
|
||||
#: apps/note/tables.py:197 apps/note/templates/note/conso_form.html:132
|
||||
#: apps/wei/tables.py:48 apps/wei/tables.py:49
|
||||
#: apps/wei/tables.py:49 apps/wei/tables.py:50
|
||||
#: apps/wei/templates/wei/base.html:89
|
||||
#: apps/wei/templates/wei/bus_detail.html:20
|
||||
#: apps/wei/templates/wei/busteam_detail.html:20
|
||||
@ -1625,7 +1629,7 @@ msgid "Amount"
|
||||
msgstr "Montant"
|
||||
|
||||
#: apps/note/templates/note/transaction_form.html:128
|
||||
#: apps/treasury/models.py:55
|
||||
#: apps/treasury/models.py:54
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
@ -2102,7 +2106,7 @@ msgstr "Invalider l'inscription"
|
||||
msgid "Treasury"
|
||||
msgstr "Trésorerie"
|
||||
|
||||
#: apps/treasury/forms.py:26 apps/treasury/models.py:94
|
||||
#: apps/treasury/forms.py:26 apps/treasury/models.py:93
|
||||
#: apps/treasury/templates/treasury/invoice_form.html:22
|
||||
msgid "This invoice is locked and can no longer be edited."
|
||||
msgstr "Cette facture est verrouillée et ne peut plus être éditée."
|
||||
@ -2115,7 +2119,7 @@ msgstr "La remise est déjà fermée."
|
||||
msgid "You can't change the type of the remittance."
|
||||
msgstr "Vous ne pouvez pas changer le type de la remise."
|
||||
|
||||
#: apps/treasury/forms.py:125 apps/treasury/models.py:268
|
||||
#: apps/treasury/forms.py:125 apps/treasury/models.py:267
|
||||
#: apps/treasury/tables.py:97 apps/treasury/tables.py:105
|
||||
#: apps/treasury/templates/treasury/invoice_list.html:16
|
||||
#: apps/treasury/templates/treasury/remittance_list.html:16
|
||||
@ -2127,120 +2131,120 @@ msgstr "Remise"
|
||||
msgid "No attached remittance"
|
||||
msgstr "Pas de remise associée"
|
||||
|
||||
#: apps/treasury/models.py:27
|
||||
#: apps/treasury/models.py:26
|
||||
msgid "Invoice identifier"
|
||||
msgstr "Numéro de facture"
|
||||
|
||||
#: apps/treasury/models.py:41
|
||||
#: apps/treasury/models.py:40
|
||||
msgid "BDE"
|
||||
msgstr "BDE"
|
||||
|
||||
#: apps/treasury/models.py:46
|
||||
#: apps/treasury/models.py:45
|
||||
msgid "Object"
|
||||
msgstr "Objet"
|
||||
|
||||
#: apps/treasury/models.py:50
|
||||
#: apps/treasury/models.py:49
|
||||
msgid "Description"
|
||||
msgstr "Description"
|
||||
|
||||
#: apps/treasury/models.py:59
|
||||
#: apps/treasury/models.py:58
|
||||
msgid "Address"
|
||||
msgstr "Adresse"
|
||||
|
||||
#: apps/treasury/models.py:64 apps/treasury/models.py:194
|
||||
#: apps/treasury/models.py:63 apps/treasury/models.py:193
|
||||
msgid "Date"
|
||||
msgstr "Date"
|
||||
|
||||
#: apps/treasury/models.py:68
|
||||
#: apps/treasury/models.py:67
|
||||
msgid "Acquitted"
|
||||
msgstr "Acquittée"
|
||||
|
||||
#: apps/treasury/models.py:73
|
||||
#: apps/treasury/models.py:72
|
||||
msgid "Locked"
|
||||
msgstr "Verrouillée"
|
||||
|
||||
#: apps/treasury/models.py:74
|
||||
#: apps/treasury/models.py:73
|
||||
msgid "An invoice can't be edited when it is locked."
|
||||
msgstr "Une facture ne peut plus être modifiée si elle est verrouillée."
|
||||
|
||||
#: apps/treasury/models.py:80
|
||||
#: apps/treasury/models.py:79
|
||||
msgid "tex source"
|
||||
msgstr "fichier TeX source"
|
||||
|
||||
#: apps/treasury/models.py:114 apps/treasury/models.py:130
|
||||
#: apps/treasury/models.py:113 apps/treasury/models.py:129
|
||||
msgid "invoice"
|
||||
msgstr "facture"
|
||||
|
||||
#: apps/treasury/models.py:115
|
||||
#: apps/treasury/models.py:114
|
||||
msgid "invoices"
|
||||
msgstr "factures"
|
||||
|
||||
#: apps/treasury/models.py:118
|
||||
#: apps/treasury/models.py:117
|
||||
#, python-brace-format
|
||||
msgid "Invoice #{id}"
|
||||
msgstr "Facture n°{id}"
|
||||
|
||||
#: apps/treasury/models.py:135
|
||||
#: apps/treasury/models.py:134
|
||||
msgid "Designation"
|
||||
msgstr "Désignation"
|
||||
|
||||
#: apps/treasury/models.py:141
|
||||
#: apps/treasury/models.py:140
|
||||
msgid "Quantity"
|
||||
msgstr "Quantité"
|
||||
|
||||
#: apps/treasury/models.py:146
|
||||
#: apps/treasury/models.py:145
|
||||
msgid "Unit price"
|
||||
msgstr "Prix unitaire"
|
||||
|
||||
#: apps/treasury/models.py:162
|
||||
#: apps/treasury/models.py:161
|
||||
msgid "product"
|
||||
msgstr "produit"
|
||||
|
||||
#: apps/treasury/models.py:163
|
||||
#: apps/treasury/models.py:162
|
||||
msgid "products"
|
||||
msgstr "produits"
|
||||
|
||||
#: apps/treasury/models.py:183
|
||||
#: apps/treasury/models.py:182
|
||||
msgid "remittance type"
|
||||
msgstr "type de remise"
|
||||
|
||||
#: apps/treasury/models.py:184
|
||||
#: apps/treasury/models.py:183
|
||||
msgid "remittance types"
|
||||
msgstr "types de remises"
|
||||
|
||||
#: apps/treasury/models.py:205
|
||||
#: apps/treasury/models.py:204
|
||||
msgid "Comment"
|
||||
msgstr "Commentaire"
|
||||
|
||||
#: apps/treasury/models.py:210
|
||||
#: apps/treasury/models.py:209
|
||||
msgid "Closed"
|
||||
msgstr "Fermée"
|
||||
|
||||
#: apps/treasury/models.py:214
|
||||
#: apps/treasury/models.py:213
|
||||
msgid "remittance"
|
||||
msgstr "remise"
|
||||
|
||||
#: apps/treasury/models.py:215
|
||||
#: apps/treasury/models.py:214
|
||||
msgid "remittances"
|
||||
msgstr "remises"
|
||||
|
||||
#: apps/treasury/models.py:248
|
||||
#: apps/treasury/models.py:247
|
||||
msgid "Remittance #{:d}: {}"
|
||||
msgstr "Remise n°{:d} : {}"
|
||||
|
||||
#: apps/treasury/models.py:272
|
||||
#: apps/treasury/models.py:271
|
||||
msgid "special transaction proxy"
|
||||
msgstr "proxy de transaction spéciale"
|
||||
|
||||
#: apps/treasury/models.py:273
|
||||
#: apps/treasury/models.py:272
|
||||
msgid "special transaction proxies"
|
||||
msgstr "proxys de transactions spéciales"
|
||||
|
||||
#: apps/treasury/models.py:299
|
||||
#: apps/treasury/models.py:298
|
||||
msgid "credit transaction"
|
||||
msgstr "transaction de crédit"
|
||||
|
||||
#: apps/treasury/models.py:418
|
||||
#: apps/treasury/models.py:419
|
||||
msgid ""
|
||||
"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."
|
||||
@ -2248,16 +2252,16 @@ msgstr ""
|
||||
"Cet utilisateur n'a pas assez d'argent pour payer les adhésions avec sa "
|
||||
"note. Merci de lui demander de recharger sa note avant d'invalider ce crédit."
|
||||
|
||||
#: apps/treasury/models.py:438
|
||||
#: apps/treasury/models.py:439
|
||||
#: apps/treasury/templates/treasury/sogecredit_detail.html:10
|
||||
msgid "Credit from the Société générale"
|
||||
msgstr "Crédit de la Société générale"
|
||||
|
||||
#: apps/treasury/models.py:439
|
||||
#: apps/treasury/models.py:440
|
||||
msgid "Credits from the Société générale"
|
||||
msgstr "Crédits de la Société générale"
|
||||
|
||||
#: apps/treasury/models.py:442
|
||||
#: apps/treasury/models.py:443
|
||||
#, python-brace-format
|
||||
msgid "Soge credit for {user}"
|
||||
msgstr "Crédit de la société générale pour l'utilisateur {user}"
|
||||
@ -2437,7 +2441,7 @@ msgstr ""
|
||||
"demande de crédit."
|
||||
|
||||
#: apps/treasury/templates/treasury/sogecredit_detail.html:63
|
||||
#: apps/wei/tables.py:59 apps/wei/tables.py:101
|
||||
#: apps/wei/tables.py:60 apps/wei/tables.py:102
|
||||
msgid "Validate"
|
||||
msgstr "Valider"
|
||||
|
||||
@ -2516,12 +2520,12 @@ msgstr ""
|
||||
"L'utilisateur sélectionné n'est pas validé. Merci de d'abord valider son "
|
||||
"compte."
|
||||
|
||||
#: apps/wei/forms/registration.py:60 apps/wei/models.py:118
|
||||
#: apps/wei/forms/registration.py:59 apps/wei/models.py:118
|
||||
#: apps/wei/models.py:315
|
||||
msgid "bus"
|
||||
msgstr "bus"
|
||||
|
||||
#: apps/wei/forms/registration.py:61
|
||||
#: apps/wei/forms/registration.py:60
|
||||
msgid ""
|
||||
"This choice is not definitive. The WEI organizers are free to attribute for "
|
||||
"you a bus and a team, in particular if you are a free eletron."
|
||||
@ -2530,11 +2534,11 @@ msgstr ""
|
||||
"attribuer un bus et une équipe, en particulier si vous êtes un électron "
|
||||
"libre."
|
||||
|
||||
#: apps/wei/forms/registration.py:68
|
||||
#: apps/wei/forms/registration.py:67
|
||||
msgid "Team"
|
||||
msgstr "Équipe"
|
||||
|
||||
#: apps/wei/forms/registration.py:70
|
||||
#: apps/wei/forms/registration.py:69
|
||||
msgid ""
|
||||
"Leave this field empty if you won't be in a team (staff, bus chief, free "
|
||||
"electron)"
|
||||
@ -2542,12 +2546,12 @@ msgstr ""
|
||||
"Laissez ce champ vide si vous ne serez pas dans une équipe (staff, chef de "
|
||||
"bus ou électron libre)"
|
||||
|
||||
#: apps/wei/forms/registration.py:76 apps/wei/forms/registration.py:86
|
||||
#: apps/wei/forms/registration.py:75 apps/wei/forms/registration.py:85
|
||||
#: apps/wei/models.py:153
|
||||
msgid "WEI Roles"
|
||||
msgstr "Rôles au WEI"
|
||||
|
||||
#: apps/wei/forms/registration.py:77
|
||||
#: apps/wei/forms/registration.py:76
|
||||
msgid "Select the roles that you are interested in."
|
||||
msgstr "Sélectionnez les rôles qui vous intéressent."
|
||||
|
||||
@ -2571,7 +2575,7 @@ msgstr "début"
|
||||
msgid "date end"
|
||||
msgstr "fin"
|
||||
|
||||
#: apps/wei/models.py:70
|
||||
#: apps/wei/models.py:70 apps/wei/tables.py:306
|
||||
msgid "seat count in the bus"
|
||||
msgstr "nombre de sièges dans le bus"
|
||||
|
||||
@ -2637,7 +2641,8 @@ msgstr "Femme"
|
||||
msgid "Non binary"
|
||||
msgstr "Non-binaire"
|
||||
|
||||
#: apps/wei/models.py:196 apps/wei/templates/wei/weimembership_form.html:55
|
||||
#: apps/wei/models.py:196 apps/wei/templates/wei/attribute_bus_1A.html:22
|
||||
#: apps/wei/templates/wei/weimembership_form.html:55
|
||||
msgid "gender"
|
||||
msgstr "genre"
|
||||
|
||||
@ -2649,7 +2654,8 @@ msgstr "coupe de vêtement"
|
||||
msgid "clothing size"
|
||||
msgstr "taille de vêtement"
|
||||
|
||||
#: apps/wei/models.py:224 apps/wei/templates/wei/weimembership_form.html:67
|
||||
#: apps/wei/models.py:224 apps/wei/templates/wei/attribute_bus_1A.html:28
|
||||
#: apps/wei/templates/wei/weimembership_form.html:67
|
||||
msgid "health issues"
|
||||
msgstr "problèmes de santé"
|
||||
|
||||
@ -2705,37 +2711,83 @@ msgstr "Adhésion au WEI"
|
||||
msgid "WEI memberships"
|
||||
msgstr "Adhésions au WEI"
|
||||
|
||||
#: apps/wei/tables.py:104
|
||||
#: apps/wei/tables.py:105
|
||||
msgid "The user does not have enough money."
|
||||
msgstr "L'utilisateur n'a pas assez d'argent."
|
||||
|
||||
#: apps/wei/tables.py:107
|
||||
msgid "The user is in first year, and the repartition algorithm didn't run."
|
||||
#: apps/wei/tables.py:108
|
||||
msgid ""
|
||||
"The user is in first year. You may validate the credit, the algorithm will "
|
||||
"run later."
|
||||
msgstr ""
|
||||
"L'utilisateur est en première année, et l'algorithme de répartition n'a pas "
|
||||
"tourné."
|
||||
"L'utilisateur est en première année, vous pouvez valider le crédit, "
|
||||
"l'algorithme tournera plus tard."
|
||||
|
||||
#: apps/wei/tables.py:110
|
||||
#: apps/wei/tables.py:111
|
||||
msgid "The user has enough money, you can validate the registration."
|
||||
msgstr "L'utilisateur a assez d'argent, l'inscription est possible."
|
||||
|
||||
#: apps/wei/tables.py:142
|
||||
#: apps/wei/tables.py:143
|
||||
msgid "Year"
|
||||
msgstr "Année"
|
||||
|
||||
#: apps/wei/tables.py:180 apps/wei/templates/wei/bus_detail.html:32
|
||||
#: apps/wei/tables.py:180 apps/wei/templates/wei/weimembership_form.html:102
|
||||
msgid "preferred bus"
|
||||
msgstr "bus préféré"
|
||||
|
||||
#: apps/wei/tables.py:211 apps/wei/templates/wei/bus_detail.html:32
|
||||
#: apps/wei/templates/wei/busteam_detail.html:50
|
||||
msgid "Teams"
|
||||
msgstr "Équipes"
|
||||
|
||||
#: apps/wei/tables.py:189 apps/wei/tables.py:230
|
||||
#: apps/wei/tables.py:220 apps/wei/tables.py:261
|
||||
msgid "Members count"
|
||||
msgstr "Nombre de membres"
|
||||
|
||||
#: apps/wei/tables.py:196 apps/wei/tables.py:227
|
||||
#: apps/wei/tables.py:227 apps/wei/tables.py:258
|
||||
msgid "members"
|
||||
msgstr "adhérents"
|
||||
|
||||
#: apps/wei/tables.py:288
|
||||
msgid "suggested first year"
|
||||
msgstr "1A suggérés"
|
||||
|
||||
#: apps/wei/tables.py:294
|
||||
msgid "validated first year"
|
||||
msgstr "1A validés"
|
||||
|
||||
#: apps/wei/tables.py:300
|
||||
msgid "validated staff"
|
||||
msgstr "2A+ validés"
|
||||
|
||||
#: apps/wei/tables.py:311
|
||||
msgid "free seats"
|
||||
msgstr "sièges libres"
|
||||
|
||||
#: apps/wei/templates/wei/1A_list.html:9
|
||||
msgid "Attribute first year members into buses"
|
||||
msgstr "Attribuer les 1A dans les bus"
|
||||
|
||||
#: apps/wei/templates/wei/1A_list.html:15
|
||||
msgid "Start attribution!"
|
||||
msgstr "Démarrer l'attribution !"
|
||||
|
||||
#: apps/wei/templates/wei/attribute_bus_1A.html:8
|
||||
msgid "Bus attribution"
|
||||
msgstr "Répartition des bus"
|
||||
|
||||
#: apps/wei/templates/wei/attribute_bus_1A.html:31
|
||||
msgid "suggested bus"
|
||||
msgstr "bus suggéré"
|
||||
|
||||
#: apps/wei/templates/wei/attribute_bus_1A.html:37
|
||||
msgid "View raw survey information"
|
||||
msgstr "Voir les informations brutes du sondage"
|
||||
|
||||
#: apps/wei/templates/wei/attribute_bus_1A.html:57
|
||||
msgid "Back to main list"
|
||||
msgstr "Retour à la liste principale"
|
||||
|
||||
#: apps/wei/templates/wei/base.html:44
|
||||
msgid "WEI fee (paid students)"
|
||||
msgstr "Prix du WEI (élèves)"
|
||||
@ -2752,11 +2804,11 @@ msgstr "Prix du WEI (étudiants)"
|
||||
msgid "WEI list"
|
||||
msgstr "Liste des WEI"
|
||||
|
||||
#: apps/wei/templates/wei/base.html:81 apps/wei/views.py:517
|
||||
#: apps/wei/templates/wei/base.html:81 apps/wei/views.py:523
|
||||
msgid "Register 1A"
|
||||
msgstr "Inscrire un 1A"
|
||||
|
||||
#: apps/wei/templates/wei/base.html:85 apps/wei/views.py:592
|
||||
#: apps/wei/templates/wei/base.html:85 apps/wei/views.py:603
|
||||
msgid "Register 2A+"
|
||||
msgstr "Inscrire un 2A+"
|
||||
|
||||
@ -2785,8 +2837,8 @@ msgstr "Télécharger au format PDF"
|
||||
|
||||
#: apps/wei/templates/wei/survey.html:11
|
||||
#: apps/wei/templates/wei/survey_closed.html:11
|
||||
#: apps/wei/templates/wei/survey_end.html:11 apps/wei/views.py:988
|
||||
#: apps/wei/views.py:1043 apps/wei/views.py:1053
|
||||
#: apps/wei/templates/wei/survey_end.html:11 apps/wei/views.py:1011
|
||||
#: apps/wei/views.py:1066 apps/wei/views.py:1076
|
||||
msgid "Survey WEI"
|
||||
msgstr "Questionnaire WEI"
|
||||
|
||||
@ -2827,7 +2879,11 @@ msgstr "Membres du WEI"
|
||||
msgid "Unvalidated registrations"
|
||||
msgstr "Inscriptions non validées"
|
||||
|
||||
#: apps/wei/templates/wei/weiclub_list.html:14 apps/wei/views.py:77
|
||||
#: apps/wei/templates/wei/weiclub_detail.html:99
|
||||
msgid "Attribute buses"
|
||||
msgstr "Répartition dans les bus"
|
||||
|
||||
#: apps/wei/templates/wei/weiclub_list.html:14 apps/wei/views.py:78
|
||||
msgid "Create WEI"
|
||||
msgstr "Créer un WEI"
|
||||
|
||||
@ -2863,10 +2919,6 @@ msgstr "L'algorithme n'a pas été exécuté."
|
||||
msgid "caution check given"
|
||||
msgstr "chèque de caution donné"
|
||||
|
||||
#: apps/wei/templates/wei/weimembership_form.html:102
|
||||
msgid "preferred bus"
|
||||
msgstr "bus préféré"
|
||||
|
||||
#: apps/wei/templates/wei/weimembership_form.html:105
|
||||
msgid "preferred team"
|
||||
msgstr "équipe préférée"
|
||||
@ -2968,67 +3020,67 @@ msgstr "Il n'y a pas de pré-inscription en attente avec cette entrée."
|
||||
msgid "View validated memberships..."
|
||||
msgstr "Voir les adhésions validées ..."
|
||||
|
||||
#: apps/wei/views.py:56
|
||||
#: apps/wei/views.py:57
|
||||
msgid "Search WEI"
|
||||
msgstr "Chercher un WEI"
|
||||
|
||||
#: apps/wei/views.py:107
|
||||
#: apps/wei/views.py:108
|
||||
msgid "WEI Detail"
|
||||
msgstr "Détails du WEI"
|
||||
|
||||
#: apps/wei/views.py:202
|
||||
#: apps/wei/views.py:203
|
||||
msgid "View members of the WEI"
|
||||
msgstr "Voir les membres du WEI"
|
||||
|
||||
#: apps/wei/views.py:230
|
||||
#: apps/wei/views.py:231
|
||||
msgid "Find WEI Membership"
|
||||
msgstr "Trouver une adhésion au WEI"
|
||||
|
||||
#: apps/wei/views.py:240
|
||||
#: apps/wei/views.py:241
|
||||
msgid "View registrations to the WEI"
|
||||
msgstr "Voir les inscriptions au WEI"
|
||||
|
||||
#: apps/wei/views.py:264
|
||||
#: apps/wei/views.py:265
|
||||
msgid "Find WEI Registration"
|
||||
msgstr "Trouver une inscription au WEI"
|
||||
|
||||
#: apps/wei/views.py:275
|
||||
#: apps/wei/views.py:276
|
||||
msgid "Update the WEI"
|
||||
msgstr "Modifier le WEI"
|
||||
|
||||
#: apps/wei/views.py:296
|
||||
#: apps/wei/views.py:297
|
||||
msgid "Create new bus"
|
||||
msgstr "Ajouter un nouveau bus"
|
||||
|
||||
#: apps/wei/views.py:334
|
||||
#: apps/wei/views.py:335
|
||||
msgid "Update bus"
|
||||
msgstr "Modifier le bus"
|
||||
|
||||
#: apps/wei/views.py:366
|
||||
#: apps/wei/views.py:367
|
||||
msgid "Manage bus"
|
||||
msgstr "Gérer le bus"
|
||||
|
||||
#: apps/wei/views.py:393
|
||||
#: apps/wei/views.py:394
|
||||
msgid "Create new team"
|
||||
msgstr "Créer une nouvelle équipe"
|
||||
|
||||
#: apps/wei/views.py:433
|
||||
#: apps/wei/views.py:434
|
||||
msgid "Update team"
|
||||
msgstr "Modifier l'équipe"
|
||||
|
||||
#: apps/wei/views.py:464
|
||||
#: apps/wei/views.py:465
|
||||
msgid "Manage WEI team"
|
||||
msgstr "Gérer l'équipe WEI"
|
||||
|
||||
#: apps/wei/views.py:486
|
||||
#: apps/wei/views.py:487
|
||||
msgid "Register first year student to the WEI"
|
||||
msgstr "Inscrire un 1A au WEI"
|
||||
|
||||
#: apps/wei/views.py:539 apps/wei/views.py:627
|
||||
#: apps/wei/views.py:545 apps/wei/views.py:638
|
||||
msgid "This user is already registered to this WEI."
|
||||
msgstr "Cette personne est déjà inscrite au WEI."
|
||||
|
||||
#: apps/wei/views.py:544
|
||||
#: apps/wei/views.py:550
|
||||
msgid ""
|
||||
"This user can't be in her/his first year since he/she has already "
|
||||
"participated to a WEI."
|
||||
@ -3036,30 +3088,38 @@ msgstr ""
|
||||
"Cet utilisateur ne peut pas être en première année puisqu'il a déjà "
|
||||
"participé à un WEI."
|
||||
|
||||
#: apps/wei/views.py:561
|
||||
#: apps/wei/views.py:567
|
||||
msgid "Register old student to the WEI"
|
||||
msgstr "Inscrire un 2A+ au WEI"
|
||||
|
||||
#: apps/wei/views.py:611 apps/wei/views.py:700
|
||||
#: apps/wei/views.py:622 apps/wei/views.py:704
|
||||
msgid "You already opened an account in the Société générale."
|
||||
msgstr "Vous avez déjà ouvert un compte auprès de la société générale."
|
||||
|
||||
#: apps/wei/views.py:657
|
||||
#: apps/wei/views.py:668
|
||||
msgid "Update WEI Registration"
|
||||
msgstr "Modifier l'inscription WEI"
|
||||
|
||||
#: apps/wei/views.py:761
|
||||
#: apps/wei/views.py:778
|
||||
msgid "Delete WEI registration"
|
||||
msgstr "Supprimer l'inscription WEI"
|
||||
|
||||
#: apps/wei/views.py:772
|
||||
#: apps/wei/views.py:789
|
||||
msgid "You don't have the right to delete this WEI registration."
|
||||
msgstr "Vous n'avez pas la permission de supprimer cette inscription au WEI."
|
||||
|
||||
#: apps/wei/views.py:791
|
||||
#: apps/wei/views.py:807
|
||||
msgid "Validate WEI registration"
|
||||
msgstr "Valider l'inscription WEI"
|
||||
|
||||
#: apps/wei/views.py:1169
|
||||
msgid "Attribute buses to first year members"
|
||||
msgstr "Répartir les 1A dans les bus"
|
||||
|
||||
#: apps/wei/views.py:1190
|
||||
msgid "Attribute bus"
|
||||
msgstr "Attribuer un bus"
|
||||
|
||||
#: note_kfet/settings/base.py:161
|
||||
msgid "German"
|
||||
msgstr "Allemand"
|
||||
|
Loading…
Reference in New Issue
Block a user