1
0
mirror of https://gitlab.com/animath/si/plateforme.git synced 2025-02-26 14:26:30 +00:00

Compare commits

...

2 Commits

Author SHA1 Message Date
Emmy D'Anello
0f2c44331c
Add vaccine sheet field, closes #18 2023-02-20 00:38:57 +01:00
Emmy D'Anello
fae4ee7105
Drop AdminRegistration in favour of a new boolean field, closes #19 2023-02-20 00:25:06 +01:00
22 changed files with 471 additions and 265 deletions

View File

@ -12,7 +12,6 @@ from django.core.exceptions import ValidationError
from django.core.validators import FileExtensionValidator from django.core.validators import FileExtensionValidator
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from pypdf import PdfFileReader from pypdf import PdfFileReader
from registration.models import VolunteerRegistration from registration.models import VolunteerRegistration
from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament

View File

@ -8,7 +8,7 @@ from django.core.management import BaseCommand
from django.utils.http import urlencode from django.utils.http import urlencode
from django.utils.translation import activate from django.utils.translation import activate
from participation.models import Team, Tournament from participation.models import Team, Tournament
from registration.models import AdminRegistration, Registration, VolunteerRegistration from registration.models import Registration, VolunteerRegistration
from tfjm.matrix import Matrix, RoomPreset, RoomVisibility from tfjm.matrix import Matrix, RoomPreset, RoomVisibility
@ -163,7 +163,7 @@ class Command(BaseCommand):
self.stdout.write(f"Invite {volunteer} in #aide-jury-orgas...") self.stdout.write(f"Invite {volunteer} in #aide-jury-orgas...")
# Admins are admins # Admins are admins
for admin in AdminRegistration.objects.all(): for admin in VolunteerRegistration.objects.filter(admin=True).all():
self.stdout.write(f"Invite {admin} in #cno and #dev-bot...") self.stdout.write(f"Invite {admin} in #cno and #dev-bot...")
await Matrix.invite("#cno:tfjm.org", f"@{admin.matrix_username}:tfjm.org") await Matrix.invite("#cno:tfjm.org", f"@{admin.matrix_username}:tfjm.org")
await Matrix.invite("#dev-bot:tfjm.org", f"@{admin.matrix_username}:tfjm.org") await Matrix.invite("#dev-bot:tfjm.org", f"@{admin.matrix_username}:tfjm.org")
@ -264,7 +264,7 @@ class Command(BaseCommand):
await Matrix.set_room_avatar(f"#tirage-au-sort-{slug}:tfjm.org", avatar_uri) await Matrix.set_room_avatar(f"#tirage-au-sort-{slug}:tfjm.org", avatar_uri)
# Invite admins and give permissions # Invite admins and give permissions
for admin in AdminRegistration.objects.all(): for admin in VolunteerRegistration.objects.filter(admin=True).all():
self.stdout.write(f"Invite {admin} in all channels of the tournament {name}...") self.stdout.write(f"Invite {admin} in all channels of the tournament {name}...")
await Matrix.invite(f"#annonces-{slug}:tfjm.org", f"@{admin.matrix_username}:tfjm.org") await Matrix.invite(f"#annonces-{slug}:tfjm.org", f"@{admin.matrix_username}:tfjm.org")
await Matrix.invite(f"#flood-{slug}:tfjm.org", f"@{admin.matrix_username}:tfjm.org") await Matrix.invite(f"#flood-{slug}:tfjm.org", f"@{admin.matrix_username}:tfjm.org")
@ -374,7 +374,7 @@ class Command(BaseCommand):
"customwidget", "Tableau", str(pool)) "customwidget", "Tableau", str(pool))
# Invite admins and give permissions # Invite admins and give permissions
for admin in AdminRegistration.objects.all(): for admin in VolunteerRegistration.objects.filter(admin=True).all():
await Matrix.invite(f"#poule-{slug}-{pool.id}{suffix}:tfjm.org", await Matrix.invite(f"#poule-{slug}-{pool.id}{suffix}:tfjm.org",
f"@{admin.matrix_username}:tfjm.org") f"@{admin.matrix_username}:tfjm.org")
await Matrix.invite(f"#poule-{slug}-{pool.id}{suffix}-jurys:tfjm.org", await Matrix.invite(f"#poule-{slug}-{pool.id}{suffix}-jurys:tfjm.org",

View File

@ -4,7 +4,7 @@
from django.core.management import BaseCommand from django.core.management import BaseCommand
from django.db.models import Q from django.db.models import Q
from participation.models import Team, Tournament from participation.models import Team, Tournament
from registration.models import AdminRegistration, ParticipantRegistration, VolunteerRegistration from registration.models import ParticipantRegistration, VolunteerRegistration
from tfjm.lists import get_sympa_client from tfjm.lists import get_sympa_client
@ -71,5 +71,5 @@ class Command(BaseCommand):
slug = jury_in.tournament.name.lower().replace(" ", "-") slug = jury_in.tournament.name.lower().replace(" ", "-")
sympa.subscribe(volunteer.user.email, f"jurys-{slug}", True) sympa.subscribe(volunteer.user.email, f"jurys-{slug}", True)
for admin in AdminRegistration.objects.all(): for admin in VolunteerRegistration.objects.filter(admin=True).all():
sympa.subscribe(admin.user.email, "admins", True) sympa.subscribe(admin.user.email, "admins", True)

View File

@ -74,6 +74,19 @@
{% endfor %} {% endfor %}
</dd> </dd>
<dt class="col-sm-6 text-right">{% trans "Vaccine sheets:" %}</dt>
<dd class="col-sm-6">
{% for student in team.students.all %}
{% if student.under_18 %}
{% if student.vaccine_sheet %}
<a href="{{ student.vaccine_sheet.url }}" data-turbolinks="false">{{ student }}</a>{% if not forloop.last %},{% endif %}
{% else %}
{{ student }} ({% trans "Not uploaded yet" %}){% if not forloop.last %},{% endif %}
{% endif %}
{% endif %}
{% endfor %}
</dd>
<dt class="col-sm-6 text-right">{% trans "Parental authorizations:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Parental authorizations:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% for student in team.students.all %} {% for student in team.students.all %}

View File

@ -230,6 +230,7 @@ class TestStudentParticipation(TestCase):
city="Paris", city="Paris",
photo_authorization="authorization/photo/mai-linh", photo_authorization="authorization/photo/mai-linh",
health_sheet="authorization/health/mai-linh", health_sheet="authorization/health/mai-linh",
vaccine_sheet="authorization/vaccine/mai-linh",
parental_authorization="authorization/parental/mai-linh", parental_authorization="authorization/parental/mai-linh",
) )
@ -251,6 +252,7 @@ class TestStudentParticipation(TestCase):
city="Paris", city="Paris",
photo_authorization="authorization/photo/emmy", photo_authorization="authorization/photo/emmy",
health_sheet="authorization/health/emmy", health_sheet="authorization/health/emmy",
vaccine_sheet="authorization/vaccine/emmy",
parental_authorization="authorization/parental/emmy", parental_authorization="authorization/parental/emmy",
) )
@ -272,11 +274,13 @@ class TestStudentParticipation(TestCase):
city="Paris", city="Paris",
photo_authorization="authorization/photo/tfjm", photo_authorization="authorization/photo/tfjm",
health_sheet="authorization/health/tfjm", health_sheet="authorization/health/tfjm",
vaccine_sheet="authorization/health/tfjm",
parental_authorization="authorization/parental/tfjm", parental_authorization="authorization/parental/tfjm",
) )
self.coach.registration.team = self.team self.coach.registration.team = self.team
self.coach.registration.health_sheet = "authorization/health/coach" self.coach.registration.health_sheet = "authorization/health/coach"
self.coach.registration.vaccine_sheet = "authorization/vaccine/coach"
self.coach.registration.photo_authorization = "authorization/photo/coach" self.coach.registration.photo_authorization = "authorization/photo/coach"
self.coach.registration.email_confirmed = True self.coach.registration.email_confirmed = True
self.coach.registration.save() self.coach.registration.save()
@ -305,6 +309,7 @@ class TestStudentParticipation(TestCase):
self.user.registration.photo_authorization = "authorization/photo/ananas" self.user.registration.photo_authorization = "authorization/photo/ananas"
self.user.registration.health_sheet = "authorization/health/ananas" self.user.registration.health_sheet = "authorization/health/ananas"
self.user.registration.vaccine_sheet = "authorization/health/ananas"
self.user.registration.parental_authorization = "authorization/parental/ananas" self.user.registration.parental_authorization = "authorization/parental/ananas"
self.user.registration.save() self.user.registration.save()

View File

@ -180,6 +180,7 @@ class TeamDetailView(LoginRequiredMixin, FormMixin, ProcessFormView, DetailView)
context["validation_form"] = ValidateParticipationForm(self.request.POST or None) context["validation_form"] = ValidateParticipationForm(self.request.POST or None)
# A team is complete when there are at least 4 members plus a coache that have sent their authorizations, # A team is complete when there are at least 4 members plus a coache that have sent their authorizations,
# their health sheet, they confirmed their email address and under-18 people sent their parental authorization. # their health sheet, they confirmed their email address and under-18 people sent their parental authorization.
# TODO: Add vaccine sheets
context["can_validate"] = team.students.count() >= 4 and team.coaches.exists() and \ context["can_validate"] = team.students.count() >= 4 and team.coaches.exists() and \
team.participation.tournament and \ team.participation.tournament and \
all(r.photo_authorization for r in team.participants.all()) and \ all(r.photo_authorization for r in team.participants.all()) and \
@ -414,6 +415,12 @@ class TeamAuthorizationsView(LoginRequiredMixin, DetailView):
zf.write("media/" + participant.health_sheet.name, zf.write("media/" + participant.health_sheet.name,
_("Health sheet of {participant}.{ext}").format(participant=str(participant), ext=ext)) _("Health sheet of {participant}.{ext}").format(participant=str(participant), ext=ext))
if isinstance(participant, StudentRegistration) and participant.vaccine_sheet:
mime_type = magic.from_file("media/" + participant.vaccine_sheet.name)
ext = mime_type.split("/")[1].replace("jpeg", "jpg")
zf.write("media/" + participant.vaccine_sheet.name,
_("Vaccine sheet of {participant}.{ext}").format(participant=str(participant), ext=ext))
if team.motivation_letter: if team.motivation_letter:
mime_type = magic.from_file("media/" + team.motivation_letter.name) mime_type = magic.from_file("media/" + team.motivation_letter.name)
ext = mime_type.split("/")[1].replace("jpeg", "jpg") ext = mime_type.split("/")[1].replace("jpeg", "jpg")

View File

