Admins can validate a team or not

This commit is contained in:
Yohann D'ANELLO 2020-10-11 18:44:42 +02:00
parent 3c8615b487
commit e9b70f351b
4 changed files with 173 additions and 52 deletions

View File

@ -44,6 +44,30 @@ class ParticipationForm(forms.ModelForm):
fields = ('problem',)
class RequestValidationForm(forms.Form):
_form_type = forms.CharField(
initial="RequestValidationForm",
widget=forms.HiddenInput(),
)
engagement = forms.BooleanField(
label=_("I engage myself to participate to the whole \"Correspondances\"."),
required=True,
)
class ValidateParticipationForm(forms.Form):
_form_type = forms.CharField(
initial="ValidateParticipationForm",
widget=forms.HiddenInput(),
)
message = forms.CharField(
label=_("Message to address to the team:"),
widget=forms.Textarea(),
)
class UploadVideoForm(forms.ModelForm):
class Meta:
model = Video

View File

@ -78,6 +78,7 @@
<div class="text-center">
<form method="post">
{% csrf_token %}
{{ request_validation_form|crispy }}
<button class="btn btn-success" name="request-validation">{% trans "Submit my team to validation" %}</button>
</form>
</div>
@ -98,8 +99,17 @@
{% trans "Your validation is pending." %}
</div>
{% else %}
Team asked for validation.
{# TODO Add validation form: validate or invalidate, with a message #}
<div class="alert alert-info">
{% trans "The team requested to be validated. You may now control the authorizations and confirm that they can participate." %}
</div>
<form method="post">
{% csrf_token %}
{{ validation_form|crispy }}
<div class="input-group btn-group">
<button class="btn btn-success" name="validate" type="submit">{% trans "Validate" %}</button>
<button class="btn btn-danger" name="invalidate" type="submit">{% trans "Invalidate" %}</button>
</div>
</form>
{% endif %}
{% endif %}

View File

@ -6,15 +6,16 @@ from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import PermissionDenied
from django.db import transaction
from django.http import HttpResponse
from django.shortcuts import redirect
from django.template.loader import render_to_string
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView, DetailView, FormView, RedirectView, UpdateView
from django.views.generic.edit import FormMixin, ProcessFormView
from magic import Magic
from registration.models import AdminRegistration
from .forms import JoinTeamForm, ParticipationForm, TeamForm, UploadVideoForm
from .forms import JoinTeamForm, ParticipationForm, RequestValidationForm, TeamForm, UploadVideoForm,\
ValidateParticipationForm
from .models import Participation, Team, Video
@ -90,32 +91,22 @@ class MyTeamDetailView(LoginRequiredMixin, RedirectView):
raise PermissionDenied(_("You don't participate, so you don't have any team."))
class TeamDetailView(LoginRequiredMixin, DetailView):
class TeamDetailView(LoginRequiredMixin, FormMixin, ProcessFormView, DetailView):
model = Team
def get(self, request, *args, **kwargs):
user = request.user
self.object = self.get_object()
if user.registration.is_admin or user.registration.participates and user.registration.team.pk == kwargs["pk"]:
return super().get(request, *args, **kwargs)
raise PermissionDenied
def post(self, request, *args, **kwargs):
if request.user.registration.participates:
if "request-validation" in request.POST:
request.user.registration.team.participation.valid = False
request.user.registration.team.participation.save()
for admin in AdminRegistration.objects.all():
mail_context = dict(user=admin.user, team=request.user.registration.team)
mail_plain = render_to_string("participation/mails/request_validation.txt", mail_context)
mail_html = render_to_string("participation/mails/request_validation.html", mail_context)
admin.user.email_user("[Corres2math] Validation d'équipe", mail_plain, html_message=mail_html)
return redirect(request.path)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
team = self.object
team = self.get_object()
context["request_validation_form"] = RequestValidationForm(self.request.POST or None)
context["validation_form"] = ValidateParticipationForm(self.request.POST or None)
context["can_validate"] = team.students.count() >= 3 and \
all(r.email_confirmed for r in team.students.all()) and \
all(r.photo_authorization for r in team.students.all()) and \
@ -123,6 +114,56 @@ class TeamDetailView(LoginRequiredMixin, DetailView):
return context
def get_form_class(self):
if not self.request.POST:
return RequestValidationForm
elif self.request.POST["_form_type"] == "RequestValidationForm":
return RequestValidationForm
elif self.request.POST["_form_type"] == "ValidateParticipationForm":
return ValidateParticipationForm
return None
def form_valid(self, form):
self.object = self.get_object()
if isinstance(form, RequestValidationForm):
if not self.request.user.registration.participates:
form.add_error(None, _("You don't participate, so you can't request the validation of the team."))
return self.form_invalid(form)
if self.object.participation.valid is not None:
form.add_error(None, _("The validation of the team is already done or pending."))
return self.form_invalid(form)
self.object.participation.valid = False
self.object.participation.save()
for admin in AdminRegistration.objects.all():
mail_context = dict(user=admin.user, team=self.object)
mail_plain = render_to_string("participation/mails/request_validation.txt", mail_context)
mail_html = render_to_string("participation/mails/request_validation.html", mail_context)
admin.user.email_user("[Corres2math] Validation d'équipe", mail_plain, html_message=mail_html)
elif isinstance(form, ValidateParticipationForm):
if not self.request.user.registration.is_admin:
form.add_error(None, _("You are not an administrator."))
return self.form_invalid(form)
elif self.object.participation.valid is not False:
form.add_error(None, _("This team has no pending validation."))
return self.form_invalid(form)
if "validate" in self.request.POST:
self.object.participation.valid = True
self.object.participation.save()
elif "invalidate" in self.request.POST:
self.object.participation.valid = None
self.object.participation.save()
else:
form.add_error(None, _("You must specify if you validate the registration or not."))
return self.form_invalid(form)
return super().form_invalid(form)
def get_success_url(self):
return self.request.path
class TeamUpdateView(LoginRequiredMixin, UpdateView):
model = Team

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Corres2math\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-10-11 16:48+0200\n"
"POT-Creation-Date: 2020-10-11 18:43+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Yohann D'ANELLO <yohann.danello@animath.fr>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -107,6 +107,14 @@ msgstr "Le trigramme doit être composé de trois lettres majuscules."
msgid "No team was found with this access code."
msgstr "Aucune équipe n'a été trouvée avec ce code d'accès."
#: apps/participation/forms.py:54
msgid "I engage myself to participate to the whole \"Correspondances\"."
msgstr "Je m'engage à participer à l'intégralité des Correspondances."
#: apps/participation/forms.py:66
msgid "Message to address to the team:"
msgstr "Message à adresser à l'équipe :"
#: apps/participation/models.py:16
msgid "name"
msgstr "nom"
@ -135,80 +143,80 @@ msgstr ""
"Donner l'autorisation de publier la vidéo sur le site principal pour "
"promouvoir les Correspondances."
#: apps/participation/models.py:59
#: apps/participation/models.py:60
#, python-brace-format
msgid "Team {name} ({trigram})"
msgstr "Équipe {name} ({trigram})"
#: apps/participation/models.py:62 apps/participation/models.py:73
#: apps/participation/models.py:63 apps/participation/models.py:74
#: apps/registration/models.py:85 apps/registration/models.py:130
msgid "team"
msgstr "équipe"
#: apps/participation/models.py:63
#: apps/participation/models.py:64
msgid "teams"
msgstr "équipes"
#: apps/participation/models.py:77
#: apps/participation/models.py:78
#, python-brace-format
msgid "Problem #{problem:d}"
msgstr "Problème n°{problem:d}"
#: apps/participation/models.py:80
#: apps/participation/models.py:81
msgid "problem number"
msgstr "numéro de problème"
#: apps/participation/models.py:86 apps/participation/models.py:134
#: apps/participation/models.py:87 apps/participation/models.py:135
msgid "valid"
msgstr "valide"
#: apps/participation/models.py:87 apps/participation/models.py:135
#: apps/participation/models.py:88 apps/participation/models.py:136
msgid "The video got the validation of the administrators."
msgstr "La vidéo a été validée par les administrateurs."
#: apps/participation/models.py:96
#: apps/participation/models.py:97
msgid "solution video"
msgstr "vidéo de solution"
#: apps/participation/models.py:105
#: apps/participation/models.py:106
msgid "received participation"
msgstr "participation reçue"
#: apps/participation/models.py:114
#: apps/participation/models.py:115
msgid "synthesis video"
msgstr "vidéo de synthèse"
#: apps/participation/models.py:118
#: apps/participation/models.py:119
#, python-brace-format
msgid "Participation of the team {name} ({trigram})"
msgstr "Participation de l'équipe {name} ({trigram})"
#: apps/participation/models.py:121
#: apps/participation/models.py:122
msgid "participation"
msgstr "participation"
#: apps/participation/models.py:122
#: apps/participation/models.py:123
msgid "participations"
msgstr "participations"
#: apps/participation/models.py:127
#: apps/participation/models.py:128
msgid "link"
msgstr "lien"
#: apps/participation/models.py:128
#: apps/participation/models.py:129
msgid "The full video link."
msgstr "Le lien complet de la vidéo."
#: apps/participation/models.py:157
#: apps/participation/models.py:158
#, python-brace-format
msgid "Video of team {name} ({trigram})"
msgstr "Vidéo de l'équipe {name} ({trigram})"
#: apps/participation/models.py:161
#: apps/participation/models.py:162
msgid "video"
msgstr "vidéo"
#: apps/participation/models.py:162
#: apps/participation/models.py:163
msgid "videos"
msgstr "vidéos"
@ -302,7 +310,7 @@ msgid "Not uploaded yet"
msgstr "Pas encore envoyée"
#: apps/participation/templates/participation/team_detail.html:61
#: apps/participation/templates/participation/team_detail.html:104
#: apps/participation/templates/participation/team_detail.html:117
#: apps/participation/templates/participation/update_team.html:12
#: apps/registration/templates/registration/update_user.html:12
#: apps/registration/templates/registration/user_detail.html:64
@ -322,11 +330,11 @@ msgstr ""
"Votre équipe contient au moins 3 personnes et toutes les autorisations de "
"droit à l'image ont été données : l'équipe peut être validée."
#: apps/participation/templates/participation/team_detail.html:79
#: apps/participation/templates/participation/team_detail.html:82
msgid "Submit my team to validation"
msgstr "Soumettre mon équipe à validation"
#: apps/participation/templates/participation/team_detail.html:84
#: apps/participation/templates/participation/team_detail.html:88
msgid ""
"Your team must be composed of 3 members and each member must upload its "
"photo authorization and confirm its email address."
@ -334,55 +342,93 @@ msgstr ""
"Votre équipe doit être composée de 3 membres et chaque membre doit envoyer "
"son autorisation de droit à l'image et confirmé son adresse e-mail."
#: apps/participation/templates/participation/team_detail.html:89
#: apps/participation/templates/participation/team_detail.html:93
msgid "This team didn't ask for validation yet."
msgstr "L'équipe n'a pas encore demandé à être validée."
#: apps/participation/templates/participation/team_detail.html:95
#: apps/participation/templates/participation/team_detail.html:99
msgid "Your validation is pending."
msgstr "Votre validation est en attente."
#: apps/participation/templates/participation/team_detail.html:103
msgid ""
"The team requested to be validated. You may now control the authorizations "
"and confirm that they can participate."
msgstr ""
"L'équipe a demandé à être validée. Vous pouvez désormais contrôler les "
"différentes autorisations et confirmer qu'elle peut participer."
#: apps/participation/templates/participation/team_detail.html:109
msgid "Validate"
msgstr "Valider"
#: apps/participation/templates/participation/team_detail.html:110
msgid "Invalidate"
msgstr "Invalider"
#: apps/participation/templates/participation/team_detail.html:116
msgid "Update team"
msgstr "Modifier l'équipe"
#: apps/participation/views.py:21 templates/base.html:70
#: apps/participation/views.py:25 templates/base.html:70
#: templates/base.html:206
msgid "Create team"
msgstr "Créer une équipe"
#: apps/participation/views.py:28 apps/participation/views.py:58
#: apps/participation/views.py:32 apps/participation/views.py:62
msgid "You don't participate, so you can't create a team."
msgstr "Vous ne participez pas, vous ne pouvez pas créer d'équipe."
#: apps/participation/views.py:30 apps/participation/views.py:60
#: apps/participation/views.py:34 apps/participation/views.py:64
msgid "You are already in a team."
msgstr "Vous êtes déjà dans une équipe."
#: apps/participation/views.py:51 templates/base.html:75
#: apps/participation/views.py:55 templates/base.html:75
#: templates/base.html:202
msgid "Join team"
msgstr "Rejoindre une équipe"
#: apps/participation/views.py:86 apps/participation/views.py:175
#: apps/participation/views.py:90 apps/participation/views.py:232
msgid "You are not in a team."
msgstr "Vous n'êtes pas dans une équipe."
#: apps/participation/views.py:87 apps/participation/views.py:176
#: apps/participation/views.py:91 apps/participation/views.py:233
msgid "You don't participate, so you don't have any team."
msgstr "Vous ne participez pas, vous n'avez donc pas d'équipe."
#: apps/participation/views.py:159 apps/registration/views.py:213
#: apps/participation/views.py:130
msgid "You don't participate, so you can't request the validation of the team."
msgstr ""
"Vous ne participez pas, vous ne pouvez pas demander la validation de "
"l'équipe."
#: apps/participation/views.py:133
msgid "The validation of the team is already done or pending."
msgstr "La validation de l'équipe est déjà faite ou en cours."
#: apps/participation/views.py:146
msgid "You are not an administrator."
msgstr "Vous n'êtes pas administrateur."
#: apps/participation/views.py:149
msgid "This team has no pending validation."
msgstr "L'équipe n'a pas de validation en attente."
#: apps/participation/views.py:159
msgid "You must specify if you validate the registration or not."
msgstr "Vous devez spécifier si vous validez l'inscription ou non."
#: apps/participation/views.py:216 apps/registration/views.py:213
#, python-brace-format
msgid "Photo authorization of {student}.{ext}"
msgstr "Autorisation de droit à l'image de {student}.{ext}"
#: apps/participation/views.py:163
#: apps/participation/views.py:220
#, python-brace-format
msgid "Photo authorizations of team {trigram}.zip"
msgstr "Autorisations de droit à l'image de l'équipe {trigram}.zip"
#: apps/participation/views.py:185
#: apps/participation/views.py:242
msgid "The team is not validated yet."
msgstr "L'équipe n'est pas encore validée."