From 505a94e3aabfb7d7133e8cbbdec05f3c20105498 Mon Sep 17 00:00:00 2001 From: Emmy D'Anello Date: Fri, 7 Apr 2023 21:47:06 +0200 Subject: [PATCH] Customize the notation sheet template for juries Signed-off-by: Emmy D'Anello --- participation/forms.py | 2 +- participation/models.py | 21 + .../static/Fiche notations - 3 équipes.ods | Bin 22927 -> 0 bytes .../static/Fiche notations - 4 équipes.ods | Bin 18928 -> 0 bytes .../static/Fiche notations - 5 équipes.ods | Bin 18172 -> 0 bytes .../templates/participation/upload_notes.html | 11 +- participation/urls.py | 5 +- participation/views.py | 507 ++++++++++++++++++ requirements.txt | 1 + 9 files changed, 535 insertions(+), 12 deletions(-) delete mode 100644 participation/static/Fiche notations - 3 équipes.ods delete mode 100644 participation/static/Fiche notations - 4 équipes.ods delete mode 100644 participation/static/Fiche notations - 5 équipes.ods diff --git a/participation/forms.py b/participation/forms.py index 5691971..0a3f0f9 100644 --- a/participation/forms.py +++ b/participation/forms.py @@ -288,7 +288,7 @@ class UploadNotesForm(forms.Form): continue name = line[0] - if name in ["Rôle", "Juré", "moyenne", "coefficient", "sous-total", "Equipe"]: + if name.lower() in ["rôle", "juré", "moyenne", "coefficient", "sous-total", "équipe", "equipe"]: continue notes = line[1:line_length] if not all(s.isnumeric() or s[0] == '-' and s[1:].isnumeric() for s in notes): diff --git a/participation/models.py b/participation/models.py index 41113ef..88434c0 100644 --- a/participation/models.py +++ b/participation/models.py @@ -534,6 +534,17 @@ class Passage(models.Model): def average_observer(self) -> float: return self.avg(note.observer_oral for note in self.notes.all()) + @property + def averages(self): + yield self.average_defender_writing + yield self.average_defender_oral + yield self.average_opponent_writing + yield self.average_opponent_oral + yield self.average_reporter_writing + yield self.average_reporter_oral + if self.observer: + yield self.average_observer + 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 \ @@ -740,6 +751,16 @@ class Note(models.Model): default=0, ) + def get_all(self): + yield self.defender_writing + yield self.defender_oral + yield self.opponent_writing + yield self.opponent_oral + yield self.reporter_writing + 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, reporter_writing: int, reporter_oral: int, observer_oral: int = 0): self.defender_writing = defender_writing diff --git a/participation/static/Fiche notations - 3 équipes.ods b/participation/static/Fiche notations - 3 équipes.ods deleted file mode 100644 index 11afeb945a31d8e397cf11d288e8660c3926fd61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22927 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 VYO0Y_9Nats{FwulPX@%n>OX=kJoEqn diff --git a/participation/static/Fiche notations - 4 équipes.ods b/participation/static/Fiche notations - 4 équipes.ods deleted file mode 100644 index acd13673711b3e98e030b7dc3f01fa522a4b15b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18928 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 diff --git a/participation/static/Fiche notations - 5 équipes.ods b/participation/static/Fiche notations - 5 équipes.ods deleted file mode 100644 index 3bfd3579a29d2c5b37edb67293971f6f37c50ec9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18172 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
{% csrf_token %} diff --git a/participation/urls.py b/participation/urls.py index 4ad4b13..0e01cf6 100644 --- a/participation/urls.py +++ b/participation/urls.py @@ -6,8 +6,8 @@ from django.views.generic import TemplateView from .views import CreateTeamView, FinalNotationSheetTemplateView, JoinTeamView, MyParticipationDetailView, \ MyTeamDetailView, NoteUpdateView, ParticipationDetailView, PassageCreateView, PassageDetailView, \ - PassageUpdateView, PoolAddJurysView, PoolCreateView, PoolDetailView, PoolUpdateTeamsView, PoolUpdateView, \ - PoolUploadNotesView, ScaleNotationSheetTemplateView, SolutionUploadView, SynthesisUploadView,\ + PassageUpdateView, PoolAddJurysView, PoolCreateView, PoolDetailView, PoolNotesTemplateView, PoolUpdateTeamsView, \ + PoolUpdateView, PoolUploadNotesView, ScaleNotationSheetTemplateView, SolutionUploadView, SynthesisUploadView, \ TeamAuthorizationsView, TeamDetailView, TeamLeaveView, TeamListView, TeamUpdateView, \ TeamUploadMotivationLetterView, TournamentCreateView, TournamentDetailView, TournamentExportCSVView, \ TournamentListView, TournamentUpdateView @@ -42,6 +42,7 @@ urlpatterns = [ path("pools//update-teams/", PoolUpdateTeamsView.as_view(), name="pool_update_teams"), path("pools//add-jurys/", PoolAddJurysView.as_view(), name="pool_add_jurys"), path("pools//upload-notes/", PoolUploadNotesView.as_view(), name="pool_upload_notes"), + path("pools//upload-notes/template/", PoolNotesTemplateView.as_view(), name="pool_notes_template"), path("pools/passages/add//", PassageCreateView.as_view(), name="passage_create"), path("pools/passages//", PassageDetailView.as_view(), name="passage_detail"), path("pools/passages//update/", PassageUpdateView.as_view(), name="passage_update"), diff --git a/participation/views.py b/participation/views.py index 72cc994..523d988 100644 --- a/participation/views.py +++ b/participation/views.py @@ -26,6 +26,10 @@ from django.views.generic import CreateView, DetailView, FormView, RedirectView, from django.views.generic.edit import FormMixin, ProcessFormView from django_tables2 import SingleTableView from magic import Magic +from odf.opendocument import OpenDocumentSpreadsheet +from odf.style import Style, TableCellProperties, TableColumnProperties, TextProperties +from odf.table import CoveredTableCell, Table, TableCell, TableColumn, TableRow +from odf.text import P from registration.models import StudentRegistration, VolunteerRegistration from tfjm.lists import get_sympa_client from tfjm.matrix import Matrix @@ -824,6 +828,509 @@ class PoolUploadNotesView(VolunteerMixin, FormView, DetailView): return reverse_lazy('participation:pool_detail', args=(self.kwargs['pk'],)) +class PoolNotesTemplateView(VolunteerMixin, DetailView): + """ + Generate an ODS sheet to fill the notes of the pool. + """ + model = Pool + + def render_to_response(self, context, **response_kwargs): # noqa: C901 + pool_size = self.object.passages.count() + passage_width = 7 if pool_size == 4 else 6 + line_length = pool_size * passage_width + + def getcol(number: int) -> str: + """ + Translates the given number to the nth column name + """ + if number == 0: + return '' + return getcol((number - 1) // 26) + chr(65 + (number - 1) % 26) + + doc = OpenDocumentSpreadsheet() + + # Define styles + style = Style(name="Contenu", family="table-cell") + style.addElement(TableCellProperties(border="0.75pt solid #000000")) + doc.styles.addElement(style) + + style_left = Style(name="Contenu gauche", family="table-cell") + style_left.addElement(TableCellProperties(border="0.75pt solid #000000", borderleft="2pt solid #000000")) + doc.styles.addElement(style_left) + + style_right = Style(name="Contenu droite", family="table-cell") + style_right.addElement(TableCellProperties(border="0.75pt solid #000000", borderright="2pt solid #000000")) + doc.styles.addElement(style_right) + + style_top = Style(name="Contenu haut", family="table-cell") + style_top.addElement(TableCellProperties(border="0.75pt solid #000000", bordertop="2pt solid #000000")) + doc.styles.addElement(style_top) + + style_topright = Style(name="Contenu haut droite", family="table-cell") + style_topright.addElement(TableCellProperties(border="0.75pt solid #000000", + borderright="2pt solid #000000", + bordertop="2pt solid #000000")) + doc.styles.addElement(style_topright) + + style_topleftright = Style(name="Contenu haut gauche droite", family="table-cell") + style_topleftright.addElement(TableCellProperties(border="0.75pt solid #000000", + borderleft="2pt solid #000000", + borderright="2pt solid #000000", + bordertop="2pt solid #000000")) + doc.styles.addElement(style_topleftright) + + style_leftright = Style(name="Contenu haut gauche droite", family="table-cell") + style_leftright.addElement(TableCellProperties(border="0.75pt solid #000000", + borderleft="2pt solid #000000", + borderright="2pt solid #000000")) + doc.styles.addElement(style_leftright) + + style_botleft = Style(name="Contenu bas gauche", family="table-cell") + style_botleft.addElement(TableCellProperties(border="0.75pt solid #000000", + borderbottom="2pt solid #000000", + borderleft="2pt solid #000000")) + doc.styles.addElement(style_botleft) + + style_bot = Style(name="Contenu bas", family="table-cell") + style_bot.addElement(TableCellProperties(border="0.75pt solid #000000", borderbottom="2pt solid #000000")) + doc.styles.addElement(style_bot) + + style_botright = Style(name="Contenu bas droite", family="table-cell") + style_botright.addElement(TableCellProperties(border="0.75pt solid #000000", + borderbottom="2pt solid #000000", + borderright="2pt solid #000000")) + doc.styles.addElement(style_botright) + + title_style = Style(name="Titre", family="table-cell") + title_style.addElement(TextProperties(fontweight="bold")) + title_style.addElement(TableCellProperties(border="0.75pt solid #000000")) + doc.styles.addElement(title_style) + + title_style_left = Style(name="Titre gauche", family="table-cell") + title_style_left.addElement(TextProperties(fontweight="bold")) + title_style_left.addElement(TableCellProperties(border="0.75pt solid #000000", + borderleft="2pt solid #000000")) + doc.styles.addElement(title_style_left) + + title_style_right = Style(name="Titre droite", family="table-cell") + title_style_right.addElement(TextProperties(fontweight="bold")) + title_style_right.addElement(TableCellProperties(border="0.75pt solid #000000", + borderright="2pt solid #000000")) + doc.styles.addElement(title_style_right) + + title_style_leftright = Style(name="Titre gauche droite", family="table-cell") + title_style_leftright.addElement(TextProperties(fontweight="bold")) + title_style_leftright.addElement(TableCellProperties(border="0.75pt solid #000000", + borderleft="2pt solid #000000", + borderright="2pt solid #000000")) + doc.styles.addElement(title_style_leftright) + + title_style_top = Style(name="Titre haut", family="table-cell") + title_style_top.addElement(TextProperties(fontweight="bold")) + title_style_top.addElement(TableCellProperties(border="0.75pt solid #000000", + bordertop="2pt solid #000000")) + doc.styles.addElement(title_style_top) + + title_style_topbot = Style(name="Titre haut bas", family="table-cell") + title_style_topbot.addElement(TextProperties(fontweight="bold")) + title_style_topbot.addElement(TableCellProperties(border="0.75pt solid #000000", + bordertop="2pt solid #000000", + borderbottom="2pt solid #000000")) + doc.styles.addElement(title_style_topbot) + + title_style_topleft = Style(name="Titre haut gauche", family="table-cell") + title_style_topleft.addElement(TextProperties(fontweight="bold")) + title_style_topleft.addElement(TableCellProperties(border="0.75pt solid #000000", + bordertop="2pt solid #000000", + borderleft="2pt solid #000000")) + doc.styles.addElement(title_style_topleft) + + title_style_topbotleft = Style(name="Titre haut bas gauche", family="table-cell") + title_style_topbotleft.addElement(TextProperties(fontweight="bold")) + title_style_topbotleft.addElement(TableCellProperties(border="0.75pt solid #000000", + bordertop="2pt solid #000000", + borderbottom="2pt solid #000000", + borderleft="2pt solid #000000")) + doc.styles.addElement(title_style_topbotleft) + + title_style_topright = Style(name="Titre haut droite", family="table-cell") + title_style_topright.addElement(TextProperties(fontweight="bold")) + title_style_topright.addElement(TableCellProperties(border="0.75pt solid #000000", + bordertop="2pt solid #000000", + borderright="2pt solid #000000")) + doc.styles.addElement(title_style_topright) + + title_style_topbotright = Style(name="Titre haut bas droite", family="table-cell") + title_style_topbotright.addElement(TextProperties(fontweight="bold")) + title_style_topbotright.addElement(TableCellProperties(border="0.75pt solid #000000", + bordertop="2pt solid #000000", + borderbottom="2pt solid #000000", + borderright="2pt solid #000000")) + doc.styles.addElement(title_style_topbotright) + + title_style_topleftright = Style(name="Titre haut gauche droite", family="table-cell") + title_style_topleftright.addElement(TextProperties(fontweight="bold")) + title_style_topleftright.addElement(TableCellProperties(border="0.75pt solid #000000", + bordertop="2pt solid #000000", + borderleft="2pt solid #000000", + borderright="2pt solid #000000")) + doc.styles.addElement(title_style_topleftright) + + title_style_bot = Style(name="Titre bas", family="table-cell") + title_style_bot.addElement(TextProperties(fontweight="bold")) + title_style_bot.addElement(TableCellProperties(border="0.75pt solid #000000", + borderbottom="2pt solid #000000")) + doc.styles.addElement(title_style_bot) + + title_style_botleft = Style(name="Titre bas gauche", family="table-cell") + title_style_botleft.addElement(TextProperties(fontweight="bold")) + title_style_botleft.addElement(TableCellProperties(border="0.75pt solid #000000", + borderbottom="2pt solid #000000", + borderleft="2pt solid #000000")) + doc.styles.addElement(title_style_botleft) + + title_style_botright = Style(name="Titre bas droite", family="table-cell") + title_style_botright.addElement(TextProperties(fontweight="bold")) + title_style_botright.addElement(TableCellProperties(border="0.75pt solid #000000", + borderbottom="2pt solid #000000", + borderright="2pt solid #000000")) + doc.styles.addElement(title_style_botright) + + first_col_style = Style(name="co1", family="table-column") + first_col_style.addElement(TableColumnProperties(columnwidth="9cm", breakbefore="auto")) + doc.automaticstyles.addElement(first_col_style) + + col_style = Style(name="co2", family="table-column") + col_style.addElement(TableColumnProperties(columnwidth="2.6cm", breakbefore="auto")) + 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}") + doc.spreadsheet.addElement(table) + + table.addElement(TableColumn(stylename=first_col_style)) + + for i in range(line_length): + table.addElement(TableColumn(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 + header_pb = TableRow() + table.addElement(header_pb) + problems_tc = TableCell(valuetype="string", stylename=title_style_topleft) + problems_tc.addElement(P(text="Problème")) + header_pb.addElement(problems_tc) + 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}")) + tc.setAttribute('numbercolumnsspanned', "7" if pool_size == 4 else "6") + tc.setAttribute("formula", f"of:=[.B{8 + self.object.juries.count() + passage.position}]") + header_pb.addElement(tc) + header_pb.addElement(CoveredTableCell(numbercolumnsrepeated=6 if pool_size == 4 else 5)) + + # Add roles on the second line of the table + header_role = TableRow() + table.addElement(header_role) + role_tc = TableCell(valuetype="string", stylename=title_style_left) + role_tc.addElement(P(text="Rôle")) + header_role.addElement(role_tc) + for i in range(pool_size): + defender_tc = TableCell(valuetype="string", stylename=title_style_left) + defender_tc.addElement(P(text="Défenseur⋅se")) + defender_tc.setAttribute('numbercolumnsspanned', "2") + header_role.addElement(defender_tc) + header_role.addElement(CoveredTableCell()) + + opponent_tc = TableCell(valuetype="string", stylename=title_style) + opponent_tc.addElement(P(text="Opposant⋅e")) + opponent_tc.setAttribute('numbercolumnsspanned', "2") + header_role.addElement(opponent_tc) + header_role.addElement(CoveredTableCell()) + + reporter_tc = TableCell(valuetype="string", + stylename=title_style_right if pool_size != 4 else title_style) + reporter_tc.addElement(P(text="Rapporteur⋅e")) + reporter_tc.setAttribute('numbercolumnsspanned', "2") + header_role.addElement(reporter_tc) + 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 + header_notes = TableRow() + table.addElement(header_notes) + jury_tc = TableCell(valuetype="string", value="Juré⋅e", stylename=title_style_botleft) + jury_tc.addElement(P(text="Juré⋅e")) + header_notes.addElement(jury_tc) + + for i in range(pool_size): + defender_w_tc = TableCell(valuetype="string", stylename=title_style_botleft) + defender_w_tc.addElement(P(text="Écrit (/20)")) + header_notes.addElement(defender_w_tc) + + defender_o_tc = TableCell(valuetype="string", stylename=title_style_bot) + defender_o_tc.addElement(P(text="Oral (/16)")) + header_notes.addElement(defender_o_tc) + + opponent_w_tc = TableCell(valuetype="string", stylename=title_style_bot) + opponent_w_tc.addElement(P(text="Écrit (/9)")) + header_notes.addElement(opponent_w_tc) + + opponent_o_tc = TableCell(valuetype="string", stylename=title_style_bot) + opponent_o_tc.addElement(P(text="Oral (/10)")) + header_notes.addElement(opponent_o_tc) + + reporter_w_tc = TableCell(valuetype="string", stylename=title_style_bot) + reporter_w_tc.addElement(P(text="Écrit (/9)")) + header_notes.addElement(reporter_w_tc) + + reporter_o_tc = TableCell(valuetype="string", + stylename=title_style_botright if pool_size != 4 else title_style_bot) + reporter_o_tc.addElement(P(text="Oral (/10)")) + 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 + for jury in self.object.juries.all(): + jury_row = TableRow() + table.addElement(jury_row) + + 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) + + for passage in self.object.passages.all(): + notes = Note.objects.get(jury=jury, passage=passage) + for j, note in enumerate(notes.get_all()): + note_tc = TableCell(valuetype="float", value=note, + stylename=style_right if j == passage_width - 1 else style) + note_tc.addElement(P(text=str(note))) + jury_row.addElement(note_tc) + + jury_size = self.object.juries.count() + min_row = 4 + max_row = 4 + jury_size - 1 + min_column = 2 + + # 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_row.addElement(average_tc) + for i, passage in enumerate(self.object.passages.all()): + for j, note in enumerate(passage.averages): + tc = TableCell(valuetype="float", value=note, + stylename=style_topright if j == passage_width - 1 else style_top) + tc.addElement(P(text=str(note))) + column = getcol(min_column + i * passage_width + j) + tc.setAttribute("formula", f"of:=AVERAGEIF([.${getcol(min_column + i * passage_width)}${min_row}" + f":${getcol(min_column + i * passage_width)}{max_row}]; \">0\"; " + f"[.{column}${min_row}:{column}{max_row}])") + average_row.addElement(tc) + + # Add coefficients for each note on the next line + coeff_row = TableRow() + table.addElement(coeff_row) + coeff_tc = TableCell(valuetype="string", stylename=title_style_leftright) + coeff_tc.addElement(P(text="Coefficient")) + coeff_row.addElement(coeff_tc) + 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))) + coeff_row.addElement(defender_o_tc) + + opponent_w_tc = TableCell(valuetype="float", value=1, stylename=style) + opponent_w_tc.addElement(P(text="1")) + coeff_row.addElement(opponent_w_tc) + + opponent_o_tc = TableCell(valuetype="float", value=2, stylename=style) + 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.addElement(P(text="1")) + coeff_row.addElement(reporter_w_tc) + + reporter_o_tc = TableCell(valuetype="float", value=1, + stylename=style_right if pool_size != 4 else style) + reporter_o_tc.addElement(P(text="1")) + 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 + subtotal_row = TableRow() + table.addElement(subtotal_row) + subtotal_tc = TableCell(valuetype="string", stylename=title_style_botleft) + subtotal_tc.addElement(P(text="Sous-total")) + subtotal_row.addElement(subtotal_tc) + 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) + defender_tc = TableCell(valuetype="float", value=passage.average_defender, stylename=style_botleft) + defender_tc.addElement(P(text=str(passage.average_defender))) + defender_tc.setAttribute('numbercolumnsspanned', "2") + defender_tc.setAttribute("formula", f"of:=[.{def_w_col}{max_row + 1}] * [.{def_w_col}{max_row + 2}]" + f" + [.{def_o_col}{max_row + 1}] * [.{def_o_col}{max_row + 2}]") + subtotal_row.addElement(defender_tc) + subtotal_row.addElement(CoveredTableCell()) + + opp_w_col = getcol(min_column + passage_width * i + 2) + opp_o_col = getcol(min_column + passage_width * i + 3) + opponent_tc = TableCell(valuetype="float", value=passage.average_opponent, stylename=style_bot) + opponent_tc.addElement(P(text=str(passage.average_opponent))) + opponent_tc.setAttribute('numbercolumnsspanned', "2") + opponent_tc.setAttribute("formula", f"of:=[.{opp_w_col}{max_row + 1}] * [.{opp_w_col}{max_row + 2}]" + f" + [.{opp_o_col}{max_row + 1}] * [.{opp_o_col}{max_row + 2}]") + subtotal_row.addElement(opponent_tc) + subtotal_row.addElement(CoveredTableCell()) + + rep_w_col = getcol(min_column + passage_width * i + 4) + rep_o_col = getcol(min_column + passage_width * i + 5) + reporter_tc = TableCell(valuetype="float", value=passage.average_reporter, + stylename=style_botright if pool_size != 4 else style_bot) + reporter_tc.addElement(P(text=str(passage.average_reporter))) + reporter_tc.setAttribute('numbercolumnsspanned', "2") + reporter_tc.setAttribute("formula", f"of:=[.{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}]") + subtotal_row.addElement(reporter_tc) + 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()) + + # Compute the total scores in a new table + scores_header = TableRow() + table.addElement(scores_header) + team_tc = TableCell(valuetype="string", stylename=title_style_topbotleft) + team_tc.addElement(P(text="Équipe")) + scores_header.addElement(team_tc) + problem_tc = TableCell(valuetype="string", stylename=title_style_topbot) + problem_tc.addElement(P(text="Problème")) + scores_header.addElement(problem_tc) + total_tc = TableCell(valuetype="string", stylename=title_style_topbot) + total_tc.addElement(P(text="Total")) + scores_header.addElement(total_tc) + rank_tc = TableCell(valuetype="string", stylename=title_style_topbotright) + rank_tc.addElement(P(text="Rang")) + scores_header.addElement(rank_tc) + + # 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 + # and eventually observer on the passage number Pi3. + passage_matrix = [] + match pool_size: + case 3: + passage_matrix = [ + [0, 2, 1], + [1, 0, 2], + [2, 1, 0], + ] + case 4: + passage_matrix = [ + [0, 3, 2, 1], + [1, 0, 3, 2], + [2, 1, 0, 3], + [3, 2, 1, 0], + ] + case 5: + passage_matrix = [ + [0, 2, 3], + [1, 4, 2], + [2, 0, 4], + [3, 1, 0], + [4, 3, 1], + ] + + sorted_participations = sorted(self.object.participations.all(), key=lambda p: -self.object.average(p)) + for passage in self.object.passages.all(): + team_row = TableRow() + table.addElement(team_row) + + 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_row.addElement(team_tc) + + problem_tc = TableCell(valuetype="string", + stylename=style_bot if passage.position == pool_size else style) + problem_tc.addElement(P(text=f"Problème {passage.solution_number}")) + team_row.addElement(problem_tc) + + passage_line = passage_matrix[passage.position - 1] + score_tc = TableCell(valuetype="float", value=self.object.average(passage.defender), + stylename=style_bot if passage.position == pool_size else style) + score_tc.addElement(P(text=self.object.average(passage.defender))) + formula = "of:=" + 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[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) + team_row.addElement(score_tc) + + score_col = 'C' + rank_tc = TableCell(valuetype="float", value=sorted_participations.index(passage.defender) + 1, + stylename=style_botright if passage.position == pool_size else style_right) + rank_tc.addElement(P(text=str(sorted_participations.index(passage.defender) + 1))) + rank_tc.setAttribute("formula", f"of:=RANK([.{score_col}{max_row + 5 + passage.position}]; " + f"[.{score_col}${max_row + 6}]:[.{score_col}${max_row + 5 + pool_size}])") + team_row.addElement(rank_tc) + + table.addElement(TableRow()) + + # Add small instructions + instructions_tr = TableRow() + table.addElement(instructions_tr) + instructions_tc = TableCell() + instructions_tc.addElement(P(text="Merci de ne pas toucher aux noms des juré⋅es.\n" + "Si nécessaire, faites les modifications sur le site\n" + "et récupérez le nouveau template.\n" + "N'entrez que des notes entières.\n" + "Ne retirez pas de 0 : toute ligne incomplète sera ignorée.\n" + "Dans le cadre de poules à 5, laissez des 0 en face des\n" + "juré⋅es qui ne sont pas dans le passage souhaité,\n" + "et remplissez uniquement les notes nécessaires dans le tableau.\n" + "Les moyennes calculées ignorent les 0, donc pas d'inquiétude.")) + instructions_tr.addElement(instructions_tc) + + # Save the sheet in a temporary file and send it in the response + doc.save('/tmp/notes.ods') + + return FileResponse(streaming_content=open("/tmp/notes.ods", "rb"), + content_type="application/vnd.oasis.opendocument.spreadsheet", + filename=f"Feuille de notes - {self.object.tournament.name} " + f"- Poule {self.object.get_letter_display()}{self.object.round}.ods") + + class NotationSheetTemplateView(VolunteerMixin, DetailView): """ Generate a PDF from a LaTeX template for the notation papers. diff --git a/requirements.txt b/requirements.txt index cb64647..51dfa6c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,6 +14,7 @@ djangorestframework~=3.14 django-rest-polymorphic~=0.1 gunicorn~=20.1 matrix-nio~=0.20 +odfpy~=1.4.1 phonenumbers~=8.12.57 psycopg2-binary~=2.9.5 pypdf~=3.4