@ -5,12 +5,12 @@ from django.contrib import admin
from django.contrib.admin import ModelAdmin from django.contrib.admin import ModelAdmin
from polymorphic.admin import PolymorphicChildModelAdmin, PolymorphicParentModelAdmin from polymorphic.admin import PolymorphicChildModelAdmin, PolymorphicParentModelAdmin
from .models import AdminRegistration, CoachRegistration, Payment, Registration, StudentRegistration from .models import CoachRegistration, Payment, Registration, StudentRegistration, VolunteerRegistration
@admin.register(Registration) @admin.register(Registration)
class RegistrationAdmin(PolymorphicParentModelAdmin): class RegistrationAdmin(PolymorphicParentModelAdmin):
child_models = (StudentRegistration, CoachRegistration, AdminRegistration,) child_models = (StudentRegistration, CoachRegistration, VolunteerRegistration,)
list_display = ("user", "type", "email_confirmed",) list_display = ("user", "type", "email_confirmed",)
polymorphic_list = True polymorphic_list = True
@ -25,8 +25,8 @@ class CoachRegistrationAdmin(PolymorphicChildModelAdmin):
pass pass
@admin.register(AdminRegistration) @admin.register(VolunteerRegistration)
class AdminRegistrationAdmin(PolymorphicChildModelAdmin): class VolunteerRegistrationAdmin(PolymorphicChildModelAdmin):
pass pass

View File

