Update ODS note sheets

Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
Emmy D'Anello 2024-03-24 20:05:07 +01:00
parent 3465da4c36
commit b6d54d27cd
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
3 changed files with 41 additions and 23 deletions

View File

@ -17,6 +17,7 @@ from django.db.models.functions import Concat
from django.utils.translation import gettext_lazy as _
from pypdf import PdfReader
from registration.models import VolunteerRegistration
from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament
@ -291,7 +292,7 @@ class UploadNotesForm(forms.Form):
def process(self, csvfile: Iterable[str], cleaned_data: dict):
parsed_notes = {}
valid_lengths = [1 + 6 * 3, 1 + 7 * 4, 1 + 6 * 5] # Per pool sizes
valid_lengths = [2 + 6 * 3, 2 + 7 * 4, 2 + 6 * 5] # Per pool sizes
pool_size = 0
line_length = 0
for line in csvfile:
@ -310,29 +311,24 @@ class UploadNotesForm(forms.Form):
name = line[0]
if name.lower() in ["rôle", "juré", "moyenne", "coefficient", "sous-total", "équipe", "equipe"]:
continue
notes = line[1:line_length]
notes = line[2:line_length]
if not all(s.isnumeric() or s[0] == '-' and s[1:].isnumeric() for s in notes):
continue
notes = list(map(int, notes))
max_notes = pool_size * ([20, 16, 9, 10, 9, 10] + ([4] if pool_size == 4 else []))
max_notes = pool_size * ([20, 20, 10, 10, 10, 10] + ([4] if pool_size == 4 else []))
for n, max_n in zip(notes, max_notes):
if n > max_n:
self.add_error('file',
_("The following note is higher of the maximum expected value:")
+ str(n) + " > " + str(max_n))
# Search by "{first_name} {last_name}"
jury = User.objects.annotate(full_name=Concat('first_name', Value(' '), 'last_name',
output_field=CharField())) \
.filter(full_name=name.replace('', '\''), registration__volunteerregistration__isnull=False)
# Search by volunteer id
jury = VolunteerRegistration.objects.filter(pk=line[1])
if jury.count() != 1:
self.add_error('file', _("The following user was not found:") + " " + name)
continue
raise ValidationError({'file': _("The following user was not found:") + " " + name})
jury = jury.get()
vr = jury.registration
parsed_notes[vr] = notes
parsed_notes[jury] = notes
cleaned_data['parsed_notes'] = parsed_notes

View File

@ -680,7 +680,7 @@ class Passage(models.Model):
@property
def average_defender(self) -> float:
return self.average_defender_writing + (2 - 0.5 * self.defender_penalties) * self.average_defender_oral
return self.average_defender_writing + (1.6 - 0.4 * self.defender_penalties) * self.average_defender_oral
@property
def average_opponent_writing(self) -> float:
@ -692,7 +692,7 @@ class Passage(models.Model):
@property
def average_opponent(self) -> float:
return self.average_opponent_writing + 2 * self.average_opponent_oral
return 0.9 * self.average_opponent_writing + 2 * self.average_opponent_oral
@property
def average_reporter_writing(self) -> float:
@ -704,7 +704,7 @@ class Passage(models.Model):
@property
def average_reporter(self) -> float:
return 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:

View File

