1
0
mirror of https://gitlab.com/animath/si/plateforme.git synced 2025-06-15 22:27:31 +02:00

Compare commits

..

3 Commits

7 changed files with 69 additions and 23 deletions

View File

@ -1,7 +1,9 @@
# Copyright (C) 2020 by Animath # Copyright (C) 2020 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
from django.contrib import admin from django.contrib import admin
from django.http import HttpRequest
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .models import Note, Participation, Passage, Pool, Solution, Team, Tournament, Tweak, WrittenReview from .models import Note, Participation, Passage, Pool, Solution, Team, Tournament, Tweak, WrittenReview
@ -51,9 +53,14 @@ class PassageInline(admin.TabularInline):
model = Passage model = Passage
extra = 0 extra = 0
ordering = ('position',) ordering = ('position',)
autocomplete_fields = ('reporter', 'opponent', 'reviewer', 'observer',)
show_change_link = True show_change_link = True
def get_autocomplete_fields(self, request: HttpRequest) -> tuple[str]:
fields = ('reporter', 'opponent', 'reviewer',)
if settings.HAS_OBSERVER:
fields += ('observer',)
return fields
class NoteInline(admin.TabularInline): class NoteInline(admin.TabularInline):
model = Note model = Note
@ -113,12 +120,9 @@ class PoolAdmin(admin.ModelAdmin):
@admin.register(Passage) @admin.register(Passage)
class PassageAdmin(admin.ModelAdmin): class PassageAdmin(admin.ModelAdmin):
list_display = ('__str__', 'reporter_trigram', 'solution_number', 'opponent_trigram', 'reviewer_trigram',
'observer_trigram', 'pool_abbr', 'position', 'tournament')
list_filter = ('pool__tournament', 'pool__round', 'pool__letter', 'solution_number',) list_filter = ('pool__tournament', 'pool__round', 'pool__letter', 'solution_number',)
search_fields = ('pool__participations__team__name', 'pool__participations__team__trigram',) search_fields = ('pool__participations__team__name', 'pool__participations__team__trigram',)
ordering = ('pool__tournament', 'pool__round', 'pool__letter', 'position',) ordering = ('pool__tournament', 'pool__round', 'pool__letter', 'position',)
autocomplete_fields = ('pool', 'reporter', 'opponent', 'reviewer', 'observer',)
inlines = (NoteInline,) inlines = (NoteInline,)
@admin.display(description=_("reporter"), ordering='reporter__team__trigram') @admin.display(description=_("reporter"), ordering='reporter__team__trigram')
@ -135,7 +139,7 @@ class PassageAdmin(admin.ModelAdmin):
@admin.display(description=_("observer"), ordering='observer__team__trigram') @admin.display(description=_("observer"), ordering='observer__team__trigram')
def observer_trigram(self, record: Passage): def observer_trigram(self, record: Passage):
return record.observer.team.trigram return record.observer.team.trigram if record.observer else None
@admin.display(description=_("pool"), ordering='pool__letter') @admin.display(description=_("pool"), ordering='pool__letter')
def pool_abbr(self, record): def pool_abbr(self, record):
@ -145,15 +149,23 @@ class PassageAdmin(admin.ModelAdmin):
def tournament(self, record: Passage): def tournament(self, record: Passage):
return record.pool.tournament return record.pool.tournament
def get_list_display(self, request: HttpRequest) -> tuple[str]:
if settings.HAS_OBSERVER:
return ('__str__', 'reporter_trigram', 'solution_number', 'opponent_trigram',
'reviewer_trigram', 'observer_trigram', 'pool_abbr', 'position', 'tournament')
else:
return ('__str__', 'reporter_trigram', 'solution_number', 'opponent_trigram',
'reviewer_trigram', 'pool_abbr', 'position', 'tournament')
def get_autocomplete_fields(self, request: HttpRequest) -> tuple[str]:
fields = ('pool', 'reporter', 'opponent', 'reviewer',)
if settings.HAS_OBSERVER:
fields += ('observer',)
return fields
@admin.register(Note) @admin.register(Note)
class NoteAdmin(admin.ModelAdmin): class NoteAdmin(admin.ModelAdmin):
list_display = ('passage', 'pool', 'jury', 'reporter_writing', 'reporter_oral',
'opponent_writing', 'opponent_oral', 'reviewer_writing', 'reviewer_oral',
'observer_writing', 'observer_oral',)
list_filter = ('passage__pool__letter', 'passage__solution_number', 'jury',
'reporter_writing', 'reporter_oral', 'opponent_writing', 'opponent_oral',
'reviewer_writing', 'reviewer_oral', 'observer_writing', 'observer_oral')
search_fields = ('jury__user__last_name', 'jury__user__first_name', 'passage__reporter__team__trigram',) search_fields = ('jury__user__last_name', 'jury__user__first_name', 'passage__reporter__team__trigram',)
autocomplete_fields = ('jury', 'passage',) autocomplete_fields = ('jury', 'passage',)
@ -161,6 +173,21 @@ class NoteAdmin(admin.ModelAdmin):
def pool(self, record): def pool(self, record):
return record.passage.pool.short_name return record.passage.pool.short_name
def get_list_display(self, request: HttpRequest) -> tuple[str]:
fields = ('passage', 'pool', 'jury', 'reporter_writing', 'reporter_oral',
'opponent_writing', 'opponent_oral', 'reviewer_writing', 'reviewer_oral',)
if settings.HAS_OBSERVER:
fields += ('observer_writing', 'observer_oral',)
return fields
def get_list_filter(self, request: HttpRequest) -> tuple[str]:
fields = ('passage__pool__letter', 'passage__solution_number', 'jury',
'reporter_writing', 'reporter_oral', 'opponent_writing', 'opponent_oral',
'reviewer_writing', 'reviewer_oral',)
if settings.HAS_OBSERVER:
fields += ('observer_writing', 'observer_oral',)
return fields
@admin.register(Solution) @admin.register(Solution)
class SolutionAdmin(admin.ModelAdmin): class SolutionAdmin(admin.ModelAdmin):

