Select teams for final

This commit is contained in:
Yohann D'ANELLO 2020-05-06 18:10:33 +02:00
parent abafdc86d9
commit 6e31bcc7f1
2 changed files with 64 additions and 25 deletions

View File

@ -158,6 +158,26 @@ class TeamDetailView(LoginRequiredMixin, DetailView):
elif "delete" in request.POST and request.user.organizes: elif "delete" in request.POST and request.user.organizes:
team.delete() team.delete()
return redirect('tournament:detail', pk=team.tournament.pk) return redirect('tournament:detail', pk=team.tournament.pk)
elif "select_final" in request.POST and request.user.admin and not team.selected_for_final and team.pools:
for solution in team.solutions.all():
alphabet = "0123456789abcdefghijklmnopqrstuvwxyz0123456789"
id = ""
for i in range(64):
id += random.choice(alphabet)
with solution.file.open("rb") as source:
with open("/code/media/" + id, "wb") as dest:
for chunk in source.chunks():
dest.write(chunk)
new_sol = Solution(
file=id,
team=team,
problem=solution.problem,
final=True,
)
new_sol.save()
team.selected_for_final = True
team.save()
return redirect('tournament:team_detail', pk=team.pk)
return self.get(request, *args, **kwargs) return self.get(request, *args, **kwargs)
@ -238,7 +258,8 @@ class SolutionsView(TeamMixin, BaseFormView, SingleTableView):
qs = super().get_queryset() qs = super().get_queryset()
if not self.request.user.admin: if not self.request.user.admin:
qs = qs.filter(team=self.request.user.team) qs = qs.filter(team=self.request.user.team)
return qs.order_by('team__tournament__date_start', 'team__tournament__name', 'team__trigram', 'problem',) return qs.order_by('final', 'team__tournament__date_start', 'team__tournament__name', 'team__trigram',
'problem',)
def form_valid(self, form): def form_valid(self, form):
solution = form.instance solution = form.instance
@ -274,7 +295,7 @@ class SolutionsOrgaListView(OrgaMixin, SingleTableView):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
if "tournament_zip" in request.POST: if "tournament_zip" in request.POST:
tournament = Tournament.objects.get(pk=request.POST["tournament_zip"][0]) tournament = Tournament.objects.get(pk=int(request.POST["tournament_zip"]))
solutions = tournament.solutions solutions = tournament.solutions
if not request.user.admin and request.user not in tournament.organizers.all(): if not request.user.admin and request.user not in tournament.organizers.all():
raise PermissionDenied raise PermissionDenied
@ -307,7 +328,8 @@ class SolutionsOrgaListView(OrgaMixin, SingleTableView):
qs = super().get_queryset() qs = super().get_queryset()
if not self.request.user.admin: if not self.request.user.admin:
qs = qs.filter(team__tournament__organizers=self.request.user) qs = qs.filter(team__tournament__organizers=self.request.user)
return qs.order_by('team__tournament__date_start', 'team__tournament__name', 'team__trigram', 'problem',) return qs.order_by('final', 'team__tournament__date_start', 'team__tournament__name', 'team__trigram',
'problem',)
class SynthesesView(TeamMixin, BaseFormView, SingleTableView): class SynthesesView(TeamMixin, BaseFormView, SingleTableView):
@ -341,8 +363,8 @@ class SynthesesView(TeamMixin, BaseFormView, SingleTableView):
qs = super().get_queryset() qs = super().get_queryset()
if not self.request.user.admin: if not self.request.user.admin:
qs = qs.filter(team=self.request.user.team) qs = qs.filter(team=self.request.user.team)
return qs.order_by('team__tournament__date_start', 'team__tournament__name', 'team__trigram', 'round', return qs.order_by('final', 'team__tournament__date_start', 'team__tournament__name', 'team__trigram',
'source',) 'round', 'source',)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
self.object_list = self.get_queryset() self.object_list = self.get_queryset()
@ -392,7 +414,7 @@ class SynthesesOrgaListView(OrgaMixin, SingleTableView):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
if "tournament_zip" in request.POST: if "tournament_zip" in request.POST:
tournament = Tournament.objects.get(pk=request.POST["tournament_zip"][0]) tournament = Tournament.objects.get(pk=request.POST["tournament_zip"])
syntheses = tournament.syntheses syntheses = tournament.syntheses
if not request.user.admin and request.user not in tournament.organizers.all(): if not request.user.admin and request.user not in tournament.organizers.all():
raise PermissionDenied raise PermissionDenied
@ -425,8 +447,8 @@ class SynthesesOrgaListView(OrgaMixin, SingleTableView):
qs = super().get_queryset() qs = super().get_queryset()
if not self.request.user.admin: if not self.request.user.admin:
qs = qs.filter(team__tournament__organizers=self.request.user) qs = qs.filter(team__tournament__organizers=self.request.user)
return qs.order_by('team__tournament__date_start', 'team__tournament__name', 'team__trigram', 'round', return qs.order_by('final', 'team__tournament__date_start', 'team__tournament__name', 'team__trigram',
'source',) 'round', 'source',)
class PoolListView(LoginRequiredMixin, SingleTableView): class PoolListView(LoginRequiredMixin, SingleTableView):
@ -441,7 +463,8 @@ class PoolListView(LoginRequiredMixin, SingleTableView):
qs = qs.filter(Q(juries=user) | Q(teams__tournament__organizers=user)) qs = qs.filter(Q(juries=user) | Q(teams__tournament__organizers=user))
elif user.participates: elif user.participates:
qs = qs.filter(teams=user.team) qs = qs.filter(teams=user.team)
qs = qs.distinct().order_by('teams__tournament__date_start', 'teams__tournament__name', 'round',) qs = qs.distinct().order_by('solutions__final', 'teams__tournament__date_start', 'teams__tournament__name',
'round',)
return qs return qs

