diff --git a/apps/registration/forms.py b/apps/registration/forms.py index 731cbd7..89b8d86 100644 --- a/apps/registration/forms.py +++ b/apps/registration/forms.py @@ -45,6 +45,38 @@ class SignupForm(UserCreationForm): fields = ('first_name', 'last_name', 'email', 'password1', 'password2', 'role',) +class AddOrganizerForm(forms.ModelForm): + """ + Signup form to registers volunteers + """ + type = forms.ChoiceField( + label=lambda: _("role").capitalize(), + choices=lambda: [ + ("volunteer", _("volunteer").capitalize()), + ("admin", _("admin").capitalize()), + ], + ) + + def clean_email(self): + """ + Ensure that the email address is unique. + """ + email = self.data["email"] + if User.objects.filter(email=email).exists(): + self.add_error("email", _("This email address is already used.")) + return email + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields["first_name"].required = True + self.fields["last_name"].required = True + self.fields["email"].required = True + + class Meta: + model = User + fields = ('first_name', 'last_name', 'email', 'type',) + + class UserForm(forms.ModelForm): """ Replace the default user form to require the first name, last name and the email. diff --git a/apps/registration/tables.py b/apps/registration/tables.py index c20bcd1..8aa6544 100644 --- a/apps/registration/tables.py +++ b/apps/registration/tables.py @@ -18,10 +18,15 @@ class RegistrationTable(tables.Table): accessor="user__last_name", ) + def order_type(self, queryset, desc): + types = ["volunteerregistration__adminregistration", "volunteerregistration", "participantregistration"] + return queryset.order_by(*(("" if desc else "-") + t for t in types)), True + class Meta: attrs = { 'class': 'table table-condensed table-striped', } model = Registration fields = ('last_name', 'user__first_name', 'user__email', 'type',) + order_by = ('volunteerregistration__adminregistration', 'volunteerregistration', 'last_name', 'first_name',) template_name = 'django_tables2/bootstrap4.html' diff --git a/apps/registration/templates/registration/add_organizer.html b/apps/registration/templates/registration/add_organizer.html new file mode 100644 index 0000000..a61974f --- /dev/null +++ b/apps/registration/templates/registration/add_organizer.html @@ -0,0 +1,43 @@ + +{% extends 'base.html' %} +{% load crispy_forms_filters %} +{% load i18n %} +{% block title %}{% trans "Add organizer" %}{% endblock %} + +{% block extracss %} + {{ volunteer_registration_form.media }} +{% endblock %} + +{% block content %} +

{% trans "Add organizer" %}

+ +
+ {% csrf_token %} + {{ form|crispy }} +
+ +
+ +
+ {{ volunteer_registration_form|crispy }} +
+
+ {{ admin_registration_form|crispy }} +
+{% endblock %} + +{% block extrajavascript %} + +{% endblock %} diff --git a/apps/registration/templates/registration/user_list.html b/apps/registration/templates/registration/user_list.html index 1c0d551..11cc7db 100644 --- a/apps/registration/templates/registration/user_list.html +++ b/apps/registration/templates/registration/user_list.html @@ -1,7 +1,14 @@ {% extends "base.html" %} -{% load django_tables2 %} +{% load django_tables2 i18n %} {% block content %} + {% if user.registration.is_admin %} + +
+ {% endif %} + {% render_table table %} {% endblock %} diff --git a/apps/registration/urls.py b/apps/registration/urls.py index de0fc63..663efa9 100644 --- a/apps/registration/urls.py +++ b/apps/registration/urls.py @@ -3,8 +3,8 @@ from django.urls import path -from .views import MyAccountDetailView, ResetAdminView, SignupView, UserDetailView, UserImpersonateView, \ - UserListView, UserResendValidationEmailView, UserUpdateView, UserUploadHealthSheetView, \ +from .views import AddOrganizerView, MyAccountDetailView, ResetAdminView, SignupView, UserDetailView,\ + UserImpersonateView, UserListView, UserResendValidationEmailView, UserUpdateView, UserUploadHealthSheetView, \ UserUploadParentalAuthorizationView, UserUploadPhotoAuthorizationView, UserValidateView, \ UserValidationEmailSentView @@ -12,6 +12,7 @@ app_name = "registration" urlpatterns = [ path("signup/", SignupView.as_view(), name="signup"), + path("add-organizer/", AddOrganizerView.as_view(), name="add_organizer"), path('validate_email/sent/', UserValidationEmailSentView.as_view(), name='email_validation_sent'), path('validate_email/resend//', UserResendValidationEmailView.as_view(), name='email_validation_resend'), diff --git a/apps/registration/views.py b/apps/registration/views.py index d6c1b43..5ef580d 100644 --- a/apps/registration/views.py +++ b/apps/registration/views.py @@ -21,8 +21,9 @@ from participation.models import Solution, Synthesis from tfjm.tokens import email_validation_token from tfjm.views import AdminMixin, UserMixin -from .forms import CoachRegistrationForm, HealthSheetForm, ParentalAuthorizationForm, PhotoAuthorizationForm,\ - SignupForm, StudentRegistrationForm, UserForm +from .forms import AddOrganizerForm, AdminRegistrationForm, CoachRegistrationForm, HealthSheetForm, \ + ParentalAuthorizationForm, PhotoAuthorizationForm, SignupForm, StudentRegistrationForm, UserForm, \ + VolunteerRegistrationForm from .models import Registration, StudentRegistration, ParticipantRegistration from .tables import RegistrationTable @@ -73,6 +74,47 @@ class SignupView(CreateView): return reverse_lazy("registration:email_validation_sent") +class AddOrganizerView(AdminMixin, CreateView): + model = User + form_class = AddOrganizerForm + template_name = "registration/add_organizer.html" + extra_context = dict(title=_("Add organizer")) + + def get_context_data(self, **kwargs): + context = super().get_context_data() + + 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["admin_registration_form"].fields["email_confirmed"] + + return context + + @transaction.atomic + 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) + del registration_form.fields["email_confirmed"] + + if not registration_form.is_valid(): + return self.form_invalid(form) + + ret = super().form_valid(form) + registration = registration_form.instance + registration.user = form.instance + registration.save() + + return ret + + def get_success_url(self): + return reverse_lazy("registration:email_validation_sent") + + + class UserValidateView(TemplateView): """ A view to validate the email address. diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index a2750d7..55d13fa 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: TFJM\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-01-14 19:30+0100\n" +"POT-Creation-Date: 2021-01-14 21:01+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Yohann D'ANELLO \n" "Language-Team: LANGUAGE \n" @@ -479,8 +479,8 @@ msgstr "Rejoindre" #: apps/participation/templates/participation/passage_detail.html:100 #: apps/participation/templates/participation/passage_detail.html:105 #: apps/participation/templates/participation/pool_detail.html:52 -#: apps/participation/templates/participation/pool_detail.html:68 -#: apps/participation/templates/participation/pool_detail.html:73 +#: apps/participation/templates/participation/pool_detail.html:70 +#: apps/participation/templates/participation/pool_detail.html:75 #: apps/participation/templates/participation/team_detail.html:84 #: apps/participation/templates/participation/team_detail.html:143 #: apps/participation/templates/participation/tournament_form.html:12 @@ -518,7 +518,7 @@ msgstr "Tournoi :" #: apps/participation/templates/participation/participation_detail.html:19 msgid "Solutions:" -msgstr "solutions :" +msgstr "Solutions :" #: apps/participation/templates/participation/participation_detail.html:24 msgid "No solution was uploaded yet." @@ -655,12 +655,12 @@ msgid "Ranking" msgstr "Classement" #: apps/participation/templates/participation/pool_detail.html:51 -#: apps/participation/templates/participation/pool_detail.html:62 +#: apps/participation/templates/participation/pool_detail.html:64 msgid "Add passage" msgstr "Ajouter un passage" #: apps/participation/templates/participation/pool_detail.html:53 -#: apps/participation/templates/participation/pool_detail.html:72 +#: apps/participation/templates/participation/pool_detail.html:74 msgid "Update teams" msgstr "Modifier les équipes" @@ -668,12 +668,12 @@ msgstr "Modifier les équipes" msgid "Passages" msgstr "Passages" -#: apps/participation/templates/participation/pool_detail.html:63 +#: apps/participation/templates/participation/pool_detail.html:65 #: apps/participation/templates/participation/tournament_detail.html:91 msgid "Add" msgstr "Ajouter" -#: apps/participation/templates/participation/pool_detail.html:67 +#: apps/participation/templates/participation/pool_detail.html:69 #: apps/participation/templates/participation/pool_form.html:11 msgid "Update pool" msgstr "Modifier la poule" @@ -936,7 +936,7 @@ msgstr "Vous devez spécifier si vous validez l'inscription ou non." msgid "Update team {trigram}" msgstr "Mise à jour de l'équipe {trigram}" -#: apps/participation/views.py:318 apps/registration/views.py:298 +#: apps/participation/views.py:318 apps/registration/views.py:340 #, python-brace-format msgid "Photo authorization of {student}.{ext}" msgstr "Autorisation de droit à l'image de {student}.{ext}" @@ -959,7 +959,7 @@ msgstr "L'équipe n'est pas encore validée." msgid "Participation of team {trigram}" msgstr "Participation de l'équipe {trigram}" -#: apps/registration/forms.py:21 +#: apps/registration/forms.py:21 apps/registration/forms.py:53 msgid "role" msgstr "rôle" @@ -971,17 +971,25 @@ msgstr "participant" msgid "coach" msgstr "encadrant" -#: apps/registration/forms.py:34 +#: apps/registration/forms.py:34 apps/registration/forms.py:66 msgid "This email address is already used." msgstr "Cette adresse e-mail est déjà utilisée." -#: apps/registration/forms.py:83 apps/registration/forms.py:105 -#: apps/registration/forms.py:127 +#: apps/registration/forms.py:55 apps/registration/models.py:254 +msgid "volunteer" +msgstr "bénévole" + +#: apps/registration/forms.py:56 apps/registration/models.py:273 +msgid "admin" +msgstr "admin" + +#: apps/registration/forms.py:115 apps/registration/forms.py:137 +#: apps/registration/forms.py:159 msgid "The uploaded file size must be under 2 Mo." msgstr "Le fichier envoyé doit peser moins de 2 Mo." -#: apps/registration/forms.py:85 apps/registration/forms.py:107 -#: apps/registration/forms.py:129 +#: apps/registration/forms.py:117 apps/registration/forms.py:139 +#: apps/registration/forms.py:161 msgid "The uploaded file must be a PDF, PNG of JPEG file." msgstr "Le fichier envoyé doit être au format PDF, PNG ou JPEG." @@ -1086,18 +1094,10 @@ msgstr "inscription d'encadrant" msgid "coach registrations" msgstr "inscriptions d'encadrants" -#: apps/registration/models.py:254 -msgid "volunteer" -msgstr "bénévole" - #: apps/registration/models.py:268 msgid "role of the administrator" msgstr "rôle de l'administrateur" -#: apps/registration/models.py:273 -msgid "admin" -msgstr "admin" - #: apps/registration/models.py:281 msgid "admin registration" msgstr "inscription d'administrateur" @@ -1110,6 +1110,14 @@ msgstr "inscriptions d'administrateur" msgid "last name" msgstr "nom de famille" +#: apps/registration/templates/registration/add_organizer.html:5 +#: apps/registration/templates/registration/add_organizer.html:12 +#: apps/registration/templates/registration/add_organizer.html:19 +#: apps/registration/templates/registration/user_list.html:8 +#: apps/registration/views.py:81 +msgid "Add organizer" +msgstr "Ajouter un organisateur" + #: apps/registration/templates/registration/email_validation_complete.html:15 msgid "Your email have successfully been validated." msgstr "Votre email a été validé avec succès." @@ -1259,7 +1267,7 @@ msgstr "Réinitialiser mon mot de passe" #: apps/registration/templates/registration/signup.html:5 #: apps/registration/templates/registration/signup.html:12 #: apps/registration/templates/registration/signup.html:19 -#: apps/registration/views.py:37 +#: apps/registration/views.py:38 msgid "Sign up" msgstr "Inscription" @@ -1384,56 +1392,56 @@ msgid "Update user" msgstr "Modifier l'utilisateur" #: apps/registration/templates/registration/user_detail.html:119 -#: apps/registration/views.py:227 +#: apps/registration/views.py:269 msgid "Upload photo authorization" msgstr "Téléverser l'autorisation de droit à l'image" #: apps/registration/templates/registration/user_detail.html:124 -#: apps/registration/views.py:247 +#: apps/registration/views.py:289 msgid "Upload health sheet" msgstr "Téléverser la fiche sanitaire" #: apps/registration/templates/registration/user_detail.html:129 -#: apps/registration/views.py:267 +#: apps/registration/views.py:309 msgid "Upload parental authorization" msgstr "Téléverser l'autorisation parentale" -#: apps/registration/views.py:80 +#: apps/registration/views.py:122 msgid "Email validation" msgstr "Validation de l'adresse mail" -#: apps/registration/views.py:82 +#: apps/registration/views.py:124 msgid "Validate email" msgstr "Valider l'adresse mail" -#: apps/registration/views.py:121 +#: apps/registration/views.py:163 msgid "Email validation unsuccessful" msgstr "Échec de la validation de l'adresse mail" -#: apps/registration/views.py:132 +#: apps/registration/views.py:174 msgid "Email validation email sent" msgstr "Mail de confirmation de l'adresse mail envoyé" -#: apps/registration/views.py:140 +#: apps/registration/views.py:182 msgid "Resend email validation link" msgstr "Renvoyé le lien de validation de l'adresse mail" -#: apps/registration/views.py:167 +#: apps/registration/views.py:209 #, python-brace-format msgid "Detail of user {user}" msgstr "Détails de l'utilisateur {user}" -#: apps/registration/views.py:191 +#: apps/registration/views.py:233 #, python-brace-format msgid "Update user {user}" msgstr "Mise à jour de l'utilisateur {user}" -#: apps/registration/views.py:320 +#: apps/registration/views.py:362 #, python-brace-format msgid "Health sheet of {student}.{ext}" msgstr "Fiche sanitaire de {student}.{ext}" -#: apps/registration/views.py:342 +#: apps/registration/views.py:384 #, python-brace-format msgid "Parental authorization of {student}.{ext}" msgstr "Autorisation parentale de {student}.{ext}"