mirror of
https://gitlab.com/animath/si/plateforme-corres2math.git
synced 2024-12-05 01:26:54 +00:00
Admins can validate a team or not
This commit is contained in:
parent
3c8615b487
commit
e9b70f351b
@ -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
|
||||
|
@ -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 %}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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."
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user