@ -4,16 +4,10 @@
from rest_framework import serializers from rest_framework import serializers
from rest_polymorphic.serializers import PolymorphicSerializer from rest_polymorphic.serializers import PolymorphicSerializer
from ..models import AdminRegistration, CoachRegistration, ParticipantRegistration, \ from ..models import CoachRegistration, ParticipantRegistration, \
StudentRegistration, VolunteerRegistration StudentRegistration, VolunteerRegistration
class AdminSerializer(serializers.ModelSerializer):
class Meta:
model = AdminRegistration
fields = '__all__'
class CoachSerializer(serializers.ModelSerializer): class CoachSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = CoachRegistration model = CoachRegistration
@ -40,7 +34,6 @@ class VolunteerSerializer(serializers.ModelSerializer):
class RegistrationSerializer(PolymorphicSerializer): class RegistrationSerializer(PolymorphicSerializer):
model_serializer_mapping = { model_serializer_mapping = {
AdminRegistration: AdminSerializer,
CoachRegistration: CoachSerializer, CoachRegistration: CoachSerializer,
StudentRegistration: StudentSerializer, StudentRegistration: StudentSerializer,
VolunteerRegistration: VolunteerSerializer, VolunteerRegistration: VolunteerSerializer,

View File

@ -20,4 +20,3 @@ class RegistrationConfig(AppConfig):
post_save.connect(create_payment, "registration.Registration") post_save.connect(create_payment, "registration.Registration")
post_save.connect(create_payment, "registration.StudentRegistration") post_save.connect(create_payment, "registration.StudentRegistration")
post_save.connect(create_payment, "registration.CoachRegistration") post_save.connect(create_payment, "registration.CoachRegistration")
post_save.connect(create_payment, "registration.AdminRegistration")

View File

@ -8,7 +8,7 @@ from django.core.exceptions import ValidationError
from django.forms import FileInput from django.forms import FileInput
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .models import AdminRegistration, CoachRegistration, ParticipantRegistration, Payment, \ from .models import CoachRegistration, ParticipantRegistration, Payment, \
StudentRegistration, VolunteerRegistration StudentRegistration, VolunteerRegistration
@ -50,14 +50,6 @@ class AddOrganizerForm(forms.ModelForm):
""" """
Signup form to registers volunteers Signup form to registers volunteers
""" """
type = forms.ChoiceField(
label=lambda: _("role").capitalize(),
choices=lambda: [
("volunteer", _("volunteer").capitalize()),
("admin", _("admin").capitalize()),
],
initial="volunteer",
)
def clean_email(self): def clean_email(self):
""" """
@ -76,7 +68,7 @@ class AddOrganizerForm(forms.ModelForm):
class Meta: class Meta:
model = User model = User
fields = ('first_name', 'last_name', 'email', 'type',) fields = ('first_name', 'last_name', 'email',)
class UserForm(forms.ModelForm): class UserForm(forms.ModelForm):
@ -154,6 +146,28 @@ class HealthSheetForm(forms.ModelForm):
fields = ('health_sheet',) fields = ('health_sheet',)
class VaccineSheetForm(forms.ModelForm):
"""
Form to send a vaccine sheet.
"""
def clean_vaccine_sheet(self):
if "vaccine_sheet" in self.files:
file = self.files["vaccine_sheet"]
if file.size > 2e6:
raise ValidationError(_("The uploaded file size must be under 2 Mo."))
if file.content_type not in ["application/pdf", "image/png", "image/jpeg"]:
raise ValidationError(_("The uploaded file must be a PDF, PNG of JPEG file."))
return self.cleaned_data["vaccine_sheet"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["vaccine_sheet"].widget = FileInput()
class Meta:
model = StudentRegistration
fields = ('vaccine_sheet',)
class ParentalAuthorizationForm(forms.ModelForm): class ParentalAuthorizationForm(forms.ModelForm):
""" """
Form to send a parental authorization. Form to send a parental authorization.
@ -192,16 +206,7 @@ class VolunteerRegistrationForm(forms.ModelForm):
""" """
class Meta: class Meta:
model = VolunteerRegistration model = VolunteerRegistration
fields = ('professional_activity', 'give_contact_to_animath', 'email_confirmed',) fields = ('professional_activity', 'admin', 'give_contact_to_animath', 'email_confirmed',)
class AdminRegistrationForm(forms.ModelForm):
"""
Admins can tell everything they want.
"""
class Meta:
model = AdminRegistration
fields = ('role', 'give_contact_to_animath', 'email_confirmed',)
class PaymentForm(forms.ModelForm): class PaymentForm(forms.ModelForm):

View File

@ -0,0 +1,51 @@
# Generated by Django 3.2.18 on 2023-02-19 22:13
from django.contrib.contenttypes.models import ContentType
from django.db import migrations, models
from django.db.models import F
def merge_admins(apps, schema_editor):
AdminRegistration = apps.get_model('registration', 'AdminRegistration')
VolunteerRegistration = apps.get_model('registration', 'VolunteerRegistration')
db_alias = schema_editor.connection.alias
AdminRegistration.objects.using(db_alias).update(admin=True)
for admin in AdminRegistration.objects.all():
admin.professional_activity = admin.role
admin.polymorphic_ctype_id = ContentType.objects.get_for_model(VolunteerRegistration).id
admin.save()
def separate_admins(apps, schema_editor):
AdminRegistration = apps.get_model('registration', 'AdminRegistration')
VolunteerRegistration = apps.get_model('registration', 'VolunteerRegistration')
for admin in VolunteerRegistration.objects.filter(admin=True).all():
admin.delete()
AdminRegistration.objects.create(user=admin.user,
professional_activity=admin.professional_activity,
role=admin.professional_activity)
class Migration(migrations.Migration):
dependencies = [
('participation', '0003_alter_team_trigram'),
('registration', '0003_alter_participantregistration_zip_code'),
]
operations = [
migrations.AddField(
model_name='volunteerregistration',
name='admin',
field=models.BooleanField(
default=False,
help_text="An administrator has all rights. Please don't give this right to all juries and volunteers.",
verbose_name='administrator'),
),
migrations.RunPython(
merge_admins,
separate_admins,
elidable=True,
),
migrations.DeleteModel(
name='AdminRegistration',
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 3.2.18 on 2023-02-19 23:38
from django.db import migrations, models
import registration.models
class Migration(migrations.Migration):
dependencies = [
('registration', '0004_volunteer_admin'),
]
operations = [
migrations.AddField(
model_name='studentregistration',
name='vaccine_sheet',
field=models.FileField(blank=True, default='', upload_to=registration.models.get_random_vaccine_filename, verbose_name='vaccine sheet'),
),
]

View File

@ -22,7 +22,7 @@ class Registration(PolymorphicModel):
""" """
Registrations store extra content that are not asked in the User Model. Registrations store extra content that are not asked in the User Model.
This is specific to the role of the user, see StudentRegistration, This is specific to the role of the user, see StudentRegistration,
ClassRegistration or AdminRegistration.. CoachRegistration or VolunteerRegistration.
""" """
user = models.OneToOneField( user = models.OneToOneField(
"auth.User", "auth.User",
@ -79,7 +79,7 @@ class Registration(PolymorphicModel):
@property @property
def is_admin(self): def is_admin(self):
return isinstance(self, AdminRegistration) or self.user.is_superuser return isinstance(self, VolunteerRegistration) and self.admin or self.user.is_superuser
@property @property
def is_volunteer(self): def is_volunteer(self):
@ -108,6 +108,10 @@ def get_random_health_filename(instance, filename):
return "authorization/health/" + get_random_string(64) return "authorization/health/" + get_random_string(64)
def get_random_vaccine_filename(instance, filename):
return "authorization/vaccine/" + get_random_string(64)
def get_random_parental_filename(instance, filename): def get_random_parental_filename(instance, filename):
return "authorization/parental/" + get_random_string(64) return "authorization/parental/" + get_random_string(64)
@ -242,6 +246,13 @@ class StudentRegistration(ParticipantRegistration):
default="", default="",
) )
vaccine_sheet = models.FileField(
verbose_name=_("vaccine sheet"),
upload_to=get_random_vaccine_filename,
blank=True,
default="",
)
@property @property
def type(self): def type(self):
return _("student") return _("student")
@ -287,13 +298,19 @@ class VolunteerRegistration(Registration):
verbose_name=_("professional activity"), verbose_name=_("professional activity"),
) )
admin = models.BooleanField(
verbose_name=_("administrator"),
help_text=_("An administrator has all rights. Please don't give this right to all juries and volunteers."),
default=False,
)
@property @property
def interesting_tournaments(self) -> set: def interesting_tournaments(self) -> set:
return set(self.organized_tournaments.all()).union(map(lambda pool: pool.tournament, self.jury_in.all())) return set(self.organized_tournaments.all()).union(map(lambda pool: pool.tournament, self.jury_in.all()))
@property @property
def type(self): def type(self):
return _('volunteer') return _('admin') if self.is_admin else _('volunteer')
@property @property
def form_class(self): def form_class(self):
@ -301,29 +318,6 @@ class VolunteerRegistration(Registration):
return VolunteerRegistrationForm return VolunteerRegistrationForm
class AdminRegistration(VolunteerRegistration):
"""
Specific registration for admins.
They have a field to justify they status.
"""
role = models.TextField(
verbose_name=_("role of the administrator"),
)
@property
def type(self):
return _("admin")
@property
def form_class(self):
from registration.forms import AdminRegistrationForm
return AdminRegistrationForm
class Meta:
verbose_name = _("admin registration")
verbose_name_plural = _("admin registrations")
def get_scholarship_filename(instance, filename): def get_scholarship_filename(instance, filename):
return f"authorization/scholarship/scholarship_{instance.registration.pk}" return f"authorization/scholarship/scholarship_{instance.registration.pk}"

View File

@ -4,7 +4,7 @@
from django.contrib.auth.models import User from django.contrib.auth.models import User
from tfjm.lists import get_sympa_client from tfjm.lists import get_sympa_client
from .models import AdminRegistration, Payment, Registration from .models import Payment, Registration, VolunteerRegistration
def set_username(instance, **_): def set_username(instance, **_):
@ -40,7 +40,7 @@ def create_admin_registration(instance, **_):
ensure that an admin registration is created. ensure that an admin registration is created.
""" """
if instance.is_superuser: if instance.is_superuser:
AdminRegistration.objects.get_or_create(user=instance) VolunteerRegistration.objects.get_or_create(user=instance, admin=True)
def create_payment(instance: Registration, **_): def create_payment(instance: Registration, **_):

View File

@ -19,7 +19,7 @@ class RegistrationTable(tables.Table):
) )
def order_type(self, queryset, desc): def order_type(self, queryset, desc):
types = ["volunteerregistration__adminregistration", "volunteerregistration", "participantregistration"] types = ["-volunteerregistration__admin", "volunteerregistration", "participantregistration"]
return queryset.order_by(*(("-" if desc else "") + t for t in types)), True return queryset.order_by(*(("-" if desc else "") + t for t in types)), True
class Meta: class Meta:

View File

@ -0,0 +1,15 @@
{% extends "base.html" %}
{% load i18n static crispy_forms_filters %}
{% block content %}
<a class="btn btn-info" href="{% url "registration:user_detail" pk=object.user.pk %}"><i class="fas fa-arrow-left"></i> {% trans "Back to the user detail" %}</a>
<hr>
<form method="post" enctype="multipart/form-data">
<div id="form-content">
{% csrf_token %}
{{ form|crispy }}
</div>
<button class="btn btn-success" type="submit">{% trans "Upload" %}</button>
</form>
{% endblock %}

View File

@ -79,6 +79,16 @@
{% endif %} {% endif %}
</dd> </dd>
<dt class="col-sm-6 text-right">{% trans "Vaccine sheet:" %}</dt>
<dd class="col-sm-6">
{% if user_object.registration.vaccine_sheet %}
<a href="{{ user_object.registration.vaccine_sheet.url }}" data-turbolinks="false">{% trans "Download" %}</a>
{% endif %}
{% if user_object.registration.team and not user_object.registration.team.participation.valid %}
<button class="btn btn-primary" data-toggle="modal" data-target="#uploadVaccineSheetModal">{% trans "Replace" %}</button>
{% endif %}
</dd>
<dt class="col-sm-6 text-right">{% trans "Parental authorization:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Parental authorization:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% if user_object.registration.parental_authorization %} {% if user_object.registration.parental_authorization %}
@ -107,8 +117,8 @@
<dd class="col-sm-6"><a href="mailto:{{ email }}">{{ email }}</a></dd> <dd class="col-sm-6"><a href="mailto:{{ email }}">{{ email }}</a></dd>
{% endwith %} {% endwith %}
{% elif user_object.registration.is_admin %} {% elif user_object.registration.is_admin %}
<dt class="col-sm-6 text-right">{% trans "Role:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Admin:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.role }}</dd> <dd class="col-sm-6">{{ user_object.registration.is_admin|yesno }}</dd>
{% elif user_object.registration.coachregistration or user_object.registration.is_volunteer %} {% elif user_object.registration.coachregistration or user_object.registration.is_volunteer %}
<dt class="col-sm-6 text-right">{% trans "Profesional activity:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Profesional activity:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.professional_activity }}</dd> <dd class="col-sm-6">{{ user_object.registration.professional_activity }}</dd>
@ -171,6 +181,11 @@
{% url "registration:upload_user_health_sheet" pk=user_object.registration.pk as modal_action %} {% url "registration:upload_user_health_sheet" pk=user_object.registration.pk as modal_action %}
{% include "base_modal.html" with modal_id="uploadHealthSheet" modal_enctype="multipart/form-data" %} {% include "base_modal.html" with modal_id="uploadHealthSheet" modal_enctype="multipart/form-data" %}
{% trans "Upload vaccine sheet" as modal_title %}
{% trans "Upload" as modal_button %}
{% url "registration:upload_user_vaccine_sheet" pk=user_object.registration.pk as modal_action %}
{% include "base_modal.html" with modal_id="uploadVaccineSheet" modal_enctype="multipart/form-data" %}
{% trans "Upload parental authorization" as modal_title %} {% trans "Upload parental authorization" as modal_title %}
{% trans "Upload" as modal_button %} {% trans "Upload" as modal_button %}
{% url "registration:upload_user_parental_authorization" pk=user_object.registration.pk as modal_action %} {% url "registration:upload_user_parental_authorization" pk=user_object.registration.pk as modal_action %}

View File

@ -15,7 +15,7 @@ from django.utils.http import urlsafe_base64_encode
from participation.models import Team from participation.models import Team
from tfjm.tokens import email_validation_token from tfjm.tokens import email_validation_token
from .models import AdminRegistration, CoachRegistration, StudentRegistration from .models import CoachRegistration, StudentRegistration, VolunteerRegistration
class TestIndexPage(TestCase): class TestIndexPage(TestCase):
@ -92,7 +92,7 @@ class TestRegistration(TestCase):
+ f"registration/registration/{self.user.registration.pk}/change/") + f"registration/registration/{self.user.registration.pk}/change/")
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
response = self.client.get(reverse("admin:index") + response = self.client.get(reverse("admin:index") +
f"r/{ContentType.objects.get_for_model(AdminRegistration).id}/" f"r/{ContentType.objects.get_for_model(VolunteerRegistration).id}/"
f"{self.user.registration.pk}/") f"{self.user.registration.pk}/")
self.assertRedirects(response, "http://" + Site.objects.get().domain + self.assertRedirects(response, "http://" + Site.objects.get().domain +
str(self.user.registration.get_absolute_url()), 302, 200) str(self.user.registration.get_absolute_url()), 302, 200)
@ -271,7 +271,7 @@ class TestRegistration(TestCase):
) )
self.student.registration.save() self.student.registration.save()
for user, data in [(self.user, dict(role="Bot")), for user, data in [(self.user, dict(professional_activity="Bot", admin=True)),
(self.student, dict(student_class=11, school="Sky", birth_date="2001-01-01", (self.student, dict(student_class=11, school="Sky", birth_date="2001-01-01",
gender="female", address="1 Rue de Rivoli", zip_code=75001, gender="female", address="1 Rue de Rivoli", zip_code=75001,
city="Paris", responsible_name="Toto", city="Paris", responsible_name="Toto",

View File

@ -7,7 +7,7 @@ from .views import AddOrganizerView, AdultPhotoAuthorizationTemplateView, ChildP
InstructionsTemplateView, MyAccountDetailView, ParentalAuthorizationTemplateView, PaymentUpdateView, \ InstructionsTemplateView, MyAccountDetailView, ParentalAuthorizationTemplateView, PaymentUpdateView, \
ResetAdminView, SignupView, UserDetailView, UserImpersonateView, UserListView, UserResendValidationEmailView, \ ResetAdminView, SignupView, UserDetailView, UserImpersonateView, UserListView, UserResendValidationEmailView, \
UserUpdateView, UserUploadHealthSheetView, UserUploadParentalAuthorizationView, UserUploadPhotoAuthorizationView, \ UserUpdateView, UserUploadHealthSheetView, UserUploadParentalAuthorizationView, UserUploadPhotoAuthorizationView, \
UserValidateView, UserValidationEmailSentView UserUploadVaccineSheetView, UserValidateView, UserValidationEmailSentView
app_name = "registration" app_name = "registration"
@ -32,6 +32,8 @@ urlpatterns = [
path("instructions-template/", InstructionsTemplateView.as_view(), name="instructions_template"), path("instructions-template/", InstructionsTemplateView.as_view(), name="instructions_template"),
path("user/<int:pk>/upload-health-sheet/", UserUploadHealthSheetView.as_view(), path("user/<int:pk>/upload-health-sheet/", UserUploadHealthSheetView.as_view(),
name="upload_user_health_sheet"), name="upload_user_health_sheet"),
path("user/<int:pk>/upload-vaccine-sheet/", UserUploadVaccineSheetView.as_view(),
name="upload_user_vaccine_sheet"),
path("user/<int:pk>/upload-parental-authorization/", UserUploadParentalAuthorizationView.as_view(), path("user/<int:pk>/upload-parental-authorization/", UserUploadParentalAuthorizationView.as_view(),
name="upload_user_parental_authorization"), name="upload_user_parental_authorization"),
path("update-payment/<int:pk>/", PaymentUpdateView.as_view(), name="update_payment"), path("update-payment/<int:pk>/", PaymentUpdateView.as_view(), name="update_payment"),

View File

@ -27,9 +27,9 @@ from participation.models import Passage, Solution, Synthesis, Tournament
from tfjm.tokens import email_validation_token from tfjm.tokens import email_validation_token
from tfjm.views import UserMixin, UserRegistrationMixin, VolunteerMixin from tfjm.views import UserMixin, UserRegistrationMixin, VolunteerMixin
from .forms import AddOrganizerForm, AdminRegistrationForm, CoachRegistrationForm, HealthSheetForm, \ from .forms import AddOrganizerForm, CoachRegistrationForm, HealthSheetForm, \
ParentalAuthorizationForm, PaymentForm, PhotoAuthorizationForm, SignupForm, StudentRegistrationForm, UserForm, \ ParentalAuthorizationForm, PaymentForm, PhotoAuthorizationForm, SignupForm, StudentRegistrationForm, UserForm, \
VolunteerRegistrationForm VaccineSheetForm, VolunteerRegistrationForm
from .models import ParticipantRegistration, Payment, Registration, StudentRegistration from .models import ParticipantRegistration, Payment, Registration, StudentRegistration
from .tables import RegistrationTable from .tables import RegistrationTable
@ -91,23 +91,20 @@ class AddOrganizerView(VolunteerMixin, CreateView):
context = super().get_context_data() context = super().get_context_data()
context["volunteer_registration_form"] = VolunteerRegistrationForm(self.request.POST or None) context["volunteer_registration_form"] = VolunteerRegistrationForm(self.request.POST or None)
context["admin_registration_form"] = AdminRegistrationForm(self.request.POST or None)
del context["volunteer_registration_form"].fields["email_confirmed"] del context["volunteer_registration_form"].fields["email_confirmed"]
del context["admin_registration_form"].fields["email_confirmed"]
if not self.request.user.registration.is_admin:
context["form"].fields["type"].widget.attrs['readonly'] = True
del context["admin_registration_form"]
return context return context
def get_form(self, form_class=None):
form = super().get_form(form_class)
if not self.request.user.registration.is_admin:
del form.fields["admin"]
return form
@transaction.atomic @transaction.atomic
def form_valid(self, form): def form_valid(self, form):
role = form.cleaned_data["type"]
if role == "admin":
registration_form = AdminRegistrationForm(self.request.POST)
else:
registration_form = VolunteerRegistrationForm(self.request.POST) registration_form = VolunteerRegistrationForm(self.request.POST)
del registration_form.fields["email_confirmed"] del registration_form.fields["email_confirmed"]
@ -347,6 +344,27 @@ class UserUploadHealthSheetView(UserRegistrationMixin, UpdateView):
return reverse_lazy("registration:user_detail", args=(self.object.user.pk,)) return reverse_lazy("registration:user_detail", args=(self.object.user.pk,))
class UserUploadVaccineSheetView(UserRegistrationMixin, UpdateView):
"""
A participant can send its vaccine sheet.
"""
model = StudentRegistration
form_class = VaccineSheetForm
template_name = "registration/upload_vaccine_sheet.html"
extra_context = dict(title=_("Upload vaccine sheet"))
@transaction.atomic
def form_valid(self, form):
old_instance = StudentRegistration.objects.get(pk=self.object.pk)
if old_instance.vaccine_sheet:
old_instance.vaccine_sheet.delete()
old_instance.save()
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("registration:user_detail", args=(self.object.user.pk,))
class UserUploadParentalAuthorizationView(UserRegistrationMixin, UpdateView): class UserUploadParentalAuthorizationView(UserRegistrationMixin, UpdateView):
""" """
A participant can send its parental authorization. A participant can send its parental authorization.
@ -487,6 +505,29 @@ class HealthSheetView(LoginRequiredMixin, View):
return FileResponse(open(path, "rb"), content_type=mime_type, filename=true_file_name) return FileResponse(open(path, "rb"), content_type=mime_type, filename=true_file_name)
class VaccineSheetView(LoginRequiredMixin, View):
"""
Display the sent health sheet.
"""
def get(self, request, *args, **kwargs):
filename = kwargs["filename"]
path = f"media/authorization/vaccine/{filename}"
if not os.path.exists(path):
raise Http404
student = StudentRegistration.objects.get(vaccine_sheet__endswith=filename)
user = request.user
if not (student.user == user or user.registration.is_admin or user.registration.is_volunteer and student.team
and student.team.participation.tournament in user.registration.organized_tournaments.all()):
raise PermissionDenied
# Guess mime type of the file
mime = Magic(mime=True)
mime_type = mime.from_file(path)
ext = mime_type.split("/")[1].replace("jpeg", "jpg")
# Replace file name
true_file_name = _("Vaccine sheet of {student}.{ext}").format(student=str(student), ext=ext)
return FileResponse(open(path, "rb"), content_type=mime_type, filename=true_file_name)
class ParentalAuthorizationView(LoginRequiredMixin, View): class ParentalAuthorizationView(LoginRequiredMixin, View):
""" """
Display the sent parental authorization. Display the sent parental authorization.

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: TFJM\n" "Project-Id-Version: TFJM\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-02-19 19:48+0100\n" "POT-Creation-Date: 2023-02-20 00:37+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n" "Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -100,83 +100,84 @@ msgid "Changelog of type \"{action}\" for model {model} at {timestamp}"
msgstr "Changelog de type \"{action}\" pour le modèle {model} le {timestamp}" msgstr "Changelog de type \"{action}\" pour le modèle {model} le {timestamp}"
#: apps/participation/admin.py:19 apps/participation/models.py:318 #: apps/participation/admin.py:19 apps/participation/models.py:318
#: apps/participation/tables.py:44 apps/registration/models.py:370 #: apps/participation/tables.py:44 apps/registration/models.py:364
msgid "valid" msgid "valid"
msgstr "valide" msgstr "valide"
#: apps/participation/forms.py:29 #: apps/participation/forms.py:28
msgid "This name is already used." msgid "This name is already used."
msgstr "Ce nom est déjà utilisé." msgstr "Ce nom est déjà utilisé."
#: apps/participation/forms.py:36 apps/participation/models.py:40 #: apps/participation/forms.py:35 apps/participation/models.py:40
msgid "The trigram must be composed of three uppercase letters." msgid "The trigram must be composed of three uppercase letters."
msgstr "Le trigramme doit être composé de trois lettres majuscules." msgstr "Le trigramme doit être composé de trois lettres majuscules."
#: apps/participation/forms.py:39 #: apps/participation/forms.py:38
msgid "This trigram is already used." msgid "This trigram is already used."
msgstr "Ce trigramme est déjà utilisé." msgstr "Ce trigramme est déjà utilisé."
#: apps/participation/forms.py:54 #: apps/participation/forms.py:53
msgid "No team was found with this access code." msgid "No team was found with this access code."
msgstr "Aucune équipe n'a été trouvée avec ce code d'accès." msgstr "Aucune équipe n'a été trouvée avec ce code d'accès."
#: apps/participation/forms.py:83 apps/participation/forms.py:281 #: apps/participation/forms.py:82 apps/participation/forms.py:280
#: apps/registration/forms.py:121 apps/registration/forms.py:143 #: apps/registration/forms.py:113 apps/registration/forms.py:135
#: apps/registration/forms.py:165 apps/registration/forms.py:219 #: apps/registration/forms.py:157 apps/registration/forms.py:179
#: apps/registration/forms.py:224
msgid "The uploaded file size must be under 2 Mo." msgid "The uploaded file size must be under 2 Mo."
msgstr "Le fichier envoyé doit peser moins de 2 Mo." msgstr "Le fichier envoyé doit peser moins de 2 Mo."
#: apps/participation/forms.py:85 apps/registration/forms.py:123 #: apps/participation/forms.py:84 apps/registration/forms.py:115
#: apps/registration/forms.py:145 apps/registration/forms.py:167 #: apps/registration/forms.py:137 apps/registration/forms.py:159
#: apps/registration/forms.py:221 #: apps/registration/forms.py:181 apps/registration/forms.py:226
msgid "The uploaded file must be a PDF, PNG of JPEG file." msgid "The uploaded file must be a PDF, PNG of JPEG file."
msgstr "Le fichier envoyé doit être au format PDF, PNG ou JPEG." msgstr "Le fichier envoyé doit être au format PDF, PNG ou JPEG."
#: apps/participation/forms.py:103 #: apps/participation/forms.py:102
msgid "I engage myself to participate to the whole TFJM²." msgid "I engage myself to participate to the whole TFJM²."
msgstr "Je m'engage à participer à l'intégralité du TFJM²." msgstr "Je m'engage à participer à l'intégralité du TFJM²."
#: apps/participation/forms.py:118 #: apps/participation/forms.py:117
msgid "Message to address to the team:" msgid "Message to address to the team:"
msgstr "Message à adresser à l'équipe :" msgstr "Message à adresser à l'équipe :"
#: apps/participation/forms.py:154 #: apps/participation/forms.py:153
msgid "The uploaded file size must be under 5 Mo." msgid "The uploaded file size must be under 5 Mo."
msgstr "Le fichier envoyé doit peser moins de 5 Mo." msgstr "Le fichier envoyé doit peser moins de 5 Mo."
#: apps/participation/forms.py:156 apps/participation/forms.py:283 #: apps/participation/forms.py:155 apps/participation/forms.py:282
msgid "The uploaded file must be a PDF file." msgid "The uploaded file must be a PDF file."
msgstr "Le fichier envoyé doit être au format PDF." msgstr "Le fichier envoyé doit être au format PDF."
#: apps/participation/forms.py:160 #: apps/participation/forms.py:159
msgid "The PDF file must not have more than 30 pages." msgid "The PDF file must not have more than 30 pages."
msgstr "Le fichier PDF ne doit pas avoir plus de 30 pages." msgstr "Le fichier PDF ne doit pas avoir plus de 30 pages."
#: apps/participation/forms.py:197 #: apps/participation/forms.py:196
msgid "CSV file:" msgid "CSV file:"
msgstr "Tableur au format CSV :" msgstr "Tableur au format CSV :"
#: apps/participation/forms.py:214 #: apps/participation/forms.py:213
msgid "" msgid ""
"This file contains non-UTF-8 content. Please send your sheet as a CSV file." "This file contains non-UTF-8 content. Please send your sheet as a CSV file."
msgstr "" msgstr ""
"Ce fichier contient des éléments non-UTF-8. Merci d'envoyer votre tableur au " "Ce fichier contient des éléments non-UTF-8. Merci d'envoyer votre tableur au "
"format CSV." "format CSV."
#: apps/participation/forms.py:239 #: apps/participation/forms.py:238
msgid "The following note is higher of the maximum expected value:" msgid "The following note is higher of the maximum expected value:"
msgstr "La note suivante est supérieure au maximum attendu :" msgstr "La note suivante est supérieure au maximum attendu :"
#: apps/participation/forms.py:247 #: apps/participation/forms.py:246
msgid "The following user was not found:" msgid "The following user was not found:"
msgstr "L'utilisateur⋅rice suivant n'a pas été trouvé :" msgstr "L'utilisateur⋅rice suivant n'a pas été trouvé :"
#: apps/participation/forms.py:264 #: apps/participation/forms.py:263
msgid "The defender, the opponent and the reporter must be different." msgid "The defender, the opponent and the reporter must be different."
msgstr "" msgstr ""
"Læ défenseur⋅se, l'opposant⋅e et læ rapporteur⋅e doivent être différent⋅es." "Læ défenseur⋅se, l'opposant⋅e et læ rapporteur⋅e doivent être différent⋅es."
#: apps/participation/forms.py:268 #: apps/participation/forms.py:267
msgid "This defender did not work on this problem." msgid "This defender did not work on this problem."
msgstr "Ce⋅tte défenseur⋅se ne travaille pas sur ce problème." msgstr "Ce⋅tte défenseur⋅se ne travaille pas sur ce problème."
@ -211,7 +212,7 @@ msgid "Team {name} ({trigram})"
msgstr "Équipe {name} ({trigram})" msgstr "Équipe {name} ({trigram})"
#: apps/participation/models.py:125 apps/participation/models.py:303 #: apps/participation/models.py:125 apps/participation/models.py:303
#: apps/registration/models.py:123 #: apps/registration/models.py:127
msgid "team" msgid "team"
msgstr "équipe" msgstr "équipe"
@ -597,14 +598,14 @@ msgstr "Rejoindre"
#: apps/participation/templates/participation/pool_detail.html:55 #: apps/participation/templates/participation/pool_detail.html:55
#: apps/participation/templates/participation/pool_detail.html:74 #: apps/participation/templates/participation/pool_detail.html:74
#: apps/participation/templates/participation/pool_detail.html:79 #: apps/participation/templates/participation/pool_detail.html:79
#: apps/participation/templates/participation/team_detail.html:113 #: apps/participation/templates/participation/team_detail.html:126
#: apps/participation/templates/participation/team_detail.html:177 #: apps/participation/templates/participation/team_detail.html:190
#: apps/participation/templates/participation/tournament_form.html:12 #: apps/participation/templates/participation/tournament_form.html:12
#: apps/participation/templates/participation/update_team.html:12 #: apps/participation/templates/participation/update_team.html:12
#: apps/registration/templates/registration/payment_form.html:49 #: apps/registration/templates/registration/payment_form.html:49
#: apps/registration/templates/registration/update_user.html:16 #: apps/registration/templates/registration/update_user.html:16
#: apps/registration/templates/registration/user_detail.html:155 #: apps/registration/templates/registration/user_detail.html:165
#: apps/registration/templates/registration/user_detail.html:187 #: apps/registration/templates/registration/user_detail.html:202
msgid "Update" msgid "Update"
msgstr "Modifier" msgstr "Modifier"
@ -661,7 +662,7 @@ msgstr "Envoyer une solution"
#: apps/participation/templates/participation/participation_detail.html:59 #: apps/participation/templates/participation/participation_detail.html:59
#: apps/participation/templates/participation/passage_detail.html:114 #: apps/participation/templates/participation/passage_detail.html:114
#: apps/participation/templates/participation/pool_detail.html:84 #: apps/participation/templates/participation/pool_detail.html:84
#: apps/participation/templates/participation/team_detail.html:172 #: apps/participation/templates/participation/team_detail.html:185
#: apps/participation/templates/participation/upload_motivation_letter.html:13 #: apps/participation/templates/participation/upload_motivation_letter.html:13
#: apps/participation/templates/participation/upload_notes.html:12 #: apps/participation/templates/participation/upload_notes.html:12
#: apps/participation/templates/participation/upload_solution.html:11 #: apps/participation/templates/participation/upload_solution.html:11
@ -669,10 +670,12 @@ msgstr "Envoyer une solution"
#: apps/registration/templates/registration/upload_health_sheet.html:17 #: apps/registration/templates/registration/upload_health_sheet.html:17
#: apps/registration/templates/registration/upload_parental_authorization.html:17 #: apps/registration/templates/registration/upload_parental_authorization.html:17
#: apps/registration/templates/registration/upload_photo_authorization.html:18 #: apps/registration/templates/registration/upload_photo_authorization.html:18
#: apps/registration/templates/registration/user_detail.html:165 #: apps/registration/templates/registration/upload_vaccine_sheet.html:13
#: apps/registration/templates/registration/user_detail.html:170
#: apps/registration/templates/registration/user_detail.html:175 #: apps/registration/templates/registration/user_detail.html:175
#: apps/registration/templates/registration/user_detail.html:180 #: apps/registration/templates/registration/user_detail.html:180
#: apps/registration/templates/registration/user_detail.html:185
#: apps/registration/templates/registration/user_detail.html:190
#: apps/registration/templates/registration/user_detail.html:195
msgid "Upload" msgid "Upload"
msgstr "Téléverser" msgstr "Téléverser"
@ -852,7 +855,8 @@ msgstr "Autorisations de droit à l'image :"
#: apps/participation/templates/participation/team_detail.html:58 #: apps/participation/templates/participation/team_detail.html:58
#: apps/participation/templates/participation/team_detail.html:71 #: apps/participation/templates/participation/team_detail.html:71
#: apps/participation/templates/participation/team_detail.html:84 #: apps/participation/templates/participation/team_detail.html:84
#: apps/participation/templates/participation/team_detail.html:96 #: apps/participation/templates/participation/team_detail.html:97
#: apps/participation/templates/participation/team_detail.html:109
msgid "Not uploaded yet" msgid "Not uploaded yet"
msgstr "Pas encore envoyée" msgstr "Pas encore envoyée"
@ -861,44 +865,50 @@ msgid "Health sheets:"
msgstr "Fiches sanitaires :" msgstr "Fiches sanitaires :"
#: apps/participation/templates/participation/team_detail.html:77 #: apps/participation/templates/participation/team_detail.html:77
msgid "Vaccine sheets:"
msgstr "Carnets de vaccination :"
#: apps/participation/templates/participation/team_detail.html:90
msgid "Parental authorizations:" msgid "Parental authorizations:"
msgstr "Autorisations parentales :" msgstr "Autorisations parentales :"
#: apps/participation/templates/participation/team_detail.html:91 #: apps/participation/templates/participation/team_detail.html:104
msgid "Motivation letter:" msgid "Motivation letter:"
msgstr "Lettre de motivation :" msgstr "Lettre de motivation :"
#: apps/participation/templates/participation/team_detail.html:94 #: apps/participation/templates/participation/team_detail.html:107
#: apps/registration/templates/registration/upload_health_sheet.html:12 #: apps/registration/templates/registration/upload_health_sheet.html:12
#: apps/registration/templates/registration/upload_parental_authorization.html:12 #: apps/registration/templates/registration/upload_parental_authorization.html:12
#: apps/registration/templates/registration/user_detail.html:62 #: apps/registration/templates/registration/user_detail.html:62
#: apps/registration/templates/registration/user_detail.html:75 #: apps/registration/templates/registration/user_detail.html:75
#: apps/registration/templates/registration/user_detail.html:85 #: apps/registration/templates/registration/user_detail.html:85
#: apps/registration/templates/registration/user_detail.html:95
msgid "Download" msgid "Download"
msgstr "Télécharger" msgstr "Télécharger"
#: apps/participation/templates/participation/team_detail.html:99 #: apps/participation/templates/participation/team_detail.html:112
#: apps/registration/templates/registration/user_detail.html:65 #: apps/registration/templates/registration/user_detail.html:65
#: apps/registration/templates/registration/user_detail.html:78 #: apps/registration/templates/registration/user_detail.html:78
#: apps/registration/templates/registration/user_detail.html:88 #: apps/registration/templates/registration/user_detail.html:88
#: apps/registration/templates/registration/user_detail.html:98
msgid "Replace" msgid "Replace"
msgstr "Remplacer" msgstr "Remplacer"
#: apps/participation/templates/participation/team_detail.html:107 #: apps/participation/templates/participation/team_detail.html:120
msgid "Download all submitted authorizations" msgid "Download all submitted authorizations"
msgstr "Télécharger toutes les autorisations soumises" msgstr "Télécharger toutes les autorisations soumises"
#: apps/participation/templates/participation/team_detail.html:115 #: apps/participation/templates/participation/team_detail.html:128
#: apps/participation/templates/participation/team_detail.html:182 #: apps/participation/templates/participation/team_detail.html:195
#: apps/participation/templates/participation/team_leave.html:11 #: apps/participation/templates/participation/team_leave.html:11
msgid "Leave" msgid "Leave"
msgstr "Quitter" msgstr "Quitter"
#: apps/participation/templates/participation/team_detail.html:125 #: apps/participation/templates/participation/team_detail.html:138
msgid "Access to team participation" msgid "Access to team participation"
msgstr "Accéder à la participation de l'équipe" msgstr "Accéder à la participation de l'équipe"
#: apps/participation/templates/participation/team_detail.html:132 #: apps/participation/templates/participation/team_detail.html:145
msgid "" msgid ""
"Your team has at least 4 members and a coach and all authorizations were " "Your team has at least 4 members and a coach and all authorizations were "
"given: the team can be validated." "given: the team can be validated."
@ -906,11 +916,11 @@ msgstr ""
"Votre équipe contient au moins 4 personnes et un⋅e encadrant⋅e et toutes les " "Votre équipe contient au moins 4 personnes et un⋅e encadrant⋅e et toutes les "
"autorisations ont été données : l'équipe peut être validée." "autorisations ont été données : l'équipe peut être validée."
#: apps/participation/templates/participation/team_detail.html:137 #: apps/participation/templates/participation/team_detail.html:150
msgid "Submit my team to validation" msgid "Submit my team to validation"
msgstr "Soumettre mon équipe à validation" msgstr "Soumettre mon équipe à validation"
#: apps/participation/templates/participation/team_detail.html:143 #: apps/participation/templates/participation/team_detail.html:156
msgid "" msgid ""
"Your team must be composed of 4 members and a coach and each member must " "Your team must be composed of 4 members and a coach and each member must "
"upload their authorizations and confirm its email address." "upload their authorizations and confirm its email address."
@ -918,15 +928,15 @@ msgstr ""
"Votre équipe doit être composée d'au moins 4 membres et un⋅e encadrant⋅e et " "Votre équipe doit être composée d'au moins 4 membres et un⋅e encadrant⋅e et "
"chaque membre doit envoyer ses autorisations et confirmé son adresse e-mail." "chaque membre doit envoyer ses autorisations et confirmé son adresse e-mail."
#: apps/participation/templates/participation/team_detail.html:148 #: apps/participation/templates/participation/team_detail.html:161
msgid "This team didn't ask for validation yet." msgid "This team didn't ask for validation yet."
msgstr "L'équipe n'a pas encore demandé à être validée." msgstr "L'équipe n'a pas encore demandé à être validée."
#: apps/participation/templates/participation/team_detail.html:154 #: apps/participation/templates/participation/team_detail.html:167
msgid "Your validation is pending." msgid "Your validation is pending."
msgstr "Votre validation est en attente." msgstr "Votre validation est en attente."
#: apps/participation/templates/participation/team_detail.html:158 #: apps/participation/templates/participation/team_detail.html:171
msgid "" msgid ""
"The team requested to be validated. You may now control the authorizations " "The team requested to be validated. You may now control the authorizations "
"and confirm that they can participate." "and confirm that they can participate."
@ -934,25 +944,25 @@ msgstr ""
"L'équipe a demandé à être validée. Vous pouvez désormais contrôler les " "L'équipe a demandé à être validée. Vous pouvez désormais contrôler les "
"différentes autorisations et confirmer qu'elle peut participer." "différentes autorisations et confirmer qu'elle peut participer."
#: apps/participation/templates/participation/team_detail.html:164 #: apps/participation/templates/participation/team_detail.html:177
msgid "Validate" msgid "Validate"
msgstr "Valider" msgstr "Valider"
#: apps/participation/templates/participation/team_detail.html:165 #: apps/participation/templates/participation/team_detail.html:178
msgid "Invalidate" msgid "Invalidate"
msgstr "Invalider" msgstr "Invalider"
#: apps/participation/templates/participation/team_detail.html:171 #: apps/participation/templates/participation/team_detail.html:184
#: apps/participation/views.py:332 #: apps/participation/views.py:333
msgid "Upload motivation letter" msgid "Upload motivation letter"
msgstr "Envoyer la lettre de motivation" msgstr "Envoyer la lettre de motivation"
#: apps/participation/templates/participation/team_detail.html:176 #: apps/participation/templates/participation/team_detail.html:189
msgid "Update team" msgid "Update team"
msgstr "Modifier l'équipe" msgstr "Modifier l'équipe"
#: apps/participation/templates/participation/team_detail.html:181 #: apps/participation/templates/participation/team_detail.html:194
#: apps/participation/views.py:435 #: apps/participation/views.py:442
msgid "Leave team" msgid "Leave team"
msgstr "Quitter l'équipe" msgstr "Quitter l'équipe"
@ -1082,12 +1092,12 @@ msgstr "Vous êtes déjà dans une équipe."
msgid "Join team" msgid "Join team"
msgstr "Rejoindre une équipe" msgstr "Rejoindre une équipe"
#: apps/participation/views.py:151 apps/participation/views.py:441 #: apps/participation/views.py:151 apps/participation/views.py:448
#: apps/participation/views.py:475 #: apps/participation/views.py:482
msgid "You are not in a team." msgid "You are not in a team."
msgstr "Vous n'êtes pas dans une équipe." msgstr "Vous n'êtes pas dans une équipe."
#: apps/participation/views.py:152 apps/participation/views.py:476 #: apps/participation/views.py:152 apps/participation/views.py:483
msgid "You don't participate, so you don't have any team." msgid "You don't participate, so you don't have any team."
msgstr "Vous ne participez pas, vous n'avez donc pas d'équipe." msgstr "Vous ne participez pas, vous n'avez donc pas d'équipe."
@ -1096,17 +1106,17 @@ msgstr "Vous ne participez pas, vous n'avez donc pas d'équipe."
msgid "Detail of team {trigram}" msgid "Detail of team {trigram}"
msgstr "Détails de l'équipe {trigram}" msgstr "Détails de l'équipe {trigram}"
#: apps/participation/views.py:214 #: apps/participation/views.py:215
msgid "You don't participate, so you can't request the validation of the team." msgid "You don't participate, so you can't request the validation of the team."
msgstr "" msgstr ""
"Vous ne participez pas, vous ne pouvez pas demander la validation de " "Vous ne participez pas, vous ne pouvez pas demander la validation de "
"l'équipe." "l'équipe."
#: apps/participation/views.py:217 #: apps/participation/views.py:218
msgid "The validation of the team is already done or pending." msgid "The validation of the team is already done or pending."
msgstr "La validation de l'équipe est déjà faite ou en cours." msgstr "La validation de l'équipe est déjà faite ou en cours."
#: apps/participation/views.py:220 #: apps/participation/views.py:221
msgid "" msgid ""
"The team can't be validated: missing email address confirmations, " "The team can't be validated: missing email address confirmations, "
"authorizations, people, motivation letter or the tournament is not set." "authorizations, people, motivation letter or the tournament is not set."
@ -1115,78 +1125,83 @@ msgstr ""
"d'adresse e-mail, soit une autorisation, soit des personnes, soit la lettre " "d'adresse e-mail, soit une autorisation, soit des personnes, soit la lettre "
"de motivation, soit le tournoi n'a pas été choisi." "de motivation, soit le tournoi n'a pas été choisi."
#: apps/participation/views.py:242 #: apps/participation/views.py:243
msgid "You are not an organizer of the tournament." msgid "You are not an organizer of the tournament."
msgstr "Vous n'êtes pas un⋅e organisateur⋅rice du tournoi." msgstr "Vous n'êtes pas un⋅e organisateur⋅rice du tournoi."
#: apps/participation/views.py:245 #: apps/participation/views.py:246
msgid "This team has no pending validation." msgid "This team has no pending validation."
msgstr "L'équipe n'a pas de validation en attente." msgstr "L'équipe n'a pas de validation en attente."
#: apps/participation/views.py:275 #: apps/participation/views.py:276
msgid "You must specify if you validate the registration or not." msgid "You must specify if you validate the registration or not."
msgstr "Vous devez spécifier si vous validez l'inscription ou non." msgstr "Vous devez spécifier si vous validez l'inscription ou non."
#: apps/participation/views.py:310 #: apps/participation/views.py:311
#, python-brace-format #, python-brace-format
msgid "Update team {trigram}" msgid "Update team {trigram}"
msgstr "Mise à jour de l'équipe {trigram}" msgstr "Mise à jour de l'équipe {trigram}"
#: apps/participation/views.py:371 apps/participation/views.py:421 #: apps/participation/views.py:372 apps/participation/views.py:428
#, python-brace-format #, python-brace-format
msgid "Motivation letter of {team}.{ext}" msgid "Motivation letter of {team}.{ext}"
msgstr "Lettre de motivation de {team}.{ext}" msgstr "Lettre de motivation de {team}.{ext}"
#: apps/participation/views.py:402 #: apps/participation/views.py:403
#, python-brace-format #, python-brace-format
msgid "Photo authorization of {participant}.{ext}" msgid "Photo authorization of {participant}.{ext}"
msgstr "Autorisation de droit à l'image de {participant}.{ext}" msgstr "Autorisation de droit à l'image de {participant}.{ext}"
#: apps/participation/views.py:408 #: apps/participation/views.py:409
#, python-brace-format #, python-brace-format
msgid "Parental authorization of {participant}.{ext}" msgid "Parental authorization of {participant}.{ext}"
msgstr "Autorisation parentale de {participant}.{ext}" msgstr "Autorisation parentale de {participant}.{ext}"
#: apps/participation/views.py:415 #: apps/participation/views.py:416
#, python-brace-format #, python-brace-format
msgid "Health sheet of {participant}.{ext}" msgid "Health sheet of {participant}.{ext}"
msgstr "Fiche sanitaire de {participant}.{ext}" msgstr "Fiche sanitaire de {participant}.{ext}"
#: apps/participation/views.py:425 #: apps/participation/views.py:422
#, python-brace-format
msgid "Vaccine sheet of {participant}.{ext}"
msgstr "Carnet de vaccination de {participant}.{ext}"
#: apps/participation/views.py:432
#, python-brace-format #, python-brace-format
msgid "Photo authorizations of team {trigram}.zip" msgid "Photo authorizations of team {trigram}.zip"
msgstr "Autorisations de droit à l'image de l'équipe {trigram}.zip" msgstr "Autorisations de droit à l'image de l'équipe {trigram}.zip"
#: apps/participation/views.py:443 #: apps/participation/views.py:450
msgid "The team is already validated or the validation is pending." msgid "The team is already validated or the validation is pending."
msgstr "La validation de l'équipe est déjà faite ou en cours." msgstr "La validation de l'équipe est déjà faite ou en cours."
#: apps/participation/views.py:490 #: apps/participation/views.py:497
msgid "The team is not validated yet." msgid "The team is not validated yet."
msgstr "L'équipe n'est pas encore validée." msgstr "L'équipe n'est pas encore validée."
#: apps/participation/views.py:504 #: apps/participation/views.py:511
#, python-brace-format #, python-brace-format
msgid "Participation of team {trigram}" msgid "Participation of team {trigram}"
msgstr "Participation de l'équipe {trigram}" msgstr "Participation de l'équipe {trigram}"
#: apps/participation/views.py:630 #: apps/participation/views.py:637
msgid "You can't upload a solution after the deadline." msgid "You can't upload a solution after the deadline."
msgstr "Vous ne pouvez pas envoyer de solution après la date limite." msgstr "Vous ne pouvez pas envoyer de solution après la date limite."
#: apps/participation/views.py:733 #: apps/participation/views.py:740
msgid "The following user is not registered as a jury:" msgid "The following user is not registered as a jury:"
msgstr "L'utilisateur⋅rice suivant n'est pas inscrit⋅e en tant que juré⋅e :" msgstr "L'utilisateur⋅rice suivant n'est pas inscrit⋅e en tant que juré⋅e :"
#: apps/participation/views.py:741 #: apps/participation/views.py:748
msgid "Notes were successfully uploaded." msgid "Notes were successfully uploaded."
msgstr "Les notes ont bien été envoyées." msgstr "Les notes ont bien été envoyées."
#: apps/participation/views.py:853 #: apps/participation/views.py:860
msgid "You can't upload a synthesis after the deadline." msgid "You can't upload a synthesis after the deadline."
msgstr "Vous ne pouvez pas envoyer de note de synthèse après la date limite." msgstr "Vous ne pouvez pas envoyer de note de synthèse après la date limite."
#: apps/registration/forms.py:22 apps/registration/forms.py:54 #: apps/registration/forms.py:22
msgid "role" msgid "role"
msgstr "rôle" msgstr "rôle"
@ -1194,27 +1209,19 @@ msgstr "rôle"
msgid "participant" msgid "participant"
msgstr "participant⋅e" msgstr "participant⋅e"
#: apps/registration/forms.py:25 apps/registration/models.py:270 #: apps/registration/forms.py:25 apps/registration/models.py:281
msgid "coach" msgid "coach"
msgstr "encadrant⋅e" msgstr "encadrant⋅e"
#: apps/registration/forms.py:35 apps/registration/forms.py:68 #: apps/registration/forms.py:35 apps/registration/forms.py:60
msgid "This email address is already used." msgid "This email address is already used."
msgstr "Cette adresse e-mail est déjà utilisée." msgstr "Cette adresse e-mail est déjà utilisée."
#: apps/registration/forms.py:56 apps/registration/models.py:296 #: apps/registration/forms.py:218
msgid "volunteer"
msgstr "bénévole"
#: apps/registration/forms.py:57 apps/registration/models.py:315
msgid "admin"
msgstr "admin"
#: apps/registration/forms.py:213
msgid "Pending" msgid "Pending"
msgstr "En attente" msgstr "En attente"
#: apps/registration/forms.py:229 #: apps/registration/forms.py:234
msgid "You must upload your scholarship attestation." msgid "You must upload your scholarship attestation."
msgstr "Vous devez envoyer votre attestation de bourse." msgstr "Vous devez envoyer votre attestation de bourse."
@ -1231,7 +1238,7 @@ msgstr "email confirmé"
msgid "Activate your TFJM² account" msgid "Activate your TFJM² account"
msgstr "Activez votre compte du TFJM²" msgstr "Activez votre compte du TFJM²"
#: apps/registration/models.py:99 apps/registration/models.py:336 #: apps/registration/models.py:99 apps/registration/models.py:330
msgid "registration" msgid "registration"
msgstr "inscription" msgstr "inscription"
@ -1239,43 +1246,43 @@ msgstr "inscription"
msgid "registrations" msgid "registrations"
msgstr "inscriptions" msgstr "inscriptions"
#: apps/registration/models.py:128 #: apps/registration/models.py:132
msgid "gender" msgid "gender"
msgstr "genre" msgstr "genre"
#: apps/registration/models.py:130 #: apps/registration/models.py:134
msgid "Female" msgid "Female"
msgstr "Femme" msgstr "Femme"
#: apps/registration/models.py:131 #: apps/registration/models.py:135
msgid "Male" msgid "Male"
msgstr "Homme" msgstr "Homme"
#: apps/registration/models.py:132 #: apps/registration/models.py:136
msgid "Other" msgid "Other"
msgstr "Autre" msgstr "Autre"
#: apps/registration/models.py:139 #: apps/registration/models.py:143
msgid "address" msgid "address"
msgstr "adresse" msgstr "adresse"
#: apps/registration/models.py:143 #: apps/registration/models.py:147
msgid "zip code" msgid "zip code"
msgstr "code postal" msgstr "code postal"
#: apps/registration/models.py:149 #: apps/registration/models.py:153
msgid "city" msgid "city"
msgstr "ville" msgstr "ville"
#: apps/registration/models.py:153 #: apps/registration/models.py:157
msgid "phone number" msgid "phone number"
msgstr "numéro de téléphone" msgstr "numéro de téléphone"
#: apps/registration/models.py:158 #: apps/registration/models.py:162
msgid "health issues" msgid "health issues"
msgstr "problèmes de santé" msgstr "problèmes de santé"
#: apps/registration/models.py:160 #: apps/registration/models.py:164
msgid "" msgid ""
"You can indicate here your allergies or anything that is important to know " "You can indicate here your allergies or anything that is important to know "
"for organizers" "for organizers"
@ -1283,140 +1290,152 @@ msgstr ""
"Vous pouvez indiquer ici vos allergies ou n'importe quoi qui peut être bon à " "Vous pouvez indiquer ici vos allergies ou n'importe quoi qui peut être bon à "
"savoir pour les organisateur⋅rices" "savoir pour les organisateur⋅rices"
#: apps/registration/models.py:164 #: apps/registration/models.py:168
msgid "photo authorization" msgid "photo authorization"
msgstr "autorisation de droit à l'image" msgstr "autorisation de droit à l'image"
#: apps/registration/models.py:197 #: apps/registration/models.py:201
msgid "birth date" msgid "birth date"
msgstr "date de naissance" msgstr "date de naissance"
#: apps/registration/models.py:203 #: apps/registration/models.py:207
msgid "12th grade" msgid "12th grade"
msgstr "Terminale" msgstr "Terminale"
#: apps/registration/models.py:204 #: apps/registration/models.py:208
msgid "11th grade" msgid "11th grade"
msgstr "Première" msgstr "Première"
#: apps/registration/models.py:205 #: apps/registration/models.py:209
msgid "10th grade or lower" msgid "10th grade or lower"
msgstr "Seconde ou inférieur" msgstr "Seconde ou inférieur"
#: apps/registration/models.py:207 #: apps/registration/models.py:211
msgid "student class" msgid "student class"
msgstr "classe" msgstr "classe"
#: apps/registration/models.py:212 #: apps/registration/models.py:216
msgid "school" msgid "school"
msgstr "école" msgstr "école"
#: apps/registration/models.py:217 #: apps/registration/models.py:221
msgid "responsible name" msgid "responsible name"
msgstr "nom de læ responsable légal⋅e" msgstr "nom de læ responsable légal⋅e"
#: apps/registration/models.py:222 #: apps/registration/models.py:226
msgid "responsible phone number" msgid "responsible phone number"
msgstr "numéro de téléphone de læ responsable légal⋅e" msgstr "numéro de téléphone de læ responsable légal⋅e"
#: apps/registration/models.py:227 #: apps/registration/models.py:231
msgid "responsible email address" msgid "responsible email address"
msgstr "adresse e-mail de læ responsable légal⋅e" msgstr "adresse e-mail de læ responsable légal⋅e"
#: apps/registration/models.py:232 #: apps/registration/models.py:236
msgid "parental authorization" msgid "parental authorization"
msgstr "autorisation parentale" msgstr "autorisation parentale"
#: apps/registration/models.py:239 #: apps/registration/models.py:243
msgid "health sheet" msgid "health sheet"
msgstr "fiche sanitaire" msgstr "fiche sanitaire"
#: apps/registration/models.py:247 #: apps/registration/models.py:250
msgid "vaccine sheet"
msgstr "carnet de vaccination"
#: apps/registration/models.py:258
msgid "student" msgid "student"
msgstr "étudiant⋅e" msgstr "étudiant⋅e"
#: apps/registration/models.py:255 #: apps/registration/models.py:266
msgid "student registration" msgid "student registration"
msgstr "inscription d'élève" msgstr "inscription d'élève"
#: apps/registration/models.py:256 #: apps/registration/models.py:267
msgid "student registrations" msgid "student registrations"
msgstr "inscriptions d'élève" msgstr "inscriptions d'élève"
#: apps/registration/models.py:265 apps/registration/models.py:287 #: apps/registration/models.py:276 apps/registration/models.py:298
msgid "professional activity" msgid "professional activity"
msgstr "activité professionnelle" msgstr "activité professionnelle"
#: apps/registration/models.py:278 #: apps/registration/models.py:289
msgid "coach registration" msgid "coach registration"
msgstr "inscription d'encadrant⋅e" msgstr "inscription d'encadrant⋅e"
#: apps/registration/models.py:279 #: apps/registration/models.py:290
msgid "coach registrations" msgid "coach registrations"
msgstr "inscriptions d'encadrant⋅es" msgstr "inscriptions d'encadrant⋅es"
#: apps/registration/models.py:310 #: apps/registration/models.py:302
msgid "role of the administrator" msgid "administrator"
msgstr "rôle de l'administrateur⋅rice" msgstr "administrateur⋅rice"
#: apps/registration/models.py:323 #: apps/registration/models.py:303
msgid "admin registration" msgid ""
msgstr "inscription d'administrateur⋅rice" "An administrator has all rights. Please don't give this right to all juries "
"and volunteers."
msgstr ""
"Un⋅e administrateur⋅rice a tous les droits. Merci de ne pas donner ce droit "
"à toustes les juré⋅es et bénévoles."
#: apps/registration/models.py:324 #: apps/registration/models.py:313
msgid "admin registrations" msgid "admin"
msgstr "inscriptions d'administrateur⋅rices" msgstr "admin"
#: apps/registration/models.py:340 #: apps/registration/models.py:313
msgid "volunteer"
msgstr "bénévole"
#: apps/registration/models.py:334
msgid "type" msgid "type"
msgstr "type" msgstr "type"
#: apps/registration/models.py:343 #: apps/registration/models.py:337
msgid "No payment" msgid "No payment"
msgstr "Pas de paiement" msgstr "Pas de paiement"
#: apps/registration/models.py:345 #: apps/registration/models.py:339
msgid "Scholarship" msgid "Scholarship"
msgstr "Notification de bourse" msgstr "Notification de bourse"
#: apps/registration/models.py:346 #: apps/registration/models.py:340
msgid "Bank transfer" msgid "Bank transfer"
msgstr "Virement bancaire" msgstr "Virement bancaire"
#: apps/registration/models.py:347 #: apps/registration/models.py:341
msgid "Other (please indicate)" msgid "Other (please indicate)"
msgstr "Autre (veuillez spécifier)" msgstr "Autre (veuillez spécifier)"
#: apps/registration/models.py:348 #: apps/registration/models.py:342
msgid "The tournament is free" msgid "The tournament is free"
msgstr "Le tournoi est gratuit" msgstr "Le tournoi est gratuit"
#: apps/registration/models.py:355 #: apps/registration/models.py:349
msgid "scholarship file" msgid "scholarship file"
msgstr "Notification de bourse" msgstr "Notification de bourse"
#: apps/registration/models.py:356 #: apps/registration/models.py:350
msgid "only if you have a scholarship." msgid "only if you have a scholarship."
msgstr "Nécessaire seulement si vous déclarez être boursier." msgstr "Nécessaire seulement si vous déclarez être boursier."
#: apps/registration/models.py:363 #: apps/registration/models.py:357
msgid "additional information" msgid "additional information"
msgstr "informations additionnelles" msgstr "informations additionnelles"
#: apps/registration/models.py:364 #: apps/registration/models.py:358
msgid "To help us to find your payment." msgid "To help us to find your payment."
msgstr "Pour nous aider à retrouver votre paiement, si nécessaire." msgstr "Pour nous aider à retrouver votre paiement, si nécessaire."
#: apps/registration/models.py:379 #: apps/registration/models.py:373
#, python-brace-format #, python-brace-format
msgid "Payment of {registration}" msgid "Payment of {registration}"
msgstr "Paiement de {registration}" msgstr "Paiement de {registration}"
#: apps/registration/models.py:382 #: apps/registration/models.py:376
msgid "payment" msgid "payment"
msgstr "paiement" msgstr "paiement"
#: apps/registration/models.py:383 #: apps/registration/models.py:377
msgid "payments" msgid "payments"
msgstr "paiements" msgstr "paiements"
@ -1640,6 +1659,7 @@ msgstr "Inscription"
#: apps/registration/templates/registration/upload_health_sheet.html:6 #: apps/registration/templates/registration/upload_health_sheet.html:6
#: apps/registration/templates/registration/upload_parental_authorization.html:6 #: apps/registration/templates/registration/upload_parental_authorization.html:6
#: apps/registration/templates/registration/upload_photo_authorization.html:6 #: apps/registration/templates/registration/upload_photo_authorization.html:6
#: apps/registration/templates/registration/upload_vaccine_sheet.html:6
msgid "Back to the user detail" msgid "Back to the user detail"
msgstr "Retour aux détails de l'utilisateur⋅rice" msgstr "Retour aux détails de l'utilisateur⋅rice"
@ -1716,133 +1736,147 @@ msgid "Health sheet:"
msgstr "Fiche sanitaire :" msgstr "Fiche sanitaire :"
#: apps/registration/templates/registration/user_detail.html:82 #: apps/registration/templates/registration/user_detail.html:82
msgid "Vaccine sheet:"
msgstr "Carnet de vaccination :"
#: apps/registration/templates/registration/user_detail.html:92
msgid "Parental authorization:" msgid "Parental authorization:"
msgstr "Autorisation parentale :" msgstr "Autorisation parentale :"
#: apps/registration/templates/registration/user_detail.html:93 #: apps/registration/templates/registration/user_detail.html:103
msgid "Student class:" msgid "Student class:"
msgstr "Classe :" msgstr "Classe :"
#: apps/registration/templates/registration/user_detail.html:96 #: apps/registration/templates/registration/user_detail.html:106
msgid "School:" msgid "School:"
msgstr "École :" msgstr "École :"
#: apps/registration/templates/registration/user_detail.html:99 #: apps/registration/templates/registration/user_detail.html:109
msgid "Responsible name:" msgid "Responsible name:"
msgstr "Nom de læ responsable légal⋅e :" msgstr "Nom de læ responsable légal⋅e :"
#: apps/registration/templates/registration/user_detail.html:102 #: apps/registration/templates/registration/user_detail.html:112
msgid "Responsible phone number:" msgid "Responsible phone number:"
msgstr "Numéro de téléphone de læ responsable légal⋅e :" msgstr "Numéro de téléphone de læ responsable légal⋅e :"
#: apps/registration/templates/registration/user_detail.html:105 #: apps/registration/templates/registration/user_detail.html:115
msgid "Responsible email address:" msgid "Responsible email address:"
msgstr "Adresse e-mail de læ responsable légal⋅e :" msgstr "Adresse e-mail de læ responsable légal⋅e :"
#: apps/registration/templates/registration/user_detail.html:110 #: apps/registration/templates/registration/user_detail.html:120
msgid "Role:" msgid "Admin:"
msgstr "Rôle :" msgstr "Administrateur⋅rice :"
#: apps/registration/templates/registration/user_detail.html:113 #: apps/registration/templates/registration/user_detail.html:123
msgid "Profesional activity:" msgid "Profesional activity:"
msgstr "Activité professionnelle :" msgstr "Activité professionnelle :"
#: apps/registration/templates/registration/user_detail.html:117 #: apps/registration/templates/registration/user_detail.html:127
msgid "Grant Animath to contact me in the future about other actions:" msgid "Grant Animath to contact me in the future about other actions:"
msgstr "Autorise Animath à recontacter à propos d'autres actions :" msgstr "Autorise Animath à recontacter à propos d'autres actions :"
#: apps/registration/templates/registration/user_detail.html:125 #: apps/registration/templates/registration/user_detail.html:135
msgid "Payment information:" msgid "Payment information:"
msgstr "Informations de paiement :" msgstr "Informations de paiement :"
#: apps/registration/templates/registration/user_detail.html:127 #: apps/registration/templates/registration/user_detail.html:137
msgid "yes,no,pending" msgid "yes,no,pending"
msgstr "oui,non,en attente" msgstr "oui,non,en attente"
#: apps/registration/templates/registration/user_detail.html:131 #: apps/registration/templates/registration/user_detail.html:141
#: apps/registration/templates/registration/user_detail.html:134 #: apps/registration/templates/registration/user_detail.html:144
msgid "valid:" msgid "valid:"
msgstr "valide :" msgstr "valide :"
#: apps/registration/templates/registration/user_detail.html:138 #: apps/registration/templates/registration/user_detail.html:148
#: apps/registration/templates/registration/user_detail.html:186 #: apps/registration/templates/registration/user_detail.html:201
msgid "Update payment" msgid "Update payment"
msgstr "Modifier le paiement" msgstr "Modifier le paiement"
#: apps/registration/templates/registration/user_detail.html:144 #: apps/registration/templates/registration/user_detail.html:154
msgid "Download scholarship attestation" msgid "Download scholarship attestation"
msgstr "Télécharger l'attestation de bourse" msgstr "Télécharger l'attestation de bourse"
#: apps/registration/templates/registration/user_detail.html:157 #: apps/registration/templates/registration/user_detail.html:167
msgid "Impersonate" msgid "Impersonate"
msgstr "Impersonifier" msgstr "Impersonifier"
#: apps/registration/templates/registration/user_detail.html:164 #: apps/registration/templates/registration/user_detail.html:174
#: apps/registration/views.py:315 #: apps/registration/views.py:312
msgid "Upload photo authorization" msgid "Upload photo authorization"
msgstr "Téléverser l'autorisation de droit à l'image" msgstr "Téléverser l'autorisation de droit à l'image"
#: apps/registration/templates/registration/user_detail.html:169 #: apps/registration/templates/registration/user_detail.html:179
#: apps/registration/views.py:336 #: apps/registration/views.py:333
msgid "Upload health sheet" msgid "Upload health sheet"
msgstr "Téléverser la fiche sanitaire" msgstr "Téléverser la fiche sanitaire"
#: apps/registration/templates/registration/user_detail.html:174 #: apps/registration/templates/registration/user_detail.html:184
#: apps/registration/templates/registration/user_detail.html:179 #: apps/registration/views.py:354
#: apps/registration/views.py:357 msgid "Upload vaccine sheet"
msgstr "Téléverser le carnet de vaccination"
#: apps/registration/templates/registration/user_detail.html:189
#: apps/registration/templates/registration/user_detail.html:194
#: apps/registration/views.py:375
msgid "Upload parental authorization" msgid "Upload parental authorization"
msgstr "Téléverser l'autorisation parentale" msgstr "Téléverser l'autorisation parentale"
#: apps/registration/views.py:127 #: apps/registration/views.py:124
msgid "New TFJM² organizer account" msgid "New TFJM² organizer account"
msgstr "Nouveau compte organisateur⋅rice pour le TFJM²" msgstr "Nouveau compte organisateur⋅rice pour le TFJM²"
#: apps/registration/views.py:153 #: apps/registration/views.py:150
msgid "Email validation" msgid "Email validation"
msgstr "Validation de l'adresse mail" msgstr "Validation de l'adresse mail"
#: apps/registration/views.py:155 #: apps/registration/views.py:152
msgid "Validate email" msgid "Validate email"
msgstr "Valider l'adresse mail" msgstr "Valider l'adresse mail"
#: apps/registration/views.py:194 #: apps/registration/views.py:191
msgid "Email validation unsuccessful" msgid "Email validation unsuccessful"
msgstr "Échec de la validation de l'adresse mail" msgstr "Échec de la validation de l'adresse mail"
#: apps/registration/views.py:205 #: apps/registration/views.py:202
msgid "Email validation email sent" msgid "Email validation email sent"
msgstr "Mail de confirmation de l'adresse mail envoyé" msgstr "Mail de confirmation de l'adresse mail envoyé"
#: apps/registration/views.py:213 #: apps/registration/views.py:210
msgid "Resend email validation link" msgid "Resend email validation link"
msgstr "Renvoyé le lien de validation de l'adresse mail" msgstr "Renvoyé le lien de validation de l'adresse mail"
#: apps/registration/views.py:255 #: apps/registration/views.py:252
#, python-brace-format #, python-brace-format
msgid "Detail of user {user}" msgid "Detail of user {user}"
msgstr "Détails de l'utilisateur⋅rice {user}" msgstr "Détails de l'utilisateur⋅rice {user}"
#: apps/registration/views.py:279 #: apps/registration/views.py:276
#, python-brace-format #, python-brace-format
msgid "Update user {user}" msgid "Update user {user}"
msgstr "Mise à jour de l'utilisateur⋅rice {user}" msgstr "Mise à jour de l'utilisateur⋅rice {user}"
#: apps/registration/views.py:463 #: apps/registration/views.py:481
#, python-brace-format #, python-brace-format
msgid "Photo authorization of {student}.{ext}" msgid "Photo authorization of {student}.{ext}"
msgstr "Autorisation de droit à l'image de {student}.{ext}" msgstr "Autorisation de droit à l'image de {student}.{ext}"
#: apps/registration/views.py:486 #: apps/registration/views.py:504
#, python-brace-format #, python-brace-format
msgid "Health sheet of {student}.{ext}" msgid "Health sheet of {student}.{ext}"
msgstr "Fiche sanitaire de {student}.{ext}" msgstr "Fiche sanitaire de {student}.{ext}"
#: apps/registration/views.py:509 #: apps/registration/views.py:527
#, python-brace-format
msgid "Vaccine sheet of {student}.{ext}"
msgstr "Carnet de vaccination de {student}.{ext}"
#: apps/registration/views.py:550
#, python-brace-format #, python-brace-format
msgid "Parental authorization of {student}.{ext}" msgid "Parental authorization of {student}.{ext}"
msgstr "Autorisation parentale de {student}.{ext}" msgstr "Autorisation parentale de {student}.{ext}"
#: apps/registration/views.py:531 #: apps/registration/views.py:572
#, python-brace-format #, python-brace-format
msgid "Scholarship attestation of {user}.{ext}" msgid "Scholarship attestation of {user}.{ext}"
msgstr "Notification de bourse de {user}.{ext}" msgstr "Notification de bourse de {user}.{ext}"
@ -2011,3 +2045,15 @@ msgstr "Résultats"
#: tfjm/templates/search/search.html:25 #: tfjm/templates/search/search.html:25
msgid "No results found." msgid "No results found."
msgstr "Aucun résultat." msgstr "Aucun résultat."
#~ msgid "Role:"
#~ msgstr "Rôle :"
#~ msgid "role of the administrator"
#~ msgstr "rôle de l'administrateur⋅rice"
#~ msgid "admin registration"
#~ msgstr "inscription d'administrateur⋅rice"
#~ msgid "admin registrations"
#~ msgstr "inscriptions d'administrateur⋅rices"

View File

@ -23,7 +23,7 @@ from django.views.defaults import bad_request, page_not_found, permission_denied
from django.views.generic import TemplateView from django.views.generic import TemplateView
from participation.views import MotivationLetterView from participation.views import MotivationLetterView
from registration.views import HealthSheetView, ParentalAuthorizationView, PhotoAuthorizationView, \ from registration.views import HealthSheetView, ParentalAuthorizationView, PhotoAuthorizationView, \
ScholarshipView, SolutionView, SynthesisView ScholarshipView, SolutionView, SynthesisView, VaccineSheetView
from .views import AdminSearchView from .views import AdminSearchView
@ -44,6 +44,8 @@ urlpatterns = [
name='photo_authorization'), name='photo_authorization'),
path('media/authorization/health/<str:filename>/', HealthSheetView.as_view(), path('media/authorization/health/<str:filename>/', HealthSheetView.as_view(),
name='health_sheet'), name='health_sheet'),
path('media/authorization/vaccine/<str:filename>/', VaccineSheetView.as_view(),
name='vaccine_sheet'),
path('media/authorization/parental/<str:filename>/', ParentalAuthorizationView.as_view(), path('media/authorization/parental/<str:filename>/', ParentalAuthorizationView.as_view(),
name='parental_authorization'), name='parental_authorization'),
path('media/authorization/scholarship/<str:filename>/', ScholarshipView.as_view(), path('media/authorization/scholarship/<str:filename>/', ScholarshipView.as_view(),