View File

@ -7,6 +7,7 @@ import re
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
from crispy_forms.layout import Div, Field, HTML, Layout, Submit from crispy_forms.layout import Div, Field, HTML, Layout, Submit
from django import forms from django import forms
from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.validators import FileExtensionValidator from django.core.validators import FileExtensionValidator
@ -14,7 +15,6 @@ from django.utils.translation import gettext_lazy as _
import pandas import pandas
from pypdf import PdfReader from pypdf import PdfReader
from registration.models import VolunteerRegistration from registration.models import VolunteerRegistration
from tfjm import settings
from .models import Note, Participation, Passage, Pool, Solution, Team, Tournament, WrittenReview from .models import Note, Participation, Passage, Pool, Solution, Team, Tournament, WrittenReview
@ -405,6 +405,12 @@ class WrittenReviewForm(forms.ModelForm):
class NoteForm(forms.ModelForm): class NoteForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if not settings.HAS_OBSERVER:
del self.fields['observer_writing']
del self.fields['observer_oral']
class Meta: class Meta:
model = Note model = Note
fields = ('reporter_writing', 'reporter_oral', 'opponent_writing', fields = ('reporter_writing', 'reporter_oral', 'opponent_writing',

View File

@ -1,6 +1,7 @@
# Copyright (C) 2020 by Animath # Copyright (C) 2020 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
from django.utils import formats from django.utils import formats
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.text import format_lazy from django.utils.text import format_lazy
@ -106,7 +107,10 @@ class PoolTable(tables.Table):
class PassageTable(tables.Table): class PassageTable(tables.Table):
# FIXME Ne pas afficher l'équipe observatrice si non nécessaire def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if not settings.HAS_OBSERVER:
del self.columns['observer']
reporter = tables.LinkColumn( reporter = tables.LinkColumn(
"participation:passage_detail", "participation:passage_detail",
@ -135,6 +139,12 @@ class PassageTable(tables.Table):
class NoteTable(tables.Table): class NoteTable(tables.Table):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if not settings.HAS_OBSERVER:
del self.columns['observer_writing']
del self.columns['observer_oral']
jury = tables.Column( jury = tables.Column(
attrs={ attrs={
"td": { "td": {

View File

@ -58,7 +58,7 @@
%%%%%%%%%%%%%%%%%%%%%DEFENSEUR %%%%%%%%%%%%%%%%%%%%%DEFENSEUR
\begin{tabular}{|c|p{25mm}|p{11cm}|c|{% for passage in passages.all %}p{2cm}|{% endfor %}}\hline \begin{tabular}{|c|p{25mm}|p{11cm}|c|{% for passage in passages.all %}p{2cm}|{% endfor %}}\hline
\multicolumn{4}{|l|}{The {\bf {% trans "Reporter" %}} \normalsize presents their ideas and major results for the solution of the problem.} {% for passage in passages.all %}& P.{{ forloop.counter }} - {{ passage.reporter.team.trigram }} {% endfor %}\\ \hline \hline \multicolumn{4}{|l|}{The {\bf {% trans "Reporter" %}} \normalsize presents their ideas and major results for the solution of the problem.} {% for passage in passages.all %}& Pb. {{ passage.solution_number }} - {{ passage.reporter.team.trigram }} {% endfor %}\\ \hline \hline
%ECRIT %ECRIT
\multirow{7}{3mm}{\bf \begin{turn}{90}WRITING\end{turn}} & \multirow{3}{20mm}{ {% trans "Scientific part" %}} & {% trans "Depth and difficulty of the elements presented" %} & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}} \multirow{7}{3mm}{\bf \begin{turn}{90}WRITING\end{turn}} & \multirow{3}{20mm}{ {% trans "Scientific part" %}} & {% trans "Depth and difficulty of the elements presented" %} & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}}
@ -86,7 +86,7 @@
%%%%%%%%%%%%%%%%%OPPOSANT⋅E %%%%%%%%%%%%%%%%%OPPOSANT⋅E
\begin{tabular}{|c|p{25mm}|p{11cm}|c{% for passage in passages.all %}|p{2cm}{% endfor %}|}\hline \begin{tabular}{|c|p{25mm}|p{11cm}|c{% for passage in passages.all %}|p{2cm}{% endfor %}|}\hline
\multicolumn{4}{|l|}{The {\bf {% trans "Opponent" %}} \normalsize provides a critical analysis of the solution and presentation.} \multicolumn{4}{|l|}{The {\bf {% trans "Opponent" %}} \normalsize provides a critical analysis of the solution and presentation.}
{% for passage in passages.all %}& P.{{ forloop.counter }} - {{ passage.opponent.team.trigram }} {% endfor %} \\ \hline \hline {% for passage in passages.all %}& Pb. {{ passage.solution_number }} - {{ passage.opponent.team.trigram }} {% endfor %} \\ \hline \hline
%ECRIT %ECRIT
\multirow{6}{3mm}{\bf \begin{turn}{90}WRITING\end{turn}} &\multirow{4}{25mm}{ {% trans "Scientific part" %}} & {% trans "Critical thinking and perspective on the proposed solution" %} & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}} \multirow{6}{3mm}{\bf \begin{turn}{90}WRITING\end{turn}} &\multirow{4}{25mm}{ {% trans "Scientific part" %}} & {% trans "Critical thinking and perspective on the proposed solution" %} & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}}
@ -108,7 +108,7 @@
%%%%%%%%%%%%%%%%%%%%%%RAPPORTEUR⋅RICE %%%%%%%%%%%%%%%%%%%%%%RAPPORTEUR⋅RICE
\begin{tabular}{|c|p{25mm}|p{11cm}|c{% for passage in passages.all %}|p{2cm}{% endfor %}|}\hline \begin{tabular}{|c|p{25mm}|p{11cm}|c{% for passage in passages.all %}|p{2cm}{% endfor %}|}\hline
\multicolumn{4}{|l|}{The {\bf {% trans "Reviewer" %}} \normalsize evaluates the debate between the Reporter and the Opponent.} {% for passage in passages.all %}& P.{{ forloop.counter }} - {{ passage.reviewer.team.trigram }} {% endfor %}\\ \hline \hline \multicolumn{4}{|l|}{The {\bf {% trans "Reviewer" %}} \normalsize evaluates the debate between the Reporter and the Opponent.} {% for passage in passages.all %}& Pb. {{ passage.solution_number }} - {{ passage.reviewer.team.trigram }} {% endfor %}\\ \hline \hline
%ECRIT %ECRIT
\multirow{6}{3mm}{\bf \begin{turn}{90}WRITING\end{turn}} &\multirow{4}{25mm}{ {% trans "Scientific part" %}} & {% trans "Critical thinking and perspective on the proposed solution" %} & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}} \multirow{6}{3mm}{\bf \begin{turn}{90}WRITING\end{turn}} &\multirow{4}{25mm}{ {% trans "Scientific part" %}} & {% trans "Critical thinking and perspective on the proposed solution" %} & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}}
@ -131,7 +131,7 @@
{% if TFJM.APP == "ETEAM" and pool.participations.count >= 4 %} {% if TFJM.APP == "ETEAM" and pool.participations.count >= 4 %}
%%%%%%%%%%%%%%%%%%%%%%OBSERVATEUR⋅RICE %%%%%%%%%%%%%%%%%%%%%%OBSERVATEUR⋅RICE
\begin{tabular}{|c|p{25mm}|p{11cm}|c{% for passage in passages.all %}|p{2cm}{% endfor %}|}\hline \begin{tabular}{|c|p{25mm}|p{11cm}|c{% for passage in passages.all %}|p{2cm}{% endfor %}|}\hline
\multicolumn{4}{|l|}{The {\bf {% trans "Observer" %}} \normalsize makes useful remarks on crucial points missed by the other participants.} {% for passage in passages.all %}& P.{{ forloop.counter }} - {{ passage.observer.team.trigram }} {% endfor %}\\ \hline \hline \multicolumn{4}{|l|}{The {\bf {% trans "Observer" %}} \normalsize makes useful remarks on crucial points missed by the other participants.} {% for passage in passages.all %}& Pb. {{ passage.solution_number }} - {{ passage.observer.team.trigram }} {% endfor %}\\ \hline \hline
%ECRIT %ECRIT
\multirow{6}{3mm}{\bf \begin{turn}{90}WRITING\end{turn}} &\multirow{4}{25mm}{ {% trans "Scientific part" %}} & {% trans "Critical thinking and perspective on the proposed solution" %} & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}} \multirow{6}{3mm}{\bf \begin{turn}{90}WRITING\end{turn}} &\multirow{4}{25mm}{ {% trans "Scientific part" %}} & {% trans "Critical thinking and perspective on the proposed solution" %} & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}}