@ -1176,6 +1176,10 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
first_col_style.addElement(TableColumnProperties(columnwidth="9cm", breakbefore="auto"))
doc.automaticstyles.addElement(first_col_style)
jury_id_style = Style(name="co_jury_id", family="table-column")
jury_id_style.addElement(TableColumnProperties(columnwidth="1cm", breakbefore="auto"))
doc.automaticstyles.addElement(jury_id_style)
col_style = Style(name="co2", family="table-column")
col_style.addElement(TableColumnProperties(columnwidth="2.6cm", breakbefore="auto"))
doc.automaticstyles.addElement(col_style)
@ -1188,6 +1192,7 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
doc.spreadsheet.addElement(table)
table.addElement(TableColumn(stylename=first_col_style))
table.addElement(TableColumn(stylename=jury_id_style))
for i in range(line_length):
table.addElement(TableColumn(stylename=obs_col_style if pool_size == 4
@ -1198,7 +1203,9 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
table.addElement(header_pb)
problems_tc = TableCell(valuetype="string", stylename=title_style_topleft)
problems_tc.addElement(P(text="Problème"))
problems_tc.setAttribute('numbercolumnsspanned', "2")
header_pb.addElement(problems_tc)
header_pb.addElement(CoveredTableCell())
for passage in self.object.passages.all():
tc = TableCell(valuetype="string", stylename=title_style_topleftright)
tc.addElement(P(text=f"Problème {passage.solution_number}"))
@ -1212,7 +1219,9 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
table.addElement(header_role)
role_tc = TableCell(valuetype="string", stylename=title_style_left)
role_tc.addElement(P(text="Rôle"))
role_tc.setAttribute('numbercolumnsspanned', "2")
header_role.addElement(role_tc)
header_role.addElement(CoveredTableCell())
for i in range(pool_size):
defender_tc = TableCell(valuetype="string", stylename=title_style_left)
defender_tc.addElement(P(text="Défenseur⋅se"))
@ -1243,7 +1252,9 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
table.addElement(header_notes)
jury_tc = TableCell(valuetype="string", value="Juré⋅e", stylename=title_style_botleft)
jury_tc.addElement(P(text="Juré⋅e"))
jury_tc.setAttribute('numbercolumnsspanned', "2")
header_notes.addElement(jury_tc)
header_notes.addElement(CoveredTableCell())
for i in range(pool_size):
defender_w_tc = TableCell(valuetype="string", stylename=title_style_botleft)
@ -1251,11 +1262,11 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
header_notes.addElement(defender_w_tc)
defender_o_tc = TableCell(valuetype="string", stylename=title_style_bot)
defender_o_tc.addElement(P(text="Oral (/16)"))
defender_o_tc.addElement(P(text="Oral (/20)"))
header_notes.addElement(defender_o_tc)
opponent_w_tc = TableCell(valuetype="string", stylename=title_style_bot)
opponent_w_tc.addElement(P(text="Écrit (/9)"))
opponent_w_tc.addElement(P(text="Écrit (/10)"))
header_notes.addElement(opponent_w_tc)
opponent_o_tc = TableCell(valuetype="string", stylename=title_style_bot)
@ -1263,7 +1274,7 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
header_notes.addElement(opponent_o_tc)
reporter_w_tc = TableCell(valuetype="string", stylename=title_style_bot)
reporter_w_tc.addElement(P(text="Écrit (/9)"))
reporter_w_tc.addElement(P(text="Écrit (/10)"))
header_notes.addElement(reporter_w_tc)
reporter_o_tc = TableCell(valuetype="string",
@ -1285,6 +1296,9 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
name_tc = TableCell(valuetype="string", stylename=style_leftright)
name_tc.addElement(P(text=f"{jury.user.first_name} {jury.user.last_name}"))
jury_row.addElement(name_tc)
jury_id_tc = TableCell(valuetype="float", value=jury.pk, stylename=style_leftright)
jury_id_tc.addElement(P(text=str(jury.pk)))
jury_row.addElement(jury_id_tc)
for passage in self.object.passages.all():
notes = Note.objects.get(jury=jury, passage=passage)
@ -1297,14 +1311,16 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
jury_size = self.object.juries.count()
min_row = 4
max_row = 4 + jury_size - 1
min_column = 2
min_column = 3
# Add line for averages
average_row = TableRow()
table.addElement(average_row)
average_tc = TableCell(valuetype="string", stylename=title_style_topleftright)
average_tc.addElement(P(text="Moyenne"))
average_tc.setAttribute('numbercolumnsspanned', "2")
average_row.addElement(average_tc)
average_row.addElement(CoveredTableCell())
for i, passage in enumerate(self.object.passages.all()):
for j, note in enumerate(passage.averages):
tc = TableCell(valuetype="float", value=note,
@ -1321,17 +1337,19 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
table.addElement(coeff_row)
coeff_tc = TableCell(valuetype="string", stylename=title_style_leftright)
coeff_tc.addElement(P(text="Coefficient"))
coeff_tc.setAttribute('numbercolumnsspanned', "2")
coeff_row.addElement(coeff_tc)
coeff_row.addElement(CoveredTableCell())
for passage in self.object.passages.all():
defender_w_tc = TableCell(valuetype="float", value=1, stylename=style_left)
defender_w_tc.addElement(P(text="1"))
coeff_row.addElement(defender_w_tc)
defender_o_tc = TableCell(valuetype="float", value=2 - 0.5 * passage.defender_penalties, stylename=style)
defender_o_tc.addElement(P(text=str(2 - 0.5 * passage.defender_penalties)))
defender_o_tc = TableCell(valuetype="float", value=1.6 - 0.4 * passage.defender_penalties, stylename=style)
defender_o_tc.addElement(P(text=str(2 - 0.4 * passage.defender_penalties)))
coeff_row.addElement(defender_o_tc)
opponent_w_tc = TableCell(valuetype="float", value=1, stylename=style)
opponent_w_tc = TableCell(valuetype="float", value=0.9, stylename=style)
opponent_w_tc.addElement(P(text="1"))
coeff_row.addElement(opponent_w_tc)
@ -1339,7 +1357,7 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
opponent_o_tc.addElement(P(text="2"))
coeff_row.addElement(opponent_o_tc)
reporter_w_tc = TableCell(valuetype="float", value=1, stylename=style)
reporter_w_tc = TableCell(valuetype="float", value=0.9, stylename=style)
reporter_w_tc.addElement(P(text="1"))
coeff_row.addElement(reporter_w_tc)
@ -1358,7 +1376,9 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
table.addElement(subtotal_row)
subtotal_tc = TableCell(valuetype="string", stylename=title_style_botleft)
subtotal_tc.addElement(P(text="Sous-total"))
subtotal_tc.setAttribute('numbercolumnsspanned', "2")
subtotal_row.addElement(subtotal_tc)
subtotal_row.addElement(CoveredTableCell())
for i, passage in enumerate(self.object.passages.all()):
def_w_col = getcol(min_column + passage_width * i)
def_o_col = getcol(min_column + passage_width * i + 1)
@ -1406,6 +1426,7 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
table.addElement(scores_header)
team_tc = TableCell(valuetype="string", stylename=title_style_topbotleft)
team_tc.addElement(P(text="Équipe"))
team_tc.setAttribute('numbercolumnsspanned', "2")
scores_header.addElement(team_tc)
problem_tc = TableCell(valuetype="string", stylename=title_style_topbot)
problem_tc.addElement(P(text="Problème"))
@ -1452,6 +1473,7 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
team_tc = TableCell(valuetype="string",
stylename=style_botleft if passage.position == pool_size else style_left)
team_tc.addElement(P(text=f"{passage.defender.team.name} ({passage.defender.team.trigram})"))
team_tc.setAttribute('numbercolumnsspanned', "2")
team_row.addElement(team_tc)
problem_tc = TableCell(valuetype="string",