Add harmonization view
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
parent
109b603b7a
commit
1e7bd209a1
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: TFJM\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-03-30 19:13+0100\n"
|
||||
"POT-Creation-Date: 2024-03-30 20:33+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -333,6 +333,7 @@ msgstr "Continuer le tirage"
|
|||
|
||||
#: draw/templates/draw/tournament_content.html:216 participation/admin.py:167
|
||||
#: participation/models.py:253 participation/models.py:653
|
||||
#: participation/templates/participation/tournament_harmonize.html:15
|
||||
#: registration/models.py:156 registration/models.py:609
|
||||
#: registration/tables.py:39
|
||||
#: registration/templates/registration/payment_form.html:52
|
||||
|
@ -377,8 +378,8 @@ msgstr "Êtes-vous sûr·e de vouloir annuler le tirage au sort ?"
|
|||
msgid "Close"
|
||||
msgstr "Fermer"
|
||||
|
||||
#: draw/views.py:31 participation/views.py:155 participation/views.py:469
|
||||
#: participation/views.py:500
|
||||
#: draw/views.py:31 participation/views.py:156 participation/views.py:470
|
||||
#: participation/views.py:501
|
||||
msgid "You are not in a team."
|
||||
msgstr "Vous n'êtes pas dans une équipe."
|
||||
|
||||
|
@ -490,7 +491,7 @@ msgstr "Ce trigramme est déjà utilisé."
|
|||
msgid "No team was found with this access code."
|
||||
msgstr "Aucune équipe n'a été trouvée avec ce code d'accès."
|
||||
|
||||
#: participation/forms.py:59 participation/views.py:471
|
||||
#: participation/forms.py:59 participation/views.py:472
|
||||
msgid "The team is already validated or the validation is pending."
|
||||
msgstr "La validation de l'équipe est déjà faite ou en cours."
|
||||
|
||||
|
@ -1355,6 +1356,7 @@ msgstr "Aller à la page Google Sheets de la poule"
|
|||
|
||||
#: participation/templates/participation/pool_detail.html:83
|
||||
#: participation/templates/participation/tournament_detail.html:98
|
||||
#: participation/templates/participation/tournament_harmonize.html:8
|
||||
msgid "Ranking"
|
||||
msgstr "Classement"
|
||||
|
||||
|
@ -1582,7 +1584,7 @@ msgid "Invalidate"
|
|||
msgstr "Invalider"
|
||||
|
||||
#: participation/templates/participation/team_detail.html:209
|
||||
#: participation/views.py:326
|
||||
#: participation/views.py:327
|
||||
msgid "Upload motivation letter"
|
||||
msgstr "Envoyer la lettre de motivation"
|
||||
|
||||
|
@ -1591,7 +1593,7 @@ msgid "Update team"
|
|||
msgstr "Modifier l'équipe"
|
||||
|
||||
#: participation/templates/participation/team_detail.html:219
|
||||
#: participation/views.py:463
|
||||
#: participation/views.py:464
|
||||
msgid "Leave team"
|
||||
msgstr "Quitter l'équipe"
|
||||
|
||||
|
@ -1685,10 +1687,41 @@ msgstr "Publier les notes pour le premier tour"
|
|||
msgid "Publish notes for second round"
|
||||
msgstr "Publier les notes pour le second tour"
|
||||
|
||||
#: participation/templates/participation/tournament_detail.html:133
|
||||
#: participation/templates/participation/tournament_detail.html:128
|
||||
#: participation/templates/participation/tournament_detail.html:132
|
||||
msgid "Harmonize"
|
||||
msgstr "Harmoniser"
|
||||
|
||||
#: participation/templates/participation/tournament_detail.html:128
|
||||
#: participation/templates/participation/tournament_detail.html:132
|
||||
msgid "Day"
|
||||
msgstr "Jour"
|
||||
|
||||
#: participation/templates/participation/tournament_detail.html:143
|
||||
msgid "Files available for download"
|
||||
msgstr "Fichiers disponibles au téléchargement"
|
||||
|
||||
#: participation/templates/participation/tournament_harmonize.html:14
|
||||
msgid "Rank"
|
||||
msgstr "Rang"
|
||||
|
||||
#: participation/templates/participation/tournament_harmonize.html:16
|
||||
msgid "Note"
|
||||
msgstr "Note"
|
||||
|
||||
#: participation/templates/participation/tournament_harmonize.html:17
|
||||
msgid "Including bonus / malus"
|
||||
msgstr "Dont bonus / malus"
|
||||
|
||||
#: participation/templates/participation/tournament_harmonize.html:18
|
||||
msgid "Add bonus / malus"
|
||||
msgstr "Ajouter bonus / malus"
|
||||
|
||||
#: participation/templates/participation/tournament_harmonize.html:48
|
||||
#: participation/templates/participation/tournament_payments.html:9
|
||||
msgid "Back to tournament page"
|
||||
msgstr "Retour à la page du tournoi"
|
||||
|
||||
#: participation/templates/participation/tournament_list.html:6
|
||||
#: tfjm/templates/base.html:67
|
||||
msgid "All tournaments"
|
||||
|
@ -1698,10 +1731,6 @@ msgstr "Tous les tournois"
|
|||
msgid "Add tournament"
|
||||
msgstr "Ajouter un tournoi"
|
||||
|
||||
#: participation/templates/participation/tournament_payments.html:9
|
||||
msgid "Back to tournament page"
|
||||
msgstr "Retour à la page du tournoi"
|
||||
|
||||
#: participation/templates/participation/upload_motivation_letter.html:6
|
||||
msgid "Back to the team detail"
|
||||
msgstr "Retour aux détails de l'utilisateur⋅rice"
|
||||
|
@ -1718,44 +1747,44 @@ msgstr "Modèles :"
|
|||
msgid "Warning: non-free format"
|
||||
msgstr "Attention : format non libre"
|
||||
|
||||
#: participation/views.py:55 tfjm/templates/base.html:79
|
||||
#: participation/views.py:56 tfjm/templates/base.html:79
|
||||
#: tfjm/templates/navbar.html:35
|
||||
msgid "Create team"
|
||||
msgstr "Créer une équipe"
|
||||
|
||||
#: participation/views.py:64 participation/views.py:105
|
||||
#: participation/views.py:65 participation/views.py:106
|
||||
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."
|
||||
|
||||
#: participation/views.py:66 participation/views.py:107
|
||||
#: participation/views.py:67 participation/views.py:108
|
||||
msgid "You are already in a team."
|
||||
msgstr "Vous êtes déjà dans une équipe."
|
||||
|
||||
#: participation/views.py:96 tfjm/templates/base.html:74
|
||||
#: participation/views.py:97 tfjm/templates/base.html:74
|
||||
#: tfjm/templates/navbar.html:40
|
||||
msgid "Join team"
|
||||
msgstr "Rejoindre une équipe"
|
||||
|
||||
#: participation/views.py:156 participation/views.py:501
|
||||
#: participation/views.py:157 participation/views.py:502
|
||||
msgid "You don't participate, so you don't have any team."
|
||||
msgstr "Vous ne participez pas, vous n'avez donc pas d'équipe."
|
||||
|
||||
#: participation/views.py:182
|
||||
#: participation/views.py:183
|
||||
#, python-brace-format
|
||||
msgid "Detail of team {trigram}"
|
||||
msgstr "Détails de l'équipe {trigram}"
|
||||
|
||||
#: participation/views.py:211
|
||||
#: participation/views.py:212
|
||||
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."
|
||||
|
||||
#: participation/views.py:214
|
||||
#: participation/views.py:215
|
||||
msgid "The validation of the team is already done or pending."
|
||||
msgstr "La validation de l'équipe est déjà faite ou en cours."
|
||||
|
||||
#: participation/views.py:217
|
||||
#: participation/views.py:218
|
||||
msgid ""
|
||||
"The team can't be validated: missing email address confirmations, "
|
||||
"authorizations, people, motivation letter or the tournament is not set."
|
||||
|
@ -1764,158 +1793,163 @@ msgstr ""
|
|||
"d'adresse e-mail, soit une autorisation, soit des personnes, soit la lettre "
|
||||
"de motivation, soit le tournoi n'a pas été choisi."
|
||||
|
||||
#: participation/views.py:239
|
||||
#: participation/views.py:240
|
||||
msgid "You are not an organizer of the tournament."
|
||||
msgstr "Vous n'êtes pas un⋅e organisateur⋅rice du tournoi."
|
||||
|
||||
#: participation/views.py:242
|
||||
#: participation/views.py:243
|
||||
msgid "This team has no pending validation."
|
||||
msgstr "L'équipe n'a pas de validation en attente."
|
||||
|
||||
#: participation/views.py:269
|
||||
#: participation/views.py:270
|
||||
msgid "You must specify if you validate the registration or not."
|
||||
msgstr "Vous devez spécifier si vous validez l'inscription ou non."
|
||||
|
||||
#: participation/views.py:304
|
||||
#: participation/views.py:305
|
||||
#, python-brace-format
|
||||
msgid "Update team {trigram}"
|
||||
msgstr "Mise à jour de l'équipe {trigram}"
|
||||
|
||||
#: participation/views.py:365 participation/views.py:448
|
||||
#: participation/views.py:366 participation/views.py:449
|
||||
#, python-brace-format
|
||||
msgid "Motivation letter of {team}.{ext}"
|
||||
msgstr "Lettre de motivation de {team}.{ext}"
|
||||
|
||||
#: participation/views.py:397
|
||||
#: participation/views.py:398
|
||||
#, python-brace-format
|
||||
msgid "Authorizations of team {trigram}.zip"
|
||||
msgstr "Autorisations de l'équipe {trigram}.zip"
|
||||
|
||||
#: participation/views.py:401
|
||||
#: participation/views.py:402
|
||||
#, python-brace-format
|
||||
msgid "Authorizations of {tournament}.zip"
|
||||
msgstr "Autorisations du tournoi {tournament}.zip"
|
||||
|
||||
#: participation/views.py:417
|
||||
#: participation/views.py:418
|
||||
#, python-brace-format
|
||||
msgid "Photo authorization of {participant}.{ext}"
|
||||
msgstr "Autorisation de droit à l'image de {participant}.{ext}"
|
||||
|
||||
#: participation/views.py:425
|
||||
#: participation/views.py:426
|
||||
#, python-brace-format
|
||||
msgid "Parental authorization of {participant}.{ext}"
|
||||
msgstr "Autorisation parentale de {participant}.{ext}"
|
||||
|
||||
#: participation/views.py:433
|
||||
#: participation/views.py:434
|
||||
#, python-brace-format
|
||||
msgid "Health sheet of {participant}.{ext}"
|
||||
msgstr "Fiche sanitaire de {participant}.{ext}"
|
||||
|
||||
#: participation/views.py:441
|
||||
#: participation/views.py:442
|
||||
#, python-brace-format
|
||||
msgid "Vaccine sheet of {participant}.{ext}"
|
||||
msgstr "Carnet de vaccination de {participant}.{ext}"
|
||||
|
||||
#: participation/views.py:515
|
||||
#: participation/views.py:516
|
||||
msgid "The team is not validated yet."
|
||||
msgstr "L'équipe n'est pas encore validée."
|
||||
|
||||
#: participation/views.py:529
|
||||
#: participation/views.py:530
|
||||
#, python-brace-format
|
||||
msgid "Participation of team {trigram}"
|
||||
msgstr "Participation de l'équipe {trigram}"
|
||||
|
||||
#: participation/views.py:611
|
||||
#: participation/views.py:612
|
||||
#, python-brace-format
|
||||
msgid "Payments of {tournament}"
|
||||
msgstr "Paiements de {tournament}"
|
||||
|
||||
#: participation/views.py:706
|
||||
#: participation/views.py:707
|
||||
msgid "Notes published!"
|
||||
msgstr "Notes publiées !"
|
||||
|
||||
#: participation/views.py:742
|
||||
#: participation/views.py:738
|
||||
#, python-brace-format
|
||||
msgid "Harmonize notes of {tournament} - Day {round}"
|
||||
msgstr "Harmoniser les notes de {tournament} - Jour {round}"
|
||||
|
||||
#: participation/views.py:818
|
||||
msgid "You can't upload a solution after the deadline."
|
||||
msgstr "Vous ne pouvez pas envoyer de solution après la date limite."
|
||||
|
||||
#: participation/views.py:866
|
||||
#: participation/views.py:942
|
||||
#, python-brace-format
|
||||
msgid "Solutions of team {trigram}.zip"
|
||||
msgstr "Solutions de l'équipe {trigram}.zip"
|
||||
|
||||
#: participation/views.py:866
|
||||
#: participation/views.py:942
|
||||
#, python-brace-format
|
||||
msgid "Syntheses of team {trigram}.zip"
|
||||
msgstr "Notes de synthèse de l'équipe {trigram}.zip"
|
||||
|
||||
#: participation/views.py:883 participation/views.py:898
|
||||
#: participation/views.py:959 participation/views.py:974
|
||||
#, python-brace-format
|
||||
msgid "Solutions of {tournament}.zip"
|
||||
msgstr "Solutions de {tournament}.zip"
|
||||
|
||||
#: participation/views.py:883 participation/views.py:898
|
||||
#: participation/views.py:959 participation/views.py:974
|
||||
#, python-brace-format
|
||||
msgid "Syntheses of {tournament}.zip"
|
||||
msgstr "Notes de synthèse de {tournament}.zip"
|
||||
|
||||
#: participation/views.py:907
|
||||
#: participation/views.py:983
|
||||
#, python-brace-format
|
||||
msgid "Solutions for pool {pool} of tournament {tournament}.zip"
|
||||
msgstr "Solutions pour la poule {pool} du tournoi {tournament}.zip"
|
||||
|
||||
#: participation/views.py:908
|
||||
#: participation/views.py:984
|
||||
#, python-brace-format
|
||||
msgid "Syntheses for pool {pool} of tournament {tournament}.zip"
|
||||
msgstr "Notes de synthèses pour la poule {pool} du tournoi {tournament}.zip"
|
||||
|
||||
#: participation/views.py:950
|
||||
#: participation/views.py:1026
|
||||
#, python-brace-format
|
||||
msgid "Jury of pool {pool} for {tournament} with teams {teams}"
|
||||
msgstr "Jury de la poule {pool} pour {tournament} avec les équipes {teams}"
|
||||
|
||||
#: participation/views.py:966
|
||||
#: participation/views.py:1042
|
||||
#, python-brace-format
|
||||
msgid "The jury {name} is already in the pool!"
|
||||
msgstr "{name} est déjà dans la poule !"
|
||||
|
||||
#: participation/views.py:986
|
||||
#: participation/views.py:1062
|
||||
msgid "New TFJM² jury account"
|
||||
msgstr "Nouveau compte de juré⋅e pour le TFJM²"
|
||||
|
||||
#: participation/views.py:1003
|
||||
#: participation/views.py:1079
|
||||
#, python-brace-format
|
||||
msgid "The jury {name} has been successfully added!"
|
||||
msgstr "{name} a été ajouté⋅e avec succès en tant que juré⋅e !"
|
||||
|
||||
#: participation/views.py:1039
|
||||
#: participation/views.py:1115
|
||||
#, python-brace-format
|
||||
msgid "The jury {name} has been successfully removed!"
|
||||
msgstr "{name} a été retiré⋅e avec succès du jury !"
|
||||
|
||||
#: participation/views.py:1065
|
||||
#: participation/views.py:1141
|
||||
#, python-brace-format
|
||||
msgid "The jury {name} has been successfully promoted president!"
|
||||
msgstr "{name} a été nommé⋅e président⋅e du jury !"
|
||||
|
||||
#: participation/views.py:1093
|
||||
#: participation/views.py:1169
|
||||
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 :"
|
||||
|
||||
#: participation/views.py:1107
|
||||
#: participation/views.py:1183
|
||||
msgid "Notes were successfully uploaded."
|
||||
msgstr "Les notes ont bien été envoyées."
|
||||
|
||||
#: participation/views.py:1740
|
||||
#: participation/views.py:1816
|
||||
#, python-brace-format
|
||||
msgid "Notation sheets of pool {pool} of {tournament}.zip"
|
||||
msgstr "Feuilles de notations pour la poule {pool} du tournoi {tournament}.zip"
|
||||
|
||||
#: participation/views.py:1745
|
||||
#: participation/views.py:1821
|
||||
#, python-brace-format
|
||||
msgid "Notation sheets of {tournament}.zip"
|
||||
msgstr "Feuilles de notation de {tournament}.zip"
|
||||
|
||||
#: participation/views.py:1924
|
||||
#: participation/views.py:2000
|
||||
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."
|
||||
|
||||
|
@ -3385,12 +3419,3 @@ msgstr "Aucun résultat."
|
|||
#: tfjm/templates/sidebar.html:10 tfjm/templates/sidebar.html:21
|
||||
msgid "Informations"
|
||||
msgstr "Informations"
|
||||
|
||||
#~ msgid "Export as CSV"
|
||||
#~ msgstr "Exporter en CSV"
|
||||
|
||||
#~ msgid "Add new pool"
|
||||
#~ msgstr "Ajouter une nouvelle poule"
|
||||
|
||||
#~ msgid "Add pool"
|
||||
#~ msgstr "Ajouter une poule"
|
||||
|
|
|
@ -201,4 +201,6 @@ class TournamentAdmin(admin.ModelAdmin):
|
|||
@admin.register(Tweak)
|
||||
class TweakAdmin(admin.ModelAdmin):
|
||||
list_display = ('participation', 'pool', 'diff',)
|
||||
list_filter = ('pool__tournament', 'pool__round',)
|
||||
search_fields = ('participation__team__name', 'participation__team__trigram',)
|
||||
autocomplete_fields = ('participation', 'pool',)
|
||||
|
|
|
@ -104,9 +104,9 @@
|
|||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% if not available_notes_1 or not available_notes_2 %}
|
||||
{% if user.registration.is_admin or user.registration in tournament.organizers.all %}
|
||||
<div class="card-footer text-center">
|
||||
{% if user.registration.is_admin or user.registration in tournament.organizers.all %}
|
||||
<div class="card-footer text-center">
|
||||
{% if not available_notes_1 or not available_notes_2 %}
|
||||
<div class="btn-group">
|
||||
{% if not available_notes_1 %}
|
||||
<a href="{% url 'participation:tournament_publish_notes' pk=tournament.pk round=1 %}" class="btn btn-info">
|
||||
|
@ -121,8 +121,18 @@
|
|||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="btn-group">
|
||||
<a href="{% url 'participation:tournament_harmonize' pk=tournament.pk round=1 %}" class="btn btn-secondary">
|
||||
<i class="fas fa-ranking-star"></i>
|
||||
{% trans "Harmonize" %} - {% trans "Day" %} 1
|
||||
</a>
|
||||
<a href="{% url 'participation:tournament_harmonize' pk=tournament.pk round=2 %}" class="btn btn-secondary">
|
||||
<i class="fas fa-ranking-star"></i>
|
||||
{% trans "Harmonize" %} - {% trans "Day" %} 2
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div class="card bg-body shadow">
|
||||
<div class="card-header text-center">
|
||||
<h5>{% trans "Ranking" %}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-striped text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Rank" %}</th>
|
||||
<th>{% trans "team"|capfirst %}</th>
|
||||
<th>{% trans "Note" %}</th>
|
||||
<th>{% trans "Including bonus / malus" %}</th>
|
||||
<th>{% trans "Add bonus / malus" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for participation, note in notes %}
|
||||
<tr>
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ participation.team }}</td>
|
||||
<td>{{ note.note|floatformat }}</td>
|
||||
<td>{% if note.tweak >= 0 %}+{% endif %}{{ note.tweak }}</td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<a href="{% url 'participation:tournament_harmonize_note' pk=tournament.pk round=round action="add" trigram=participation.team.trigram %}"
|
||||
class="btn btn-sm btn-success">
|
||||
+1
|
||||
</a>
|
||||
<a href="{% url 'participation:tournament_harmonize_note' pk=tournament.pk round=round action="remove" trigram=participation.team.trigram %}"
|
||||
class="btn btn-sm btn-danger">
|
||||
-1
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-footer text-center">
|
||||
<a class="btn btn-secondary" href="{% url 'participation:tournament_detail' pk=tournament.pk %}">
|
||||
<i class="fas fa-arrow-left-long"></i>
|
||||
{% trans "Back to tournament page" %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -11,7 +11,8 @@ from .views import CreateTeamView, FinalNotationSheetTemplateView, JoinTeamView,
|
|||
ScaleNotationSheetTemplateView, SolutionsDownloadView, SolutionUploadView, SynthesisUploadView, \
|
||||
TeamAuthorizationsView, TeamDetailView, TeamLeaveView, TeamListView, TeamUpdateView, \
|
||||
TeamUploadMotivationLetterView, TournamentCreateView, TournamentDetailView, TournamentExportCSVView, \
|
||||
TournamentListView, TournamentPaymentsView, TournamentPublishNotesView, TournamentUpdateView
|
||||
TournamentHarmonizeView, TournamentHarmonizeNoteView, TournamentListView, TournamentPaymentsView, \
|
||||
TournamentPublishNotesView, TournamentUpdateView
|
||||
|
||||
|
||||
app_name = "participation"
|
||||
|
@ -47,6 +48,10 @@ urlpatterns = [
|
|||
name="tournament_notation_sheets"),
|
||||
path("tournament/<int:pk>/publish-notes/<int:round>/", TournamentPublishNotesView.as_view(),
|
||||
name="tournament_publish_notes"),
|
||||
path("tournament/<int:pk>/harmonize/<int:round>/", TournamentHarmonizeView.as_view(),
|
||||
name="tournament_harmonize"),
|
||||
path("tournament/<int:pk>/harmonize/<int:round>/<str:action>/<str:trigram>/", TournamentHarmonizeNoteView.as_view(),
|
||||
name="tournament_harmonize_note"),
|
||||
path("pools/create/", PoolCreateView.as_view(), name="pool_create"),
|
||||
path("pools/<int:pk>/", PoolDetailView.as_view(), name="pool_detail"),
|
||||
path("pools/<int:pk>/update/", PoolUpdateView.as_view(), name="pool_update"),
|
||||
|
|
|
@ -9,6 +9,7 @@ from tempfile import mkdtemp
|
|||
from typing import Any, Dict
|
||||
from zipfile import ZipFile
|
||||
|
||||
import gspread
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
|
@ -41,7 +42,7 @@ from tfjm.views import AdminMixin, VolunteerMixin
|
|||
from .forms import AddJuryForm, JoinTeamForm, MotivationLetterForm, NoteForm, ParticipationForm, PassageForm, \
|
||||
PoolForm, PoolTeamsForm, RequestValidationForm, SolutionForm, SynthesisForm, TeamForm, TournamentForm, \
|
||||
UploadNotesForm, ValidateParticipationForm
|
||||
from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament
|
||||
from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament, Tweak
|
||||
from .tables import NoteTable, ParticipationTable, PassageTable, PoolTable, TeamTable, TournamentTable
|
||||
|
||||
|
||||
|
@ -710,6 +711,81 @@ class TournamentPublishNotesView(VolunteerMixin, SingleObjectMixin, RedirectView
|
|||
return reverse_lazy("participation:tournament_detail", args=(kwargs['pk'],))
|
||||
|
||||
|
||||
class TournamentHarmonizeView(VolunteerMixin, DetailView):
|
||||
"""
|
||||
Harmonize the notes of a tournament.
|
||||
"""
|
||||
model = Tournament
|
||||
template_name = "participation/tournament_harmonize.html"
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not request.user.is_authenticated:
|
||||
return self.handle_no_permission()
|
||||
tournament = self.get_object()
|
||||
reg = request.user.registration
|
||||
if not reg.is_admin and (not reg.is_volunteer or tournament not in reg.organized_tournaments.all()):
|
||||
return self.handle_no_permission()
|
||||
if self.kwargs['round'] not in (1, 2):
|
||||
raise Http404
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
tournament = self.get_object()
|
||||
context['round'] = self.kwargs['round']
|
||||
context['pools'] = tournament.pools.filter(round=context["round"]).all()
|
||||
context['title'] = _("Harmonize notes of {tournament} - Day {round}") \
|
||||
.format(tournament=tournament, round=context["round"])
|
||||
|
||||
notes = dict()
|
||||
for participation in self.object.participations.all():
|
||||
note = sum(pool.average(participation) for pool in context['pools'])
|
||||
tweak = sum(tweak.diff for tweak in participation.tweaks.filter(pool__in=context['pools']).all())
|
||||
notes[participation] = {'note': note, 'tweak': tweak}
|
||||
context["notes"] = sorted(notes.items(), key=lambda x: x[1]['note'], reverse=True)
|
||||
|
||||
return context
|
||||
|
||||
|
||||
class TournamentHarmonizeNoteView(VolunteerMixin, DetailView):
|
||||
model = Tournament
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not request.user.is_authenticated:
|
||||
return self.handle_no_permission()
|
||||
tournament = self.get_object()
|
||||
reg = request.user.registration
|
||||
if not reg.is_admin and (not reg.is_volunteer or tournament not in reg.organized_tournaments.all()):
|
||||
return self.handle_no_permission()
|
||||
if self.kwargs['round'] not in (1, 2) or self.kwargs['action'] not in ('add', 'remove') \
|
||||
or self.kwargs['trigram'] not in [p.team.trigram for p in tournament.participations.all()]:
|
||||
raise Http404
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
tournament = self.get_object()
|
||||
participation = tournament.participations.get(team__trigram=kwargs['trigram'])
|
||||
pool = tournament.pools.get(round=kwargs['round'], participations=participation)
|
||||
tweak_qs = Tweak.objects.filter(participation=participation, pool=pool)
|
||||
old_diff = tweak_qs.first().diff if tweak_qs.exists() else 0
|
||||
new_diff = old_diff + (1 if kwargs['action'] == 'add' else -1)
|
||||
if new_diff == 0:
|
||||
tweak_qs.delete()
|
||||
else:
|
||||
tweak_qs.update_or_create(defaults={'diff': new_diff},
|
||||
create_defaults={'diff': new_diff, 'participation': participation, 'pool': pool})
|
||||
|
||||
gc = gspread.service_account_from_dict(settings.GOOGLE_SERVICE_CLIENT)
|
||||
spreadsheet = gc.open_by_key(tournament.notes_sheet_id)
|
||||
worksheet = spreadsheet.worksheet("Classement final")
|
||||
column = 3 if kwargs['round'] == '1' else 5
|
||||
row = worksheet.find(f"{participation.team.name} ({participation.team.trigram})", in_column=1).row
|
||||
worksheet.update_cell(row, column, new_diff)
|
||||
|
||||
return redirect(reverse_lazy("participation:tournament_harmonize", args=(tournament.pk, kwargs['round'],)))
|
||||
|
||||
|
||||
class SolutionUploadView(LoginRequiredMixin, FormView):
|
||||
template_name = "participation/upload_solution.html"
|
||||
form_class = SolutionForm
|
||||
|
|
Loading…
Reference in New Issue