View File

@ -52,7 +52,7 @@
%%%%%%%%%%%%%%%%%%%%%DEFENSEUR %%%%%%%%%%%%%%%%%%%%%DEFENSEUR
\begin{tabular}{|c|p{24mm}|p{11cm}|c|{% for passage in passages.all %}p{2cm}|{% endfor %}}\hline \begin{tabular}{|c|p{24mm}|p{11cm}|c|{% for passage in passages.all %}p{2cm}|{% endfor %}}\hline
\multicolumn{4}{|l|}{{\bf D\'efenseur⋅se} \normalsize pr\'esente les id\'ees et r\'esultats principaux pour la solution du probl\`eme.} {% for passage in passages.all %}& P.{{ forloop.counter }} - {{ passage.reporter.team.trigram }} {% endfor %}\\ \hline \hline \multicolumn{4}{|l|}{{\bf D\'efenseur⋅se} \normalsize pr\'esente les id\'ees et r\'esultats principaux pour la solution du probl\`eme.} {% for passage in passages.all %}& Pb. {{ passage.solution_number }} - {{ passage.reporter.team.trigram }} {% endfor %}\\ \hline \hline
%ECRIT %ECRIT
\multirow{7}{3mm}{\bf \begin{turn}{90}ÉCRIT\end{turn}} & \multirow{3}{24mm}{Partie scientifique} & Profondeur et difficulté des éléments présentés & [0,6] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}} \multirow{7}{3mm}{\bf \begin{turn}{90}ÉCRIT\end{turn}} & \multirow{3}{24mm}{Partie scientifique} & Profondeur et difficulté des éléments présentés & [0,6] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}}
@ -80,7 +80,7 @@
%%%%%%%%%%%%%%%%%OPPOSANT %%%%%%%%%%%%%%%%%OPPOSANT
\begin{tabular}{|c|p{24mm}|p{11cm}|c{% for passage in passages.all %}|p{2cm}{% endfor %}|}\hline \begin{tabular}{|c|p{24mm}|p{11cm}|c{% for passage in passages.all %}|p{2cm}{% endfor %}|}\hline
\multicolumn{4}{|l|}{L' {\bf Opposant⋅e} \normalsize fournit une analyse critique de la solution et de la pr\'esentation.} \multicolumn{4}{|l|}{L' {\bf Opposant⋅e} \normalsize fournit une analyse critique de la solution et de la pr\'esentation.}
{% for passage in passages.all %}& P.{{ forloop.counter }} - {{ passage.opponent.team.trigram }} {% endfor %} \\ \hline \hline {% for passage in passages.all %}& Pb. {{ passage.solution_number }} - {{ passage.opponent.team.trigram }} {% endfor %} \\ \hline \hline
%ECRIT %ECRIT
\multirow{6}{3mm}{\bf \begin{turn}{90}ÉCRIT\end{turn}} &\multirow{4}{24mm}{Partie scientifique} & Recul et esprit critique par rapport à la solution proposée & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}} \multirow{6}{3mm}{\bf \begin{turn}{90}ÉCRIT\end{turn}} &\multirow{4}{24mm}{Partie scientifique} & Recul et esprit critique par rapport à la solution proposée & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}}
@ -102,7 +102,7 @@
%%%%%%%%%%%%%%%%%%%%%%RAPPORTEUR.RICE %%%%%%%%%%%%%%%%%%%%%%RAPPORTEUR.RICE
\begin{tabular}{|c|p{24mm}|p{11cm}|c{% for passage in passages.all %}|p{2cm}{% endfor %}|}\hline \begin{tabular}{|c|p{24mm}|p{11cm}|c{% for passage in passages.all %}|p{2cm}{% endfor %}|}\hline
\multicolumn{4}{|l|}{{\bf Rapporteur⋅rice} \normalsize \'evalue le d\'ebat entre læ D\'efenseur⋅se et l'Opposant⋅e.} {% for passage in passages.all %}& P.{{ forloop.counter }} - {{ passage.reviewer.team.trigram }} {% endfor %}\\ \hline \hline \multicolumn{4}{|l|}{{\bf Rapporteur⋅rice} \normalsize \'evalue le d\'ebat entre læ D\'efenseur⋅se et l'Opposant⋅e.} {% for passage in passages.all %}& Pb. {{ passage.solution_number }} - {{ passage.reviewer.team.trigram }} {% endfor %}\\ \hline \hline
%ECRIT %ECRIT
\multirow{6}{3mm}{\bf \begin{turn}{90}ÉCRIT\end{turn}} &\multirow{4}{24mm}{Partie scientifique} & Recul et esprit critique par rapport à la solution proposée & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}} \multirow{6}{3mm}{\bf \begin{turn}{90}ÉCRIT\end{turn}} &\multirow{4}{24mm}{Partie scientifique} & Recul et esprit critique par rapport à la solution proposée & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}}
@ -115,7 +115,7 @@
\multirow{9}{3mm}{\bf \begin{turn}{90}ORAL\end{turn}} & \multirow{5}{24mm}{Questions et discours de læ rapporteur⋅rice} & \footnotesize Faire prendre de la hauteur au débat (par les sujets abordés, la pertinence des questions posées, les points soulevés, gestion du temps) & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}} \multirow{9}{3mm}{\bf \begin{turn}{90}ORAL\end{turn}} & \multirow{5}{24mm}{Questions et discours de læ rapporteur⋅rice} & \footnotesize Faire prendre de la hauteur au débat (par les sujets abordés, la pertinence des questions posées, les points soulevés, gestion du temps) & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}}
&& \footnotesize Créer un échange constructif entre les participants (formulation des questions, réaction aux réponses, articulation entre les questions, circulation de la parole) & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}} && \footnotesize Créer un échange constructif entre les participants (formulation des questions, réaction aux réponses, articulation entre les questions, circulation de la parole) & [0,3] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}}
&& Capacité à évaluer la qualité des échanges (Défenseur⋅se-Opposant⋅e et à trois) & [0,2] {{ esp|safe }}\\ \cline{2-{{ passages.count|add:4 }}} && Capacité à évaluer la qualité des échanges (Défenseur⋅se-Opposant⋅e et à trois) & [0,2] {{ esp|safe }}\\ \cline{2-{{ passages.count|add:4 }}}
&& Réponses aux questions de læ Rapporteur⋅rice et du jury (fond et capacité à faire avancer le débat) & [0,2] {{ esp|safe }}\\ \cline{2-{{ passages.count|add:4 }}} && Réponses aux questions du jury (fond et capacité à faire avancer le débat) & [0,2] {{ esp|safe }}\\ \cline{2-{{ passages.count|add:4 }}}
& Malus & Attitude irrespectueuse ? & [-3,0] {{ esp|safe }}\\ \cline{2-{{ passages.count|add:4 }}} & Malus & Attitude irrespectueuse ? & [-3,0] {{ esp|safe }}\\ \cline{2-{{ passages.count|add:4 }}}
&\multicolumn{3}{|l|}{\bf TOTAL ORAL (/10)} {{ esp|safe }}\\ \hline &\multicolumn{3}{|l|}{\bf TOTAL ORAL (/10)} {{ esp|safe }}\\ \hline
\end{tabular} \end{tabular}

