diff --git a/draw/models.py b/draw/models.py index 836f8be..bf35f63 100644 --- a/draw/models.py +++ b/draw/models.py @@ -353,6 +353,7 @@ class Pool(models.Model): await self.asave() # Define the passage matrix according to the number of teams + table = [] if self.size == 3: table = [ [0, 1, 2], @@ -361,10 +362,10 @@ class Pool(models.Model): ] elif self.size == 4: table = [ - [0, 1, 2], - [1, 2, 3], - [2, 3, 0], - [3, 0, 1], + [0, 1, 2, 3], + [1, 2, 3, 0], + [2, 3, 0, 1], + [3, 0, 1, 2], ] elif self.size == 5: table = [ @@ -377,7 +378,7 @@ class Pool(models.Model): for i, line in enumerate(table): # Create the passage - await Passage.objects.acreate( + passage = await Passage.objects.acreate( pool=self.associated_pool, position=i + 1, solution_number=tds[line[0]].accepted, @@ -386,6 +387,10 @@ class Pool(models.Model): reporter=tds[line[2]].participation, defender_penalties=tds[line[0]].penalty_int, ) + if self.size == 4: + # Add observer for 4-teams pools + passage.observer = tds[line[3]].participation + await passage.asave() return self.associated_pool diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index ae9c03c..4285811 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: TFJM\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-04-07 00:04+0200\n" +"POT-Creation-Date: 2023-04-07 12:02+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Emmy D'Anello \n" "Language-Team: LANGUAGE \n" @@ -33,7 +33,7 @@ msgstr "équipes" msgid "tournament" msgstr "tournoi" -#: draw/admin.py:60 draw/models.py:228 draw/models.py:415 +#: draw/admin.py:60 draw/models.py:228 draw/models.py:420 #: participation/models.py:355 msgid "round" msgstr "tour" @@ -201,78 +201,78 @@ msgstr "poule associée" msgid "The full pool instance." msgstr "L'instance complète de la poule." -#: draw/models.py:393 +#: draw/models.py:398 #, python-brace-format msgid "Pool {letter}{number}" msgstr "Poule {letter}{number}" -#: draw/models.py:396 draw/models.py:423 participation/admin.py:69 +#: draw/models.py:401 draw/models.py:428 participation/admin.py:69 #: participation/admin.py:88 participation/models.py:421 #: participation/models.py:430 participation/tables.py:82 msgid "pool" msgstr "poule" -#: draw/models.py:397 participation/models.py:422 +#: draw/models.py:402 participation/models.py:422 msgid "pools" msgstr "poules" -#: draw/models.py:409 participation/models.py:342 participation/models.py:562 -#: participation/models.py:592 participation/models.py:630 +#: draw/models.py:414 participation/models.py:342 participation/models.py:580 +#: participation/models.py:610 participation/models.py:648 msgid "participation" msgstr "participation" -#: draw/models.py:430 +#: draw/models.py:435 msgid "passage index" msgstr "numéro de passage" -#: draw/models.py:431 +#: draw/models.py:436 msgid "" "The passage order in the pool, between 0 and the size of the pool minus 1." msgstr "" "L'ordre de passage dans la poule, de 0 à la taille de la poule moins 1." -#: draw/models.py:439 +#: draw/models.py:444 msgid "choose index" msgstr "numéro de choix" -#: draw/models.py:440 +#: draw/models.py:445 msgid "" "The choice order in the pool, between 0 and the size of the pool minus 1." msgstr "" "L'ordre de choix dans la poule, entre 0 et la taille de la poule moins 1." -#: draw/models.py:446 draw/models.py:469 participation/models.py:444 -#: participation/models.py:599 +#: draw/models.py:451 draw/models.py:474 participation/models.py:444 +#: participation/models.py:617 #, python-brace-format msgid "Problem #{problem}" msgstr "Problème n°{problem}" -#: draw/models.py:450 draw/models.py:473 +#: draw/models.py:455 draw/models.py:478 msgid "accepted problem" msgstr "problème accepté" -#: draw/models.py:457 +#: draw/models.py:462 msgid "passage dice" msgstr "dé d'ordre de passage" -#: draw/models.py:464 +#: draw/models.py:469 msgid "choice dice" msgstr "dé d'ordre de choix" -#: draw/models.py:478 +#: draw/models.py:483 msgid "rejected problems" msgstr "problèmes rejetés" -#: draw/models.py:504 +#: draw/models.py:509 #, python-brace-format msgid "Draw of the team {trigram} for the pool {letter}{number}" msgstr "Tirage de l'équipe {trigram} pour la poule {letter}{number}" -#: draw/models.py:510 +#: draw/models.py:515 msgid "team draw" msgstr "tirage d'équipe" -#: draw/models.py:511 +#: draw/models.py:516 msgid "team draws" msgstr "tirages d'équipe" @@ -439,16 +439,16 @@ msgid "defender" msgstr "défenseur⋅se" #: participation/admin.py:61 participation/models.py:458 -#: participation/models.py:642 +#: participation/models.py:660 msgid "opponent" msgstr "opposant⋅e" #: participation/admin.py:65 participation/models.py:465 -#: participation/models.py:643 +#: participation/models.py:661 msgid "reporter" msgstr "rapporteur⋅e" -#: participation/admin.py:120 participation/models.py:597 +#: participation/admin.py:120 participation/models.py:615 msgid "problem" msgstr "numéro de problème" @@ -706,11 +706,15 @@ msgstr "position" msgid "defended solution" msgstr "solution défendue" -#: participation/models.py:470 +#: participation/models.py:475 +msgid "observer" +msgstr "observateur⋅rice" + +#: participation/models.py:480 msgid "penalties" msgstr "pénalités" -#: participation/models.py:472 +#: participation/models.py:482 msgid "" "Number of penalties for the defender. The defender will loose a 0.5 " "coefficient per penalty." @@ -718,120 +722,124 @@ msgstr "" "Nombre de pénalités pour læ défenseur⋅se. Læ défenseur⋅se perd un " "coefficient 0.5 sur sa présentation orale par pénalité." -#: participation/models.py:532 participation/models.py:535 -#: participation/models.py:538 +#: participation/models.py:547 participation/models.py:550 +#: participation/models.py:553 participation/models.py:556 #, python-brace-format msgid "Team {trigram} is not registered in the pool." msgstr "L'équipe {trigram} n'est pas inscrite dans la poule." -#: participation/models.py:543 +#: participation/models.py:561 #, python-brace-format msgid "Passage of {defender} for problem {problem}" msgstr "Passage de {defender} pour le problème {problem}" -#: participation/models.py:547 participation/models.py:556 -#: participation/models.py:637 participation/models.py:679 +#: participation/models.py:565 participation/models.py:574 +#: participation/models.py:655 participation/models.py:697 msgid "passage" msgstr "passage" -#: participation/models.py:548 +#: participation/models.py:566 msgid "passages" msgstr "passages" -#: participation/models.py:567 +#: participation/models.py:585 msgid "difference" msgstr "différence" -#: participation/models.py:568 +#: participation/models.py:586 msgid "Score to add/remove on the final score" msgstr "Score à ajouter/retrancher au score final" -#: participation/models.py:575 +#: participation/models.py:593 msgid "tweak" msgstr "harmonisation" -#: participation/models.py:576 +#: participation/models.py:594 msgid "tweaks" msgstr "harmonisations" -#: participation/models.py:604 +#: participation/models.py:622 msgid "solution for the final tournament" msgstr "solution pour la finale" -#: participation/models.py:609 participation/models.py:648 +#: participation/models.py:627 participation/models.py:666 msgid "file" msgstr "fichier" -#: participation/models.py:615 +#: participation/models.py:633 #, python-brace-format msgid "Solution of team {team} for problem {problem}" msgstr "Solution de l'équipe {team} pour le problème {problem}" -#: participation/models.py:617 +#: participation/models.py:635 msgid "for final" msgstr "pour la finale" -#: participation/models.py:620 +#: participation/models.py:638 msgid "solution" msgstr "solution" -#: participation/models.py:621 +#: participation/models.py:639 msgid "solutions" msgstr "solutions" -#: participation/models.py:654 +#: participation/models.py:672 #, python-brace-format msgid "Synthesis of {team} as {type} for problem {problem} of {defender}" msgstr "" "Note de synthèse de l'équipe {team} en tant que {type} pour le problème " "{problem} de {defender}" -#: participation/models.py:662 +#: participation/models.py:680 msgid "synthesis" msgstr "note de synthèse" -#: participation/models.py:663 +#: participation/models.py:681 msgid "syntheses" msgstr "notes de synthèse" -#: participation/models.py:672 +#: participation/models.py:690 msgid "jury" msgstr "jury" -#: participation/models.py:684 +#: participation/models.py:702 msgid "defender writing note" msgstr "note d'écrit de læ défenseur⋅se" -#: participation/models.py:690 +#: participation/models.py:708 msgid "defender oral note" msgstr "note d'oral de læ défenseur⋅se" -#: participation/models.py:696 +#: participation/models.py:714 msgid "opponent writing note" msgstr "note d'écrit de l'opposant⋅e" -#: participation/models.py:702 +#: participation/models.py:720 msgid "opponent oral note" msgstr "note d'oral de l'opposant⋅e" -#: participation/models.py:708 +#: participation/models.py:726 msgid "reporter writing note" msgstr "note d'écrit de læ rapporteur⋅e" -#: participation/models.py:714 +#: participation/models.py:732 msgid "reporter oral note" msgstr "note d'oral de læ rapporteur⋅e" -#: participation/models.py:732 +#: participation/models.py:738 +msgid "observer note" +msgstr "note de l'observateur⋅rice" + +#: participation/models.py:757 #, python-brace-format msgid "Notes of {jury} for {passage}" msgstr "Notes de {jury} pour le {passage}" -#: participation/models.py:739 +#: participation/models.py:764 msgid "note" msgstr "note" -#: participation/models.py:740 +#: participation/models.py:765 msgid "notes" msgstr "notes" @@ -911,9 +919,9 @@ msgid "Join" msgstr "Rejoindre" #: participation/templates/participation/note_form.html:11 -#: participation/templates/participation/passage_detail.html:49 -#: participation/templates/participation/passage_detail.html:105 -#: participation/templates/participation/passage_detail.html:111 +#: participation/templates/participation/passage_detail.html:54 +#: participation/templates/participation/passage_detail.html:120 +#: participation/templates/participation/passage_detail.html:126 #: participation/templates/participation/pool_add_jurys.html:35 #: participation/templates/participation/pool_detail.html:88 #: participation/templates/participation/pool_detail.html:106 @@ -980,7 +988,7 @@ msgid "Upload solution" msgstr "Envoyer une solution" #: participation/templates/participation/participation_detail.html:59 -#: participation/templates/participation/passage_detail.html:117 +#: participation/templates/participation/passage_detail.html:132 #: participation/templates/participation/pool_detail.html:116 #: participation/templates/participation/team_detail.html:185 #: participation/templates/participation/upload_motivation_letter.html:13 @@ -1019,73 +1027,85 @@ msgstr "Opposant⋅e :" msgid "Reporter:" msgstr "Rapporteur⋅e :" -#: participation/templates/participation/passage_detail.html:28 +#: participation/templates/participation/passage_detail.html:29 +msgid "Observer:" +msgstr "Observateur⋅rice :" + +#: participation/templates/participation/passage_detail.html:33 msgid "Defended solution:" msgstr "Solution défendue" -#: participation/templates/participation/passage_detail.html:31 +#: participation/templates/participation/passage_detail.html:36 msgid "Defender penalties count:" msgstr "Nombre de pénalités :" -#: participation/templates/participation/passage_detail.html:34 +#: participation/templates/participation/passage_detail.html:39 msgid "Syntheses:" msgstr "Notes de synthèse :" -#: participation/templates/participation/passage_detail.html:39 +#: participation/templates/participation/passage_detail.html:44 msgid "No synthesis was uploaded yet." msgstr "Aucune note de synthèse n'a encore été envoyée." -#: participation/templates/participation/passage_detail.html:47 -#: participation/templates/participation/passage_detail.html:110 +#: participation/templates/participation/passage_detail.html:52 +#: participation/templates/participation/passage_detail.html:125 msgid "Update notes" msgstr "Modifier les notes" -#: participation/templates/participation/passage_detail.html:53 -#: participation/templates/participation/passage_detail.html:116 +#: participation/templates/participation/passage_detail.html:58 +#: participation/templates/participation/passage_detail.html:131 msgid "Upload synthesis" msgstr "Envoyer une note de synthèse" -#: participation/templates/participation/passage_detail.html:61 +#: participation/templates/participation/passage_detail.html:66 msgid "Notes detail" msgstr "Détails des notes" -#: participation/templates/participation/passage_detail.html:68 +#: participation/templates/participation/passage_detail.html:73 msgid "Average points for the defender writing:" msgstr "Moyenne de l'écrit de læ défenseur⋅se :" -#: participation/templates/participation/passage_detail.html:71 +#: participation/templates/participation/passage_detail.html:76 msgid "Average points for the defender oral:" msgstr "Moyenne de l'oral de læ défenseur⋅se :" -#: participation/templates/participation/passage_detail.html:74 +#: participation/templates/participation/passage_detail.html:79 msgid "Average points for the opponent writing:" msgstr "Moyenne de l'écrit de l'opposant⋅e :" -#: participation/templates/participation/passage_detail.html:77 +#: participation/templates/participation/passage_detail.html:82 msgid "Average points for the opponent oral:" msgstr "Moyenne de l'oral de l'opposant⋅e :" -#: participation/templates/participation/passage_detail.html:80 +#: participation/templates/participation/passage_detail.html:85 msgid "Average points for the reporter writing:" msgstr "Moyenne de l'écrit de læ rapporteur⋅e :" -#: participation/templates/participation/passage_detail.html:83 +#: participation/templates/participation/passage_detail.html:88 msgid "Average points for the reporter oral:" msgstr "Moyenne de l'oral de læ rapporteur⋅e :" -#: participation/templates/participation/passage_detail.html:90 +#: participation/templates/participation/passage_detail.html:92 +msgid "Average points for the observer oral:" +msgstr "Moyenne de l'oral de l'observateur⋅rice :" + +#: participation/templates/participation/passage_detail.html:100 msgid "Defender points:" msgstr "Points de læ défenseur⋅se :" -#: participation/templates/participation/passage_detail.html:93 +#: participation/templates/participation/passage_detail.html:103 msgid "Opponent points:" msgstr "Points de l'opposant⋅e :" -#: participation/templates/participation/passage_detail.html:96 +#: participation/templates/participation/passage_detail.html:106 msgid "Reporter points:" msgstr "Points de læ rapporteur⋅e :" -#: participation/templates/participation/passage_detail.html:104 +#: participation/templates/participation/passage_detail.html:110 +msgid "Observer points:" +msgstr "Points de l'observateur⋅rice :" + +#: participation/templates/participation/passage_detail.html:119 #: participation/templates/participation/passage_form.html:11 msgid "Update passage" msgstr "Modifier le passage" @@ -1546,33 +1566,33 @@ msgstr "L'équipe n'est pas encore validée." msgid "Participation of team {trigram}" msgstr "Participation de l'équipe {trigram}" -#: participation/views.py:641 +#: participation/views.py:643 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:732 +#: participation/views.py:734 #, python-brace-format msgid "Jurys of {pool}" msgstr "Juré⋅es de la {pool}" -#: participation/views.py:759 +#: participation/views.py:761 msgid "New TFJM² jury account" msgstr "Nouveau compte de juré⋅e pour le TFJM²" -#: participation/views.py:772 +#: participation/views.py:774 #, python-brace-format msgid "The jury {name} has been successfully added!" msgstr "Læ juré⋅e {name} a été ajouté⋅e avec succès !" -#: participation/views.py:808 +#: participation/views.py:810 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:816 +#: participation/views.py:818 msgid "Notes were successfully uploaded." msgstr "Les notes ont bien été envoyées." -#: participation/views.py:974 +#: participation/views.py:979 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." diff --git a/participation/forms.py b/participation/forms.py index d1f30c3..7f5e290 100644 --- a/participation/forms.py +++ b/participation/forms.py @@ -323,7 +323,7 @@ class PassageForm(forms.ModelForm): class Meta: model = Passage - fields = ('position', 'solution_number', 'defender', 'opponent', 'reporter', 'defender_penalties',) + fields = ('position', 'solution_number', 'defender', 'opponent', 'reporter', 'observer', 'defender_penalties',) class SynthesisForm(forms.ModelForm): @@ -350,4 +350,4 @@ class NoteForm(forms.ModelForm): class Meta: model = Note fields = ('defender_writing', 'defender_oral', 'opponent_writing', - 'opponent_oral', 'reporter_writing', 'reporter_oral', ) + 'opponent_oral', 'reporter_writing', 'reporter_oral', 'observer_oral', ) diff --git a/participation/migrations/0007_note_observer_oral_passage_observer.py b/participation/migrations/0007_note_observer_oral_passage_observer.py new file mode 100644 index 0000000..88be734 --- /dev/null +++ b/participation/migrations/0007_note_observer_oral_passage_observer.py @@ -0,0 +1,45 @@ +# Generated by Django 4.2 on 2023-04-07 10:07 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("participation", "0006_alter_passage_options_passage_position_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="note", + name="observer_oral", + field=models.SmallIntegerField( + choices=[ + (-4, -4), + (-3, -3), + (-2, -2), + (-1, -1), + (0, 0), + (1, 1), + (2, 2), + (3, 3), + (4, 4), + ], + default=0, + verbose_name="observer note", + ), + ), + migrations.AddField( + model_name="passage", + name="observer", + field=models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="+", + to="participation.participation", + verbose_name="observer", + ), + ), + ] diff --git a/participation/models.py b/participation/models.py index 00cd7f7..41113ef 100644 --- a/participation/models.py +++ b/participation/models.py @@ -466,6 +466,16 @@ class Passage(models.Model): related_name="+", ) + observer = models.ForeignKey( + Participation, + on_delete=models.PROTECT, + null=True, + blank=True, + default=None, + verbose_name=_("observer"), + related_name="+", + ) + defender_penalties = models.PositiveSmallIntegerField( verbose_name=_("penalties"), default=0, @@ -520,9 +530,14 @@ class Passage(models.Model): def average_reporter(self) -> float: return self.average_reporter_writing + self.average_reporter_oral + @property + def average_observer(self) -> float: + return self.avg(note.observer_oral for note in self.notes.all()) + def average(self, participation): return self.average_defender if participation == self.defender else self.average_opponent \ - if participation == self.opponent else self.average_reporter if participation == self.reporter else 0 + if participation == self.opponent else self.average_reporter if participation == self.reporter \ + else self.average_observer if participation == self.observer else 0 def get_absolute_url(self): return reverse_lazy("participation:passage_detail", args=(self.pk,)) @@ -537,6 +552,9 @@ class Passage(models.Model): if self.reporter not in self.pool.participations.all(): raise ValidationError(_("Team {trigram} is not registered in the pool.") .format(trigram=self.reporter.team.trigram)) + if self.observer and self.observer not in self.pool.participations.all(): + raise ValidationError(_("Team {trigram} is not registered in the pool.") + .format(trigram=self.observer.team.trigram)) return super().clean() def __str__(self): @@ -716,14 +734,21 @@ class Note(models.Model): default=0, ) + observer_oral = models.SmallIntegerField( + verbose_name=_("observer note"), + choices=zip(range(-4, 5), range(-4, 5)), + default=0, + ) + def set_all(self, defender_writing: int, defender_oral: int, opponent_writing: int, opponent_oral: int, - reporter_writing: int, reporter_oral: int): + reporter_writing: int, reporter_oral: int, observer_oral: int = 0): self.defender_writing = defender_writing self.defender_oral = defender_oral self.opponent_writing = opponent_writing self.opponent_oral = opponent_oral self.reporter_writing = reporter_writing self.reporter_oral = reporter_oral + self.observer_oral = observer_oral def get_absolute_url(self): return reverse_lazy("participation:passage_detail", args=(self.passage.pk,)) @@ -733,7 +758,7 @@ class Note(models.Model): def __bool__(self): return any((self.defender_writing, self.defender_oral, self.opponent_writing, self.opponent_oral, - self.reporter_writing, self.reporter_oral)) + self.reporter_writing, self.reporter_oral, self.observer_oral)) class Meta: verbose_name = _("note") diff --git a/participation/tables.py b/participation/tables.py index 29d82e4..ad8a27d 100644 --- a/participation/tables.py +++ b/participation/tables.py @@ -141,4 +141,4 @@ class NoteTable(tables.Table): } model = Note fields = ('jury', 'defender_writing', 'defender_oral', 'opponent_writing', 'opponent_oral', - 'reporter_writing', 'reporter_oral',) + 'reporter_writing', 'reporter_oral', 'observer_oral',) diff --git a/participation/templates/participation/passage_detail.html b/participation/templates/participation/passage_detail.html index ae3af24..fe8b77f 100644 --- a/participation/templates/participation/passage_detail.html +++ b/participation/templates/participation/passage_detail.html @@ -25,6 +25,11 @@
{% trans "Reporter:" %}
{{ passage.reporter.team }}
+ {% if passage.observer %} +
{% trans "Observer:" %}
+
{{ passage.observer.team }}
+ {% endif %} +
{% trans "Defended solution:" %}
{{ passage.defended_solution }}
@@ -82,6 +87,11 @@
{% trans "Average points for the reporter oral:" %}
{{ passage.average_reporter_oral|floatformat }}/10
+ + {% if passage.observer %} +
{% trans "Average points for the observer oral:" %}
+
{{ passage.average_observer|floatformat }}/4
+ {% endif %}
@@ -95,6 +105,11 @@
{% trans "Reporter points:" %}
{{ passage.average_reporter|floatformat }}/19
+ + {% if passage.observer %} +
{% trans "Observer points:" %}
+
{{ passage.average_observer|floatformat }}/4
+ {% endif %} diff --git a/participation/templates/participation/tex/finale.tex b/participation/templates/participation/tex/finale.tex index cb058fe..a881c62 100644 --- a/participation/templates/participation/tex/finale.tex +++ b/participation/templates/participation/tex/finale.tex @@ -62,7 +62,7 @@ Tour {{ pool.round }} \;-- Poule {{ pool.get_letter_display }}{{ page }} \;-- {% & \phantom{asd asd} \phantom{asd asd} \centering \normalsize$0\leq x\leq 10$ {% endfor %} & \hline {% if passages.count == 4 %} -\multirow{4}{35mm}{\Large Intervention exceptionnelle}& \multicolumn{2}{c|}{\Large {{ passages.last.defender.team.trigram }}}{% for passage in passages.all %}{% if forloop.counter < 4 %} & \multicolumn{2}{c|}{\Large {{ passage.defender.team.trigram }}}{% endif %}{% endfor %} \\ \cline{2-{{ passages.count|add:passages.count|add:1 }}} +\multirow{4}{35mm}{\Large Intervention exceptionnelle}{% for passage in passages.all %} & \multicolumn{2}{c|}{\Large {{ passage.observer.team.trigram }}}{% endfor %} \\ \cline{2-{{ passages.count|add:passages.count|add:1 }}} & \multicolumn{2}{c|}{\phantom{asd asd} \phantom{asd asd}} & \multicolumn{2}{c|}{\phantom{asd asd} \phantom{asd asd}} & \multicolumn{2}{c|}{\phantom{asd asd} \phantom{asd asd}} diff --git a/participation/views.py b/participation/views.py index 2cf7099..1fda3b2 100644 --- a/participation/views.py +++ b/participation/views.py @@ -920,6 +920,9 @@ class PassageDetailView(LoginRequiredMixin, DetailView): context["notes"] = NoteTable([note for note in self.object.notes.all() if note]) elif self.request.user.registration.is_admin: context["notes"] = NoteTable([note for note in self.object.notes.all() if note]) + if 'notes' in context and not self.object.observer: + # Only display the observer column for 4-teams pools + context['notes']._sequence.pop() return context @@ -1003,3 +1006,10 @@ class NoteUpdateView(VolunteerMixin, UpdateView): return super().dispatch(request, *args, **kwargs) return self.handle_no_permission() + + def get_form(self, form_class=None): + form = super().get_form(form_class) + if not self.object.passage.observer: + # Set the note of the observer only for 4-teams pools + del form.fields['observer_oral'] + return form