View File

@ -19,13 +19,15 @@
<dd class="col-xl-6">{{ team.access_code }}</dd> <dd class="col-xl-6">{{ team.access_code }}</dd>
<dt class="col-xl-6 text-right">{% trans 'tournament'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'tournament'|capfirst %}</dt>
<dd class="col-xl-6"><a href="{% url "tournament:detail" pk=team.tournament.pk %}">{{ team.tournament }}</a></dd> <dd class="col-xl-6"><a
href="{% url "tournament:detail" pk=team.tournament.pk %}">{{ team.tournament }}</a></dd>
<dt class="col-xl-6 text-right">{% trans 'coachs'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'coachs'|capfirst %}</dt>
<dd class="col-xl-6">{% autoescape off %}{{ team.linked_encadrants|join:", " }}{% endautoescape %}</dd> <dd class="col-xl-6">{% autoescape off %}{{ team.linked_encadrants|join:", " }}{% endautoescape %}</dd>
<dt class="col-xl-6 text-right">{% trans 'participants'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'participants'|capfirst %}</dt>
<dd class="col-xl-6">{% autoescape off %}{{ team.linked_participants|join:", " }}{% endautoescape %}</dd> <dd class="col-xl-6">
{% autoescape off %}{{ team.linked_participants|join:", " }}{% endautoescape %}</dd>
<dt class="col-xl-6 text-right">{% trans 'validation status'|capfirst %}</dt> <dt class="col-xl-6 text-right">{% trans 'validation status'|capfirst %}</dt>
<dd class="col-xl-6">{{ team.get_validation_status_display }}</dd> <dd class="col-xl-6">{{ team.get_validation_status_display }}</dd>
@ -40,19 +42,26 @@
{% if user.admin or user in team.tournament.organizers.all or team == user.team %} {% if user.admin or user in team.tournament.organizers.all or team == user.team %}
<div class="card-footer text-center"> <div class="card-footer text-center">
{% if team.invalid or user.organizes %} <form method="post">
<a href="{% url "tournament:team_update" pk=team.pk %}"><button class="btn btn-secondary">{% trans "Edit team" %}</button></a> {% csrf_token %}
{% endif %} {% if team.invalid or user.organizes %}
{% if team.invalid %} <a class="btn btn-secondary" href="{% url "tournament:team_update" pk=team.pk %}">
<form method="post"> {% trans "Edit team" %}
</a>
{% endif %}
{% if team.valid and user.admin and not team.selected_for_final and team.pools %}
<button name="select_final" class="btn btn-success">{% trans "Select for final" %}</button>
{% endif %}
{% if team.invalid %}
<form method="post">
{% csrf_token %} {% csrf_token %}
{% if user.admin %} {% if user.admin %}
<button name="delete" class="btn btn-danger">{% trans "Delete team" %}</button> <button name="delete" class="btn btn-danger">{% trans "Delete team" %}</button>
{% elif team == user.team %} {% elif team == user.team %}
<button name="leave" class="btn btn-danger">{% trans "Leave this team" %}</button> <button name="leave" class="btn btn-danger">{% trans "Leave this team" %}</button>
{% endif %} {% endif %}
</form> {% endif %}
{% endif %} </form>
</div> </div>
{% endif %} {% endif %}
</div> </div>
@ -75,14 +84,17 @@
<div class="alert alert-warning"> <div class="alert alert-warning">
Pour demander à valider votre équipe, vous devez avoir au moins un encadrant, quatre participants Pour demander à valider votre équipe, vous devez avoir au moins un encadrant, quatre participants
et soumis une autorisation de droit à l'image, une fiche sanitaire et une autorisation et soumis une autorisation de droit à l'image, une fiche sanitaire et une autorisation
parentale (si besoin) par participant, ainsi qu'une lettre de motivation à transmettre aux organisateurs. parentale (si besoin) par participant, ainsi qu'une lettre de motivation à transmettre aux
organisateurs.
Les encadrants doivent également fournir une autorisation de droit à l'image. Les encadrants doivent également fournir une autorisation de droit à l'image.
</div> </div>
{% endif %} {% endif %}
<hr> <hr>
<div class="alert alert-danger"> <div class="alert alert-danger">
En raison du changement de format du TFJM² 2020, il n'y a plus de document obligatoire à envoyer. Les autorisations En raison du changement de format du TFJM² 2020, il n'y a plus de document obligatoire à envoyer. Les
précédemment envoyées ont été détruites. Seules les lettres de motivation ont été conservées, mais leur envoi autorisations
précédemment envoyées ont été détruites. Seules les lettres de motivation ont été conservées, mais leur
envoi
n'est plus obligatoire. n'est plus obligatoire.
</div> </div>
{% endif %} {% endif %}
@ -90,7 +102,7 @@
{% if team.waiting %} {% if team.waiting %}
<hr> <hr>
<div class="alert alert-warning"> <div class="alert alert-warning">
{% trans "The team is waiting about validation." %} {% trans "The team is waiting about validation." %}
</div> </div>
{% if user.admin %} {% if user.admin %}
@ -98,7 +110,8 @@
{% csrf_token %} {% csrf_token %}
<div class="form-group row"> <div class="form-group row">
<label for="message">{% trans "Message addressed to the team:" %}</label> <label for="message">{% trans "Message addressed to the team:" %}</label>
<textarea class="form-control" id="message" name="message" placeholder="{% trans "Message..." %}"></textarea> <textarea class="form-control" id="message" name="message"
placeholder="{% trans "Message..." %}"></textarea>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -118,7 +131,8 @@
{% if team.motivation_letters.count %} {% if team.motivation_letters.count %}
<div class="alert alert-info"> <div class="alert alert-info">
<strong>{% blocktrans %}Motivation letter:{% endblocktrans %}</strong> <strong>{% blocktrans %}Motivation letter:{% endblocktrans %}</strong>
<a data-turbolinks="false" href="{% url "document" file=team.motivation_letters.last.file %}">{% trans "Download" %}</a> <a data-turbolinks="false"
href="{% url "document" file=team.motivation_letters.last.file %}">{% trans "Download" %}</a>
</div> </div>
{% endif %} {% endif %}
@ -126,7 +140,9 @@
<div class="alert alert-info"> <div class="alert alert-info">
<ul> <ul>
{% for solution in ordered_solutions %} {% for solution in ordered_solutions %}
<li><strong>{{ solution }} :</strong> <a data-turbolinks="false" href="{% url "document" file=solution.file %}">{% trans "Download" %}</a></li> <li><strong>{{ solution }} :</strong> <a data-turbolinks="false"
href="{% url "document" file=solution.file %}">{% trans "Download" %}</a>
</li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>