View File

@ -70,7 +70,7 @@ class Survey(models.Model):
teams = Team.objects.filter(participation__valid=True) teams = Team.objects.filter(participation__valid=True)
if self.tournament: if self.tournament:
teams = teams.filter(participation__tournament=self.tournament) teams = teams.filter(participation__tournament=self.tournament)
return teams.all() return teams.order_by('participation__tournament__name', 'trigram').all()
else: else:
if self.invite_coaches: if self.invite_coaches:
registrations = ParticipantRegistration.objects.filter(team__participation__valid=True) registrations = ParticipantRegistration.objects.filter(team__participation__valid=True)
@ -78,7 +78,7 @@ class Survey(models.Model):
registrations = StudentRegistration.objects.filter(team__participation__valid=True) registrations = StudentRegistration.objects.filter(team__participation__valid=True)
if self.tournament: if self.tournament:
registrations = registrations.filter(team__participation__tournament=self.tournament) registrations = registrations.filter(team__participation__tournament=self.tournament)
return registrations.all() return registrations.order_by('team__participation__tournament__name', 'team__trigram').all()
@property @property
def completed(self): def completed(self):

View File

@ -48,6 +48,7 @@
<thead> <thead>
<tr> <tr>
<th>{% trans "participant"|capfirst %}</th> <th>{% trans "participant"|capfirst %}</th>
<th>{% trans "tournament"|capfirst %}</th>
<th>{% trans "completed"|capfirst %}</th> <th>{% trans "completed"|capfirst %}</th>
</tr> </tr>
</thead> </thead>
@ -56,8 +57,10 @@
<tr class="{% if participant in survey.completed.all %}table-success{% else %}table-danger{% endif %}"> <tr class="{% if participant in survey.completed.all %}table-success{% else %}table-danger{% endif %}">
{% if survey.invite_team %} {% if survey.invite_team %}
<td>{% trans "Team" %} {{ participant.name }} ({{ participant.trigram }})</td> <td>{% trans "Team" %} {{ participant.name }} ({{ participant.trigram }})</td>
<td>{{ participant.participation.tournament.name }}</td>
{% else %} {% else %}
<td>{{ participant.user.first_name }} {{ participant.user.last_name }} ({% trans "team" %} {{ participant.team.trigram }})</td> <td>{{ participant.user.first_name }} {{ participant.user.last_name }} ({% trans "team" %} {{ participant.team.trigram }})</td>
<td>{{ participant.team.participation.tournament.name }}</td>
{% endif %} {% endif %}
{% if participant in survey.completed.all %} {% if participant in survey.completed.all %}
<td>{% trans "Yes" %}</td> <td>{% trans "Yes" %}</td>