mirror of
https://gitlab.com/animath/si/plateforme.git
synced 2024-12-25 07:02:22 +00:00
Remove observer status
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
parent
5bfcaab831
commit
338a19ec32
@ -396,10 +396,6 @@ class Pool(models.Model):
|
|||||||
reporter=tds[line[2]].participation,
|
reporter=tds[line[2]].participation,
|
||||||
defender_penalties=tds[line[0]].penalty_int,
|
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()
|
|
||||||
|
|
||||||
# Update Google Sheets
|
# Update Google Sheets
|
||||||
if os.getenv('GOOGLE_PRIVATE_KEY_ID', None):
|
if os.getenv('GOOGLE_PRIVATE_KEY_ID', None):
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -51,7 +51,7 @@ class PassageInline(admin.TabularInline):
|
|||||||
model = Passage
|
model = Passage
|
||||||
extra = 0
|
extra = 0
|
||||||
ordering = ('position',)
|
ordering = ('position',)
|
||||||
autocomplete_fields = ('defender', 'opponent', 'reporter', 'observer',)
|
autocomplete_fields = ('defender', 'opponent', 'reporter',)
|
||||||
show_change_link = True
|
show_change_link = True
|
||||||
|
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ class PassageAdmin(admin.ModelAdmin):
|
|||||||
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', 'defender', 'opponent', 'reporter', 'observer',)
|
autocomplete_fields = ('pool', 'defender', 'opponent', 'reporter',)
|
||||||
inlines = (NoteInline,)
|
inlines = (NoteInline,)
|
||||||
|
|
||||||
@admin.display(description=_("defender"), ordering='defender__team__trigram')
|
@admin.display(description=_("defender"), ordering='defender__team__trigram')
|
||||||
|
@ -336,7 +336,7 @@ class PassageForm(forms.ModelForm):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Passage
|
model = Passage
|
||||||
fields = ('position', 'solution_number', 'defender', 'opponent', 'reporter', 'observer', 'defender_penalties',)
|
fields = ('position', 'solution_number', 'defender', 'opponent', 'reporter', 'defender_penalties',)
|
||||||
|
|
||||||
|
|
||||||
class SynthesisForm(forms.ModelForm):
|
class SynthesisForm(forms.ModelForm):
|
||||||
@ -367,4 +367,4 @@ class NoteForm(forms.ModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Note
|
model = Note
|
||||||
fields = ('defender_writing', 'defender_oral', 'opponent_writing',
|
fields = ('defender_writing', 'defender_oral', 'opponent_writing',
|
||||||
'opponent_oral', 'reporter_writing', 'reporter_oral', 'observer_oral', )
|
'opponent_oral', 'reporter_writing', 'reporter_oral', )
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
# Generated by Django 5.0.3 on 2024-04-16 21:59
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
(
|
||||||
|
"participation",
|
||||||
|
"0010_tournament_notes_sheet_id_alter_note_defender_oral_and_more",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="note",
|
||||||
|
name="observer_oral",
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="passage",
|
||||||
|
name="observer",
|
||||||
|
),
|
||||||
|
]
|
@ -979,7 +979,7 @@ class Pool(models.Model):
|
|||||||
spreadsheet.del_worksheet(spreadsheet.worksheet("Sheet1"))
|
spreadsheet.del_worksheet(spreadsheet.worksheet("Sheet1"))
|
||||||
|
|
||||||
pool_size = self.participations.count()
|
pool_size = self.participations.count()
|
||||||
passage_width = 7 if pool_size == 4 else 6
|
passage_width = 6
|
||||||
passages = self.passages.all()
|
passages = self.passages.all()
|
||||||
|
|
||||||
header = [
|
header = [
|
||||||
@ -988,10 +988,8 @@ class Pool(models.Model):
|
|||||||
sum(([f"Défenseur⋅se ({passage.defender.team.trigram})", "",
|
sum(([f"Défenseur⋅se ({passage.defender.team.trigram})", "",
|
||||||
f"Opposant⋅e ({passage.opponent.team.trigram})", "",
|
f"Opposant⋅e ({passage.opponent.team.trigram})", "",
|
||||||
f"Rapporteur⋅rice ({passage.reporter.team.trigram})", ""]
|
f"Rapporteur⋅rice ({passage.reporter.team.trigram})", ""]
|
||||||
+ ([f"Observateur⋅rice ({passage.observer.team.trigram})"] if pool_size == 4 else [])
|
|
||||||
for passage in passages), start=["Rôle", ""]),
|
for passage in passages), start=["Rôle", ""]),
|
||||||
sum((["Écrit (/20)", "Oral (/20)", "Écrit (/10)", "Oral (/10)", "Écrit (/10)", "Oral (/10)"]
|
sum((["Écrit (/20)", "Oral (/20)", "Écrit (/10)", "Oral (/10)", "Écrit (/10)", "Oral (/10)"]
|
||||||
+ (["Oral (± 4)"] if pool_size == 4 else [])
|
|
||||||
for _passage in passages), start=["Juré⋅e", ""]),
|
for _passage in passages), start=["Juré⋅e", ""]),
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1002,8 +1000,6 @@ class Pool(models.Model):
|
|||||||
note = passage.notes.filter(jury=jury).first()
|
note = passage.notes.filter(jury=jury).first()
|
||||||
line.extend([note.defender_writing, note.defender_oral, note.opponent_writing, note.opponent_oral,
|
line.extend([note.defender_writing, note.defender_oral, note.opponent_writing, note.opponent_oral,
|
||||||
note.reporter_writing, note.reporter_oral])
|
note.reporter_writing, note.reporter_oral])
|
||||||
if pool_size == 4:
|
|
||||||
line.append(note.observer_oral)
|
|
||||||
notes.append(line)
|
notes.append(line)
|
||||||
notes.append([]) # Add empty line to ensure pretty design
|
notes.append([]) # Add empty line to ensure pretty design
|
||||||
|
|
||||||
@ -1016,8 +1012,8 @@ class Pool(models.Model):
|
|||||||
return getcol((number - 1) // 26) + chr(65 + (number - 1) % 26)
|
return getcol((number - 1) // 26) + chr(65 + (number - 1) % 26)
|
||||||
|
|
||||||
average = ["Moyenne", ""]
|
average = ["Moyenne", ""]
|
||||||
coeffs = sum(([1, 1.6 - 0.4 * passage.defender_penalties, 0.9, 2, 0.9, 1]
|
coeffs = sum(([1, 1.6 - 0.4 * passage.defender_penalties, 0.9, 2, 0.9, 1] for passage in passages),
|
||||||
+ ([1] if pool_size == 4 else []) for passage in passages), start=["Coefficient", ""])
|
start=["Coefficient", ""])
|
||||||
subtotal = ["Sous-total", ""]
|
subtotal = ["Sous-total", ""]
|
||||||
footer = [average, coeffs, subtotal, 32 * [""]]
|
footer = [average, coeffs, subtotal, 32 * [""]]
|
||||||
|
|
||||||
@ -1045,10 +1041,6 @@ class Pool(models.Model):
|
|||||||
subtotal.extend([f"={rep_w_col}{max_row + 1} * {rep_w_col}{max_row + 2}"
|
subtotal.extend([f"={rep_w_col}{max_row + 1} * {rep_w_col}{max_row + 2}"
|
||||||
f" + {rep_o_col}{max_row + 1} * {rep_o_col}{max_row + 2}", ""])
|
f" + {rep_o_col}{max_row + 1} * {rep_o_col}{max_row + 2}", ""])
|
||||||
|
|
||||||
if pool_size == 4:
|
|
||||||
obs_col = getcol(min_column + passage_width * i + 6)
|
|
||||||
subtotal.append(f"={obs_col}{max_row + 1} * {obs_col}{max_row + 2}")
|
|
||||||
|
|
||||||
ranking = [
|
ranking = [
|
||||||
["Équipe", "", "Problème", "Total", "Rang"],
|
["Équipe", "", "Problème", "Total", "Rang"],
|
||||||
]
|
]
|
||||||
@ -1062,10 +1054,10 @@ class Pool(models.Model):
|
|||||||
]
|
]
|
||||||
case 4:
|
case 4:
|
||||||
passage_matrix = [
|
passage_matrix = [
|
||||||
[0, 3, 2, 1],
|
[0, 3, 2],
|
||||||
[1, 0, 3, 2],
|
[1, 0, 3],
|
||||||
[2, 1, 0, 3],
|
[2, 1, 0],
|
||||||
[3, 2, 1, 0],
|
[3, 2, 1],
|
||||||
]
|
]
|
||||||
case 5:
|
case 5:
|
||||||
passage_matrix = [
|
passage_matrix = [
|
||||||
@ -1082,9 +1074,6 @@ class Pool(models.Model):
|
|||||||
formula += getcol(min_column + passage_line[0] * passage_width) + str(max_row + 3) # Defender
|
formula += getcol(min_column + passage_line[0] * passage_width) + str(max_row + 3) # Defender
|
||||||
formula += " + " + getcol(min_column + passage_line[1] * passage_width + 2) + str(max_row + 3) # Opponent
|
formula += " + " + getcol(min_column + passage_line[1] * passage_width + 2) + str(max_row + 3) # Opponent
|
||||||
formula += " + " + getcol(min_column + passage_line[2] * passage_width + 4) + str(max_row + 3) # Reporter
|
formula += " + " + getcol(min_column + passage_line[2] * passage_width + 4) + str(max_row + 3) # Reporter
|
||||||
if pool_size == 4:
|
|
||||||
# Observer
|
|
||||||
formula += " + " + getcol(min_column + passage_line[3] * passage_width + 6) + str(max_row + 3)
|
|
||||||
ranking.append([f"{participation.team.name} ({participation.team.trigram})", "",
|
ranking.append([f"{participation.team.name} ({participation.team.trigram})", "",
|
||||||
f"=${getcol(3 + (passage.position - 1) * passage_width)}$1", formula,
|
f"=${getcol(3 + (passage.position - 1) * passage_width)}$1", formula,
|
||||||
f"=RANG(D{max_row + 5 + passage.position}; "
|
f"=RANG(D{max_row + 5 + passage.position}; "
|
||||||
@ -1173,8 +1162,6 @@ class Pool(models.Model):
|
|||||||
for passage in passages:
|
for passage in passages:
|
||||||
column_widths.append((f"{getcol(3 + passage_width * (passage.position - 1))}"
|
column_widths.append((f"{getcol(3 + passage_width * (passage.position - 1))}"
|
||||||
f":{getcol(8 + passage_width * (passage.position - 1))}", 75))
|
f":{getcol(8 + passage_width * (passage.position - 1))}", 75))
|
||||||
if pool_size == 4:
|
|
||||||
column_widths.append((getcol(9 + passage_width * (passage.position - 1)), 120))
|
|
||||||
for column, width in column_widths:
|
for column, width in column_widths:
|
||||||
grid_range = a1_range_to_grid_range(column, worksheet.id)
|
grid_range = a1_range_to_grid_range(column, worksheet.id)
|
||||||
format_requests.append({
|
format_requests.append({
|
||||||
@ -1260,8 +1247,8 @@ class Pool(models.Model):
|
|||||||
for i in range(pool_size):
|
for i in range(pool_size):
|
||||||
for j in range(passage_width):
|
for j in range(passage_width):
|
||||||
column = getcol(min_column + i * passage_width + j)
|
column = getcol(min_column + i * passage_width + j)
|
||||||
min_note = 0 if j < 6 else -4
|
min_note = 0
|
||||||
max_note = 20 if j < 2 else 10 if j < 6 else 4
|
max_note = 20 if j < 2 else 10
|
||||||
format_requests.append({
|
format_requests.append({
|
||||||
"setDataValidation": {
|
"setDataValidation": {
|
||||||
"range": a1_range_to_grid_range(f"{column}{min_row - 1}:{column}{max_row}", worksheet.id),
|
"range": a1_range_to_grid_range(f"{column}{min_row - 1}:{column}{max_row}", worksheet.id),
|
||||||
@ -1350,7 +1337,7 @@ class Pool(models.Model):
|
|||||||
if not data or not data[0]:
|
if not data or not data[0]:
|
||||||
return
|
return
|
||||||
|
|
||||||
passage_width = 7 if self.participations.count() == 4 else 6
|
passage_width = 6
|
||||||
for line in data:
|
for line in data:
|
||||||
jury_name = line[0]
|
jury_name = line[0]
|
||||||
jury_id = line[1]
|
jury_id = line[1]
|
||||||
@ -1422,16 +1409,6 @@ class Passage(models.Model):
|
|||||||
related_name="+",
|
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(
|
defender_penalties = models.PositiveSmallIntegerField(
|
||||||
verbose_name=_("penalties"),
|
verbose_name=_("penalties"),
|
||||||
default=0,
|
default=0,
|
||||||
@ -1486,10 +1463,6 @@ class Passage(models.Model):
|
|||||||
def average_reporter(self) -> float:
|
def average_reporter(self) -> float:
|
||||||
return 0.9 * self.average_reporter_writing + self.average_reporter_oral
|
return 0.9 * 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())
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def averages(self):
|
def averages(self):
|
||||||
yield self.average_defender_writing
|
yield self.average_defender_writing
|
||||||
@ -1498,13 +1471,10 @@ class Passage(models.Model):
|
|||||||
yield self.average_opponent_oral
|
yield self.average_opponent_oral
|
||||||
yield self.average_reporter_writing
|
yield self.average_reporter_writing
|
||||||
yield self.average_reporter_oral
|
yield self.average_reporter_oral
|
||||||
if self.observer:
|
|
||||||
yield self.average_observer
|
|
||||||
|
|
||||||
def average(self, participation):
|
def average(self, participation):
|
||||||
return self.average_defender if participation == self.defender else self.average_opponent \
|
return self.average_defender if participation == self.defender else self.average_opponent \
|
||||||
if participation == self.opponent else self.average_reporter if participation == self.reporter \
|
if participation == self.opponent else self.average_reporter if participation == self.reporter else 0
|
||||||
else self.average_observer if participation == self.observer else 0
|
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse_lazy("participation:passage_detail", args=(self.pk,))
|
return reverse_lazy("participation:passage_detail", args=(self.pk,))
|
||||||
@ -1519,9 +1489,6 @@ class Passage(models.Model):
|
|||||||
if self.reporter not in self.pool.participations.all():
|
if self.reporter not in self.pool.participations.all():
|
||||||
raise ValidationError(_("Team {trigram} is not registered in the pool.")
|
raise ValidationError(_("Team {trigram} is not registered in the pool.")
|
||||||
.format(trigram=self.reporter.team.trigram))
|
.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()
|
return super().clean()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@ -1705,12 +1672,6 @@ class Note(models.Model):
|
|||||||
default=0,
|
default=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
observer_oral = models.SmallIntegerField(
|
|
||||||
verbose_name=_("observer note"),
|
|
||||||
choices=zip(range(-4, 5), range(-4, 5)),
|
|
||||||
default=0,
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_all(self):
|
def get_all(self):
|
||||||
yield self.defender_writing
|
yield self.defender_writing
|
||||||
yield self.defender_oral
|
yield self.defender_oral
|
||||||
@ -1718,18 +1679,15 @@ class Note(models.Model):
|
|||||||
yield self.opponent_oral
|
yield self.opponent_oral
|
||||||
yield self.reporter_writing
|
yield self.reporter_writing
|
||||||
yield self.reporter_oral
|
yield self.reporter_oral
|
||||||
if self.passage.observer:
|
|
||||||
yield self.observer_oral
|
|
||||||
|
|
||||||
def set_all(self, defender_writing: int, defender_oral: int, opponent_writing: int, opponent_oral: int,
|
def set_all(self, defender_writing: int, defender_oral: int, opponent_writing: int, opponent_oral: int,
|
||||||
reporter_writing: int, reporter_oral: int, observer_oral: int = 0):
|
reporter_writing: int, reporter_oral: int):
|
||||||
self.defender_writing = defender_writing
|
self.defender_writing = defender_writing
|
||||||
self.defender_oral = defender_oral
|
self.defender_oral = defender_oral
|
||||||
self.opponent_writing = opponent_writing
|
self.opponent_writing = opponent_writing
|
||||||
self.opponent_oral = opponent_oral
|
self.opponent_oral = opponent_oral
|
||||||
self.reporter_writing = reporter_writing
|
self.reporter_writing = reporter_writing
|
||||||
self.reporter_oral = reporter_oral
|
self.reporter_oral = reporter_oral
|
||||||
self.observer_oral = observer_oral
|
|
||||||
|
|
||||||
def update_spreadsheet(self):
|
def update_spreadsheet(self):
|
||||||
if not self.has_any_note():
|
if not self.has_any_note():
|
||||||
@ -1744,7 +1702,7 @@ class Note(models.Model):
|
|||||||
if not jury_id_cell:
|
if not jury_id_cell:
|
||||||
raise ValueError("The jury ID cell was not found in the spreadsheet.")
|
raise ValueError("The jury ID cell was not found in the spreadsheet.")
|
||||||
jury_row = jury_id_cell.row
|
jury_row = jury_id_cell.row
|
||||||
passage_width = 7 if passage.pool.participations.count() == 4 else 6
|
passage_width = 6
|
||||||
|
|
||||||
def getcol(number: int) -> str:
|
def getcol(number: int) -> str:
|
||||||
if number == 0:
|
if number == 0:
|
||||||
|
@ -155,4 +155,4 @@ class NoteTable(tables.Table):
|
|||||||
}
|
}
|
||||||
model = Note
|
model = Note
|
||||||
fields = ('jury', 'defender_writing', 'defender_oral', 'opponent_writing', 'opponent_oral',
|
fields = ('jury', 'defender_writing', 'defender_oral', 'opponent_writing', 'opponent_oral',
|
||||||
'reporter_writing', 'reporter_oral', 'observer_oral', 'update',)
|
'reporter_writing', 'reporter_oral', 'update',)
|
||||||
|
@ -34,11 +34,6 @@
|
|||||||
<dt class="col-sm-3">{% trans "Reporter:" %}</dt>
|
<dt class="col-sm-3">{% trans "Reporter:" %}</dt>
|
||||||
<dd class="col-sm-9"><a href="{{ passage.reporter.get_absolute_url }}">{{ passage.reporter.team }}</a></dd>
|
<dd class="col-sm-9"><a href="{{ passage.reporter.get_absolute_url }}">{{ passage.reporter.team }}</a></dd>
|
||||||
|
|
||||||
{% if passage.observer %}
|
|
||||||
<dt class="col-sm-3">{% trans "Observer:" %}</dt>
|
|
||||||
<dd class="col-sm-9"><a href="{{ passage.observer.get_absolute_url }}">{{ passage.observer.team }}</a></dd>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<dt class="col-sm-3">{% trans "Defended solution:" %}</dt>
|
<dt class="col-sm-3">{% trans "Defended solution:" %}</dt>
|
||||||
<dd class="col-sm-9"><a href="{{ passage.defended_solution.file.url }}">{{ passage.defended_solution }}</a></dd>
|
<dd class="col-sm-9"><a href="{{ passage.defended_solution.file.url }}">{{ passage.defended_solution }}</a></dd>
|
||||||
|
|
||||||
@ -113,14 +108,6 @@
|
|||||||
({{ passage.reporter.team.trigram }}) :
|
({{ passage.reporter.team.trigram }}) :
|
||||||
</dt>
|
</dt>
|
||||||
<dd class="col-sm-4">{{ passage.average_reporter_oral|floatformat }}/10</dd>
|
<dd class="col-sm-4">{{ passage.average_reporter_oral|floatformat }}/10</dd>
|
||||||
|
|
||||||
{% if passage.observer %}
|
|
||||||
<dt class="col-sm-8">
|
|
||||||
{% trans "Average points for the observer oral" %}
|
|
||||||
({{ passage.observer.team.trigram }}) :
|
|
||||||
</dt>
|
|
||||||
<dd class="col-sm-4">{{ passage.average_observer|floatformat }}/4</dd>
|
|
||||||
{% endif %}
|
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
@ -143,14 +130,6 @@
|
|||||||
({{ passage.reporter.team.trigram }}) :
|
({{ passage.reporter.team.trigram }}) :
|
||||||
</dt>
|
</dt>
|
||||||
<dd class="col-sm-4">{{ passage.average_reporter|floatformat }}/19</dd>
|
<dd class="col-sm-4">{{ passage.average_reporter|floatformat }}/19</dd>
|
||||||
|
|
||||||
{% if passage.observer %}
|
|
||||||
<dt class="col-sm-8">
|
|
||||||
{% trans "Observer points" %}
|
|
||||||
({{ passage.observer.team.trigram }}) :
|
|
||||||
</dt>
|
|
||||||
<dd class="col-sm-4">{{ passage.average_observer|floatformat }}/4</dd>
|
|
||||||
{% endif %}
|
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -73,18 +73,6 @@
|
|||||||
|
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
|
|
||||||
{% if passages.count == 4 %}
|
|
||||||
|
|
||||||
\vfill
|
|
||||||
|
|
||||||
%%%%%%% INTERVENTION EXCEPTIONNELLE
|
|
||||||
\begin{tabular}{|p{14.7cm}|c|p{2cm}|p{2cm}|p{2cm}|p{2cm}|}\hline
|
|
||||||
\multicolumn{2}{|l|}{L'{\bf Intervention exceptionnelle} \normalsize permet de signaler une erreur grave omise par tous.} {% for passage in passages.all %}& P.{{ forloop.counter }} - {{ passage.observer.team.trigram }} {% endfor %}\\ \hline \hline
|
|
||||||
%ORAL
|
|
||||||
Toute intervention exceptionnelle non pertinente est sanctionn\'ee par une note n\'egative, l'absence d'intervention re\c coit un z\'ero forfaitaire. \phantom{pour avoir oral en entier dans la} \phantom{colonne il} \phantom{faut blablater un peu}& [-4,4] {{ esp|safe }}\\ \hline
|
|
||||||
\end{tabular}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
\newpage
|
\newpage
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%OPPOSANT
|
%%%%%%%%%%%%%%%%%OPPOSANT
|
||||||
|
@ -61,22 +61,6 @@ Tour {{ pool.round }} \;-- Poule {{ pool.get_letter_display }}{{ page }} \;-- {%
|
|||||||
& \phantom{asd asd} \phantom{asd asd} \centering \normalsize$0\leq x\leq 10$
|
& \phantom{asd asd} \phantom{asd asd} \centering \normalsize$0\leq x\leq 10$
|
||||||
& \phantom{asd asd} \phantom{asd asd} \centering \normalsize$0\leq x\leq 10$
|
& \phantom{asd asd} \phantom{asd asd} \centering \normalsize$0\leq x\leq 10$
|
||||||
{% endfor %} & \hline
|
{% endfor %} & \hline
|
||||||
{% if passages.count == 4 %}
|
|
||||||
\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}}
|
|
||||||
& \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}}
|
|
||||||
& \multicolumn{2}{c|}{\phantom{asd asd} \phantom{asd asd}}
|
|
||||||
& \multicolumn{2}{c|}{\phantom{asd asd} \phantom{asd asd}}\\
|
|
||||||
& \multicolumn{2}{c|}{\centering \normalsize$-4\leq x\leq 4$}
|
|
||||||
& \multicolumn{2}{c|}{\centering \normalsize$-4\leq x\leq 4$}
|
|
||||||
& \multicolumn{2}{c|}{\centering \normalsize$-4\leq x\leq 4$}
|
|
||||||
& \multicolumn{2}{c|}{\centering \normalsize$-4\leq x\leq 4$} & \hline
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
|
|
||||||
\vspace{15mm}
|
\vspace{15mm}
|
||||||
|
@ -1245,8 +1245,7 @@ class PoolUploadNotesView(VolunteerMixin, FormView, DetailView):
|
|||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
|
|
||||||
for vr, notes in parsed_notes.items():
|
for vr, notes in parsed_notes.items():
|
||||||
# There is an observer note for 4-teams pools
|
notes_count = 6
|
||||||
notes_count = 7 if pool.passages.count() == 4 else 6
|
|
||||||
for i, passage in enumerate(pool.passages.all()):
|
for i, passage in enumerate(pool.passages.all()):
|
||||||
note = Note.objects.get_or_create(jury=vr, passage=passage)[0]
|
note = Note.objects.get_or_create(jury=vr, passage=passage)[0]
|
||||||
passage_notes = notes[notes_count * i:notes_count * (i + 1)]
|
passage_notes = notes[notes_count * i:notes_count * (i + 1)]
|
||||||
@ -1282,7 +1281,7 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
|||||||
|
|
||||||
def render_to_response(self, context, **response_kwargs): # noqa: C901
|
def render_to_response(self, context, **response_kwargs): # noqa: C901
|
||||||
pool_size = self.object.passages.count()
|
pool_size = self.object.passages.count()
|
||||||
passage_width = 7 if pool_size == 4 else 6
|
passage_width = 6
|
||||||
line_length = pool_size * passage_width
|
line_length = pool_size * passage_width
|
||||||
|
|
||||||
def getcol(number: int) -> str:
|
def getcol(number: int) -> str:
|
||||||
@ -1454,10 +1453,6 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
|||||||
col_style.addElement(TableColumnProperties(columnwidth="2.6cm", breakbefore="auto"))
|
col_style.addElement(TableColumnProperties(columnwidth="2.6cm", breakbefore="auto"))
|
||||||
doc.automaticstyles.addElement(col_style)
|
doc.automaticstyles.addElement(col_style)
|
||||||
|
|
||||||
obs_col_style = Style(name="co3", family="table-column")
|
|
||||||
obs_col_style.addElement(TableColumnProperties(columnwidth="5.2cm", breakbefore="auto"))
|
|
||||||
doc.automaticstyles.addElement(obs_col_style)
|
|
||||||
|
|
||||||
table = Table(name=f"Poule {self.object.get_letter_display()}{self.object.round}")
|
table = Table(name=f"Poule {self.object.get_letter_display()}{self.object.round}")
|
||||||
doc.spreadsheet.addElement(table)
|
doc.spreadsheet.addElement(table)
|
||||||
|
|
||||||
@ -1465,8 +1460,7 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
|||||||
table.addElement(TableColumn(stylename=jury_id_style))
|
table.addElement(TableColumn(stylename=jury_id_style))
|
||||||
|
|
||||||
for i in range(line_length):
|
for i in range(line_length):
|
||||||
table.addElement(TableColumn(
|
table.addElement(TableColumn(stylename=col_style))
|
||||||
stylename=obs_col_style if pool_size == 4 and i % passage_width == passage_width - 1 else col_style))
|
|
||||||
|
|
||||||
# Add line for the problems for different passages
|
# Add line for the problems for different passages
|
||||||
header_pb = TableRow()
|
header_pb = TableRow()
|
||||||
@ -1479,10 +1473,10 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
|||||||
for passage in self.object.passages.all():
|
for passage in self.object.passages.all():
|
||||||
tc = TableCell(valuetype="string", stylename=title_style_topleftright)
|
tc = TableCell(valuetype="string", stylename=title_style_topleftright)
|
||||||
tc.addElement(P(text=f"Problème {passage.solution_number}"))
|
tc.addElement(P(text=f"Problème {passage.solution_number}"))
|
||||||
tc.setAttribute('numbercolumnsspanned', "7" if pool_size == 4 else "6")
|
tc.setAttribute('numbercolumnsspanned', "6")
|
||||||
tc.setAttribute("formula", f"of:=[.B{8 + self.object.juries.count() + passage.position}]")
|
tc.setAttribute("formula", f"of:=[.B{8 + self.object.juries.count() + passage.position}]")
|
||||||
header_pb.addElement(tc)
|
header_pb.addElement(tc)
|
||||||
header_pb.addElement(CoveredTableCell(numbercolumnsrepeated=6 if pool_size == 4 else 5))
|
header_pb.addElement(CoveredTableCell(numbercolumnsrepeated=5))
|
||||||
|
|
||||||
# Add roles on the second line of the table
|
# Add roles on the second line of the table
|
||||||
header_role = TableRow()
|
header_role = TableRow()
|
||||||
@ -1506,17 +1500,12 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
|||||||
header_role.addElement(CoveredTableCell())
|
header_role.addElement(CoveredTableCell())
|
||||||
|
|
||||||
reporter_tc = TableCell(valuetype="string",
|
reporter_tc = TableCell(valuetype="string",
|
||||||
stylename=title_style_right if pool_size != 4 else title_style)
|
stylename=title_style_right)
|
||||||
reporter_tc.addElement(P(text="Rapporteur⋅rice"))
|
reporter_tc.addElement(P(text="Rapporteur⋅rice"))
|
||||||
reporter_tc.setAttribute('numbercolumnsspanned', "2")
|
reporter_tc.setAttribute('numbercolumnsspanned', "2")
|
||||||
header_role.addElement(reporter_tc)
|
header_role.addElement(reporter_tc)
|
||||||
header_role.addElement(CoveredTableCell())
|
header_role.addElement(CoveredTableCell())
|
||||||
|
|
||||||
if pool_size == 4:
|
|
||||||
observer_tc = TableCell(valuetype="string", stylename=title_style_right)
|
|
||||||
observer_tc.addElement(P(text="Intervention exceptionnelle"))
|
|
||||||
header_role.addElement(observer_tc)
|
|
||||||
|
|
||||||
# Add maximum notes on the third line
|
# Add maximum notes on the third line
|
||||||
header_notes = TableRow()
|
header_notes = TableRow()
|
||||||
table.addElement(header_notes)
|
table.addElement(header_notes)
|
||||||
@ -1547,17 +1536,10 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
|||||||
reporter_w_tc.addElement(P(text="Écrit (/10)"))
|
reporter_w_tc.addElement(P(text="Écrit (/10)"))
|
||||||
header_notes.addElement(reporter_w_tc)
|
header_notes.addElement(reporter_w_tc)
|
||||||
|
|
||||||
reporter_o_tc = TableCell(valuetype="string",
|
reporter_o_tc = TableCell(valuetype="string", stylename=title_style_botright)
|
||||||
stylename=title_style_botright if pool_size != 4 else title_style_bot)
|
|
||||||
reporter_o_tc.addElement(P(text="Oral (/10)"))
|
reporter_o_tc.addElement(P(text="Oral (/10)"))
|
||||||
header_notes.addElement(reporter_o_tc)
|
header_notes.addElement(reporter_o_tc)
|
||||||
|
|
||||||
if pool_size == 4:
|
|
||||||
observer_tc = TableCell(valuetype="string",
|
|
||||||
stylename=title_style_botright)
|
|
||||||
observer_tc.addElement(P(text="Oral (± 4)"))
|
|
||||||
header_notes.addElement(observer_tc)
|
|
||||||
|
|
||||||
# Add a notation line for each jury
|
# Add a notation line for each jury
|
||||||
for jury in self.object.juries.all():
|
for jury in self.object.juries.all():
|
||||||
jury_row = TableRow()
|
jury_row = TableRow()
|
||||||
@ -1631,16 +1613,10 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
|||||||
reporter_w_tc.addElement(P(text="1"))
|
reporter_w_tc.addElement(P(text="1"))
|
||||||
coeff_row.addElement(reporter_w_tc)
|
coeff_row.addElement(reporter_w_tc)
|
||||||
|
|
||||||
reporter_o_tc = TableCell(valuetype="float", value=1,
|
reporter_o_tc = TableCell(valuetype="float", value=1, stylename=style_right)
|
||||||
stylename=style_right if pool_size != 4 else style)
|
|
||||||
reporter_o_tc.addElement(P(text="1"))
|
reporter_o_tc.addElement(P(text="1"))
|
||||||
coeff_row.addElement(reporter_o_tc)
|
coeff_row.addElement(reporter_o_tc)
|
||||||
|
|
||||||
if pool_size == 4:
|
|
||||||
observer_tc = TableCell(valuetype="float", value=1, stylename=style_right)
|
|
||||||
observer_tc.addElement(P(text="1"))
|
|
||||||
coeff_row.addElement(observer_tc)
|
|
||||||
|
|
||||||
# Add the subtotal on the next line
|
# Add the subtotal on the next line
|
||||||
subtotal_row = TableRow()
|
subtotal_row = TableRow()
|
||||||
table.addElement(subtotal_row)
|
table.addElement(subtotal_row)
|
||||||
@ -1672,8 +1648,7 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
|||||||
|
|
||||||
rep_w_col = getcol(min_column + passage_width * i + 4)
|
rep_w_col = getcol(min_column + passage_width * i + 4)
|
||||||
rep_o_col = getcol(min_column + passage_width * i + 5)
|
rep_o_col = getcol(min_column + passage_width * i + 5)
|
||||||
reporter_tc = TableCell(valuetype="float", value=passage.average_reporter,
|
reporter_tc = TableCell(valuetype="float", value=passage.average_reporter, stylename=style_botright)
|
||||||
stylename=style_botright if pool_size != 4 else style_bot)
|
|
||||||
reporter_tc.addElement(P(text=str(passage.average_reporter)))
|
reporter_tc.addElement(P(text=str(passage.average_reporter)))
|
||||||
reporter_tc.setAttribute('numbercolumnsspanned', "2")
|
reporter_tc.setAttribute('numbercolumnsspanned', "2")
|
||||||
reporter_tc.setAttribute("formula", f"of:=[.{rep_w_col}{max_row + 1}] * [.{rep_w_col}{max_row + 2}]"
|
reporter_tc.setAttribute("formula", f"of:=[.{rep_w_col}{max_row + 1}] * [.{rep_w_col}{max_row + 2}]"
|
||||||
@ -1681,14 +1656,6 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
|||||||
subtotal_row.addElement(reporter_tc)
|
subtotal_row.addElement(reporter_tc)
|
||||||
subtotal_row.addElement(CoveredTableCell())
|
subtotal_row.addElement(CoveredTableCell())
|
||||||
|
|
||||||
if pool_size == 4:
|
|
||||||
obs_col = getcol(min_column + passage_width * i + 6)
|
|
||||||
observer_tc = TableCell(valuetype="float", value=passage.average_observer,
|
|
||||||
stylename=style_botright)
|
|
||||||
observer_tc.addElement(P(text=str(passage.average_observer)))
|
|
||||||
observer_tc.setAttribute("formula", f"of:=[.{obs_col}{max_row + 1}] * [.{obs_col}{max_row + 2}]")
|
|
||||||
subtotal_row.addElement(observer_tc)
|
|
||||||
|
|
||||||
table.addElement(TableRow())
|
table.addElement(TableRow())
|
||||||
|
|
||||||
# Compute the total scores in a new table
|
# Compute the total scores in a new table
|
||||||
@ -1710,7 +1677,6 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
|||||||
|
|
||||||
# For each line of the matrix P, the ith team is defender on the passage number Pi0,
|
# For each line of the matrix P, the ith team is defender on the passage number Pi0,
|
||||||
# opponent on the passage number Pi1, reporter on the passage number Pi2
|
# opponent on the passage number Pi1, reporter on the passage number Pi2
|
||||||
# and eventually observer on the passage number Pi3.
|
|
||||||
passage_matrix = []
|
passage_matrix = []
|
||||||
match pool_size:
|
match pool_size:
|
||||||
case 3:
|
case 3:
|
||||||
@ -1721,10 +1687,10 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
|||||||
]
|
]
|
||||||
case 4:
|
case 4:
|
||||||
passage_matrix = [
|
passage_matrix = [
|
||||||
[0, 3, 2, 1],
|
[0, 3, 2],
|
||||||
[1, 0, 3, 2],
|
[1, 0, 3],
|
||||||
[2, 1, 0, 3],
|
[2, 1, 0],
|
||||||
[3, 2, 1, 0],
|
[3, 2, 1],
|
||||||
]
|
]
|
||||||
case 5:
|
case 5:
|
||||||
passage_matrix = [
|
passage_matrix = [
|
||||||
@ -1759,9 +1725,6 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
|||||||
formula += getcol(min_column + passage_line[0] * passage_width) + str(max_row + 3) # Defender
|
formula += getcol(min_column + passage_line[0] * passage_width) + str(max_row + 3) # Defender
|
||||||
formula += " + " + getcol(min_column + passage_line[1] * passage_width + 2) + str(max_row + 3) # Opponent
|
formula += " + " + getcol(min_column + passage_line[1] * passage_width + 2) + str(max_row + 3) # Opponent
|
||||||
formula += " + " + getcol(min_column + passage_line[2] * passage_width + 4) + str(max_row + 3) # Reporter
|
formula += " + " + getcol(min_column + passage_line[2] * passage_width + 4) + str(max_row + 3) # Reporter
|
||||||
if pool_size == 4:
|
|
||||||
# Observer
|
|
||||||
formula += " + " + getcol(min_column + passage_line[3] * passage_width + 6) + str(max_row + 3)
|
|
||||||
score_tc.setAttribute("formula", formula)
|
score_tc.setAttribute("formula", formula)
|
||||||
team_row.addElement(score_tc)
|
team_row.addElement(score_tc)
|
||||||
|
|
||||||
@ -1986,7 +1949,7 @@ class PassageDetailView(LoginRequiredMixin, DetailView):
|
|||||||
or reg in passage.pool.juries.all()
|
or reg in passage.pool.juries.all()
|
||||||
or reg.pools_presided.filter(tournament=passage.pool.tournament).exists()) \
|
or reg.pools_presided.filter(tournament=passage.pool.tournament).exists()) \
|
||||||
or reg.participates and reg.team \
|
or reg.participates and reg.team \
|
||||||
and reg.team.participation in [passage.defender, passage.opponent, passage.reporter, passage.observer]:
|
and reg.team.participation in [passage.defender, passage.opponent, passage.reporter]:
|
||||||
return super().dispatch(request, *args, **kwargs)
|
return super().dispatch(request, *args, **kwargs)
|
||||||
return self.handle_no_permission()
|
return self.handle_no_permission()
|
||||||
|
|
||||||
@ -2004,9 +1967,6 @@ class PassageDetailView(LoginRequiredMixin, DetailView):
|
|||||||
notes = [note for note in notes if note.has_any_note() or note.jury == reg]
|
notes = [note for note in notes if note.has_any_note() or note.jury == reg]
|
||||||
context["notes"] = NoteTable(notes)
|
context["notes"] = NoteTable(notes)
|
||||||
|
|
||||||
# Only display the observer column for 4-teams pools
|
|
||||||
if passage.pool.participations.count() != 4:
|
|
||||||
context['notes']._sequence.remove('observer_oral')
|
|
||||||
if 'notes' in context and not self.request.user.registration.is_admin:
|
if 'notes' in context and not self.request.user.registration.is_admin:
|
||||||
context['notes']._sequence.remove('update')
|
context['notes']._sequence.remove('update')
|
||||||
|
|
||||||
@ -2016,8 +1976,6 @@ class PassageDetailView(LoginRequiredMixin, DetailView):
|
|||||||
context['notes'].columns['opponent_oral'].column.verbose_name += f" ({passage.opponent.team.trigram})"
|
context['notes'].columns['opponent_oral'].column.verbose_name += f" ({passage.opponent.team.trigram})"
|
||||||
context['notes'].columns['reporter_writing'].column.verbose_name += f" ({passage.reporter.team.trigram})"
|
context['notes'].columns['reporter_writing'].column.verbose_name += f" ({passage.reporter.team.trigram})"
|
||||||
context['notes'].columns['reporter_oral'].column.verbose_name += f" ({passage.reporter.team.trigram})"
|
context['notes'].columns['reporter_oral'].column.verbose_name += f" ({passage.reporter.team.trigram})"
|
||||||
if self.object.observer:
|
|
||||||
context['notes'].columns['observer_oral'].column.verbose_name += f" ({passage.observer.team.trigram})"
|
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
@ -2112,11 +2070,6 @@ class NoteUpdateView(VolunteerMixin, UpdateView):
|
|||||||
form.fields['opponent_oral'].label += f" ({self.object.passage.opponent.team.trigram})"
|
form.fields['opponent_oral'].label += f" ({self.object.passage.opponent.team.trigram})"
|
||||||
form.fields['reporter_writing'].label += f" ({self.object.passage.reporter.team.trigram})"
|
form.fields['reporter_writing'].label += f" ({self.object.passage.reporter.team.trigram})"
|
||||||
form.fields['reporter_oral'].label += f" ({self.object.passage.reporter.team.trigram})"
|
form.fields['reporter_oral'].label += f" ({self.object.passage.reporter.team.trigram})"
|
||||||
if self.object.passage.observer:
|
|
||||||
form.fields['observer_oral'].label += f" ({self.object.passage.observer.team.trigram})"
|
|
||||||
else:
|
|
||||||
# Set the note of the observer only for 4-teams pools
|
|
||||||
del form.fields['observer_oral']
|
|
||||||
return form
|
return form
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
|
Loading…
Reference in New Issue
Block a user