Defender => Reporter
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
parent
12205f953b
commit
620bbe7817
|
@ -416,7 +416,7 @@ class Pool(models.Model):
|
||||||
passage_pool = pool2
|
passage_pool = pool2
|
||||||
passage_position = 1 + i // 2
|
passage_position = 1 + i // 2
|
||||||
|
|
||||||
defender = tds[line[0]].participation
|
reporter = tds[line[0]].participation
|
||||||
opponent = tds[line[1]].participation
|
opponent = tds[line[1]].participation
|
||||||
reviewer = tds[line[2]].participation
|
reviewer = tds[line[2]].participation
|
||||||
observer = tds[line[3]].participation if self.size >= 4 and settings.TFJM_APP == "ETEAM" else None
|
observer = tds[line[3]].participation if self.size >= 4 and settings.TFJM_APP == "ETEAM" else None
|
||||||
|
@ -426,11 +426,11 @@ class Pool(models.Model):
|
||||||
pool=passage_pool,
|
pool=passage_pool,
|
||||||
position=passage_position,
|
position=passage_position,
|
||||||
solution_number=tds[line[0]].accepted,
|
solution_number=tds[line[0]].accepted,
|
||||||
defender=defender,
|
reporter=reporter,
|
||||||
opponent=opponent,
|
opponent=opponent,
|
||||||
reviewer=reviewer,
|
reviewer=reviewer,
|
||||||
observer=observer,
|
observer=observer,
|
||||||
defender_penalties=tds[line[0]].penalty_int,
|
reporter_penalties=tds[line[0]].penalty_int,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Update Google Sheets
|
# Update Google Sheets
|
||||||
|
@ -549,7 +549,7 @@ class TeamDraw(models.Model):
|
||||||
@property
|
@property
|
||||||
def penalty(self):
|
def penalty(self):
|
||||||
"""
|
"""
|
||||||
The penalty multiplier on the defender oral, in percentage, which is a malus of 25% for each penalty.
|
The penalty multiplier on the reporter oral, in percentage, which is a malus of 25% for each penalty.
|
||||||
"""
|
"""
|
||||||
return 25 * self.penalty_int
|
return 25 * self.penalty_int
|
||||||
|
|
||||||
|
|
|
@ -521,9 +521,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
teamTd.innerText = team
|
teamTd.innerText = team
|
||||||
teamTr.append(teamTd)
|
teamTr.append(teamTd)
|
||||||
|
|
||||||
let defenderTd = document.createElement('td')
|
let reporterTd = document.createElement('td')
|
||||||
defenderTd.classList.add('text-center')
|
reporterTd.classList.add('text-center')
|
||||||
defenderTd.innerText = 'Déf'
|
reporterTd.innerText = 'Déf'
|
||||||
|
|
||||||
let opponentTd = document.createElement('td')
|
let opponentTd = document.createElement('td')
|
||||||
opponentTd.classList.add('text-center')
|
opponentTd.classList.add('text-center')
|
||||||
|
@ -537,29 +537,29 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
if (poule.teams.length === 3) {
|
if (poule.teams.length === 3) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
teamTr.append(defenderTd, reviewerTd, opponentTd)
|
teamTr.append(reporterTd, reviewerTd, opponentTd)
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
teamTr.append(opponentTd, defenderTd, reviewerTd)
|
teamTr.append(opponentTd, reporterTd, reviewerTd)
|
||||||
break
|
break
|
||||||
case 2:
|
case 2:
|
||||||
teamTr.append(reviewerTd, opponentTd, defenderTd)
|
teamTr.append(reviewerTd, opponentTd, reporterTd)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else if (poule.teams.length === 4) {
|
} else if (poule.teams.length === 4) {
|
||||||
let emptyTd = document.createElement('td')
|
let emptyTd = document.createElement('td')
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
teamTr.append(defenderTd, emptyTd, reviewerTd, opponentTd)
|
teamTr.append(reporterTd, emptyTd, reviewerTd, opponentTd)
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
teamTr.append(opponentTd, defenderTd, emptyTd, reviewerTd)
|
teamTr.append(opponentTd, reporterTd, emptyTd, reviewerTd)
|
||||||
break
|
break
|
||||||
case 2:
|
case 2:
|
||||||
teamTr.append(reviewerTd, opponentTd, defenderTd, emptyTd)
|
teamTr.append(reviewerTd, opponentTd, reporterTd, emptyTd)
|
||||||
break
|
break
|
||||||
case 3:
|
case 3:
|
||||||
teamTr.append(emptyTd, reviewerTd, opponentTd, defenderTd)
|
teamTr.append(emptyTd, reviewerTd, opponentTd, reporterTd)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else if (poule.teams.length === 5) {
|
} else if (poule.teams.length === 5) {
|
||||||
|
@ -567,19 +567,19 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
let emptyTd2 = document.createElement('td')
|
let emptyTd2 = document.createElement('td')
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
teamTr.append(defenderTd, emptyTd, opponentTd, reviewerTd, emptyTd2)
|
teamTr.append(reporterTd, emptyTd, opponentTd, reviewerTd, emptyTd2)
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
teamTr.append(emptyTd, defenderTd, reviewerTd, emptyTd2, opponentTd)
|
teamTr.append(emptyTd, reporterTd, reviewerTd, emptyTd2, opponentTd)
|
||||||
break
|
break
|
||||||
case 2:
|
case 2:
|
||||||
teamTr.append(opponentTd, emptyTd, defenderTd, emptyTd2, reviewerTd)
|
teamTr.append(opponentTd, emptyTd, reporterTd, emptyTd2, reviewerTd)
|
||||||
break
|
break
|
||||||
case 3:
|
case 3:
|
||||||
teamTr.append(reviewerTd, opponentTd, emptyTd, defenderTd, emptyTd2)
|
teamTr.append(reviewerTd, opponentTd, emptyTd, reporterTd, emptyTd2)
|
||||||
break
|
break
|
||||||
case 4:
|
case 4:
|
||||||
teamTr.append(emptyTd, reviewerTd, emptyTd2, opponentTd, defenderTd)
|
teamTr.append(emptyTd, reviewerTd, emptyTd2, opponentTd, reporterTd)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -662,7 +662,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
|
||||||
let penaltyDiv = document.getElementById(`recap-${tid}-round-${round}-team-${team}-penalty`)
|
let penaltyDiv = document.getElementById(`recap-${tid}-round-${round}-team-${team}-penalty`)
|
||||||
if (rejected.length > problems_count - RECOMMENDED_SOLUTIONS_COUNT) {
|
if (rejected.length > problems_count - RECOMMENDED_SOLUTIONS_COUNT) {
|
||||||
// If more than P - 5 problems were rejected, add a penalty of 25% of the coefficient of the oral defender
|
// If more than P - 5 problems were rejected, add a penalty of 25% of the coefficient of the oral reporter
|
||||||
// This is P - 6 for the ETEAM
|
// This is P - 6 for the ETEAM
|
||||||
if (penaltyDiv === null) {
|
if (penaltyDiv === null) {
|
||||||
penaltyDiv = document.createElement('div')
|
penaltyDiv = document.createElement('div')
|
||||||
|
|
|
@ -307,71 +307,71 @@
|
||||||
<td class="text-center">{{ td.participation.team.trigram }}</td>
|
<td class="text-center">{{ td.participation.team.trigram }}</td>
|
||||||
{% if pool.size == 3 %}
|
{% if pool.size == 3 %}
|
||||||
{% if forloop.counter == 1 %}
|
{% if forloop.counter == 1 %}
|
||||||
<td class="text-center">Déf</td>
|
<td class="text-center">{% trans "Rep" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Rap</td>
|
<td class="text-center">{% trans "Rev" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Opp</td>
|
<td class="text-center">{% trans "Opp" context "Role abbreviation" %}</td>
|
||||||
{% elif forloop.counter == 2 %}
|
{% elif forloop.counter == 2 %}
|
||||||
<td class="text-center">Opp</td>
|
<td class="text-center">{% trans "Opp" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Déf</td>
|
<td class="text-center">{% trans "Rep" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Rap</td>
|
<td class="text-center">{% trans "Rev" context "Role abbreviation" %}</td>
|
||||||
{% elif forloop.counter == 3 %}
|
{% elif forloop.counter == 3 %}
|
||||||
<td class="text-center">Rap</td>
|
<td class="text-center">{% trans "Rev" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Opp</td>
|
<td class="text-center">{% trans "Opp" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Déf</td>
|
<td class="text-center">{% trans "Rep" context "Role abbreviation" %}</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% elif pool.size == 4 %}
|
{% elif pool.size == 4 %}
|
||||||
{% if forloop.counter == 1 %}
|
{% if forloop.counter == 1 %}
|
||||||
<td class="text-center">Déf</td>
|
<td class="text-center">{% trans "Rep" context "Role abbreviation" %}</td>
|
||||||
<td></td>
|
<td class="text-center">{% if TFJM.APP == "ETEAM" %}{% trans "Obs" context "Role abbreviation" %}{% endif %}</td>
|
||||||
<td class="text-center">Rap</td>
|
<td class="text-center">{% trans "Rev" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Opp</td>
|
<td class="text-center">{% trans "Opp" context "Role abbreviation" %}</td>
|
||||||
{% elif forloop.counter == 2 %}
|
{% elif forloop.counter == 2 %}
|
||||||
<td class="text-center">Opp</td>
|
<td class="text-center">{% trans "Opp" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Déf</td>
|
<td class="text-center">{% trans "Rep" context "Role abbreviation" %}</td>
|
||||||
<td></td>
|
<td class="text-center">{% if TFJM.APP == "ETEAM" %}{% trans "Obs" context "Role abbreviation" %}{% endif %}</td>
|
||||||
<td class="text-center">Rap</td>
|
<td class="text-center">{% trans "Rev" context "Role abbreviation" %}</td>
|
||||||
{% elif forloop.counter == 3 %}
|
{% elif forloop.counter == 3 %}
|
||||||
<td class="text-center">Rap</td>
|
<td class="text-center">{% trans "Rev" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Opp</td>
|
<td class="text-center">{% trans "Opp" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Déf</td>
|
<td class="text-center">{% trans "Rep" context "Role abbreviation" %}</td>
|
||||||
<td></td>
|
<td class="text-center">{% if TFJM.APP == "ETEAM" %}{% trans "Obs" context "Role abbreviation" %}{% endif %}</td>
|
||||||
{% elif forloop.counter == 4 %}
|
{% elif forloop.counter == 4 %}
|
||||||
<td></td>
|
<td class="text-center">{% if TFJM.APP == "ETEAM" %}{% trans "Obs" context "Role abbreviation" %}{% endif %}</td>
|
||||||
<td class="text-center">Rap</td>
|
<td class="text-center">{% trans "Rev" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Opp</td>
|
<td class="text-center">{% trans "Opp" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Déf</td>
|
<td class="text-center">{% trans "Rep" context "Role abbreviation" %}</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% elif pool.size == 5 %}
|
{% elif pool.size == 5 %}
|
||||||
{% if forloop.counter == 1 %}
|
{% if forloop.counter == 1 %}
|
||||||
<td class="text-center">Déf</td>
|
<td class="text-center">{% trans "Rep" context "Role abbreviation" %}</td>
|
||||||
<td></td>
|
<td class="text-center"></td>
|
||||||
<td class="text-center">Rap</td>
|
<td class="text-center">{% trans "Rev" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Opp</td>
|
<td class="text-center">{% trans "Opp" context "Role abbreviation" %}</td>
|
||||||
<td></td>
|
<td class="text-center">{% if TFJM.APP == "ETEAM" %}{% trans "Obs" context "Role abbreviation" %}{% endif %}</td>
|
||||||
{% elif forloop.counter == 2 %}
|
{% elif forloop.counter == 2 %}
|
||||||
<td></td>
|
<td class="text-center">{% if TFJM.APP == "ETEAM" %}{% trans "Obs" context "Role abbreviation" %}{% endif %}</td>
|
||||||
<td class="text-center">Déf</td>
|
<td class="text-center">{% trans "Rep" context "Role abbreviation" %}</td>
|
||||||
<td></td>
|
<td class="text-center"></td>
|
||||||
<td class="text-center">Rap</td>
|
<td class="text-center">{% trans "Rev" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Opp</td>
|
<td class="text-center">{% trans "Opp" context "Role abbreviation" %}</td>
|
||||||
{% elif forloop.counter == 3 %}
|
{% elif forloop.counter == 3 %}
|
||||||
<td class="text-center">Opp</td>
|
<td class="text-center">{% trans "Opp" context "Role abbreviation" %}</td>
|
||||||
<td></td>
|
<td class="text-center">{% if TFJM.APP == "ETEAM" %}{% trans "Obs" context "Role abbreviation" %}{% endif %}</td>
|
||||||
<td class="text-center">Déf</td>
|
<td class="text-center">{% trans "Rep" context "Role abbreviation" %}</td>
|
||||||
<td></td>
|
<td class="text-center"></td>
|
||||||
<td class="text-center">Rap</td>
|
<td class="text-center">{% trans "Rev" context "Role abbreviation" %}</td>
|
||||||
{% elif forloop.counter == 4 %}
|
{% elif forloop.counter == 4 %}
|
||||||
<td class="text-center">Rap</td>
|
<td class="text-center">{% trans "Rev" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Opp</td>
|
<td class="text-center">{% trans "Opp" context "Role abbreviation" %}</td>
|
||||||
<td></td>
|
<td class="text-center">{% if TFJM.APP == "ETEAM" %}{% trans "Obs" context "Role abbreviation" %}{% endif %}</td>
|
||||||
<td class="text-center">Déf</td>
|
<td class="text-center">{% trans "Rep" context "Role abbreviation" %}</td>
|
||||||
<td></td>
|
<td class="text-center"></td>
|
||||||
{% elif forloop.counter == 5 %}
|
{% elif forloop.counter == 5 %}
|
||||||
<td></td>
|
<td class="text-center"></td>
|
||||||
<td class="text-center">Rap</td>
|
<td class="text-center">{% trans "Rev" context "Role abbreviation" %}</td>
|
||||||
<td class="text-center">Opp</td>
|
<td class="text-center">{% trans "Opp" context "Role abbreviation" %}</td>
|
||||||
<td></td>
|
<td class="text-center">{% if TFJM.APP == "ETEAM" %}{% trans "Obs" context "Role abbreviation" %}{% endif %}</td>
|
||||||
<td class="text-center">Déf</td>
|
<td class="text-center">{% trans "Rep" context "Role abbreviation" %}</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: TFJM\n"
|
"Project-Id-Version: TFJM\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-07-06 21:27+0200\n"
|
"POT-Creation-Date: 2024-07-06 22:07+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
|
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -814,6 +814,67 @@ msgstr "Pb."
|
||||||
msgid "Room"
|
msgid "Room"
|
||||||
msgstr "Salle"
|
msgstr "Salle"
|
||||||
|
|
||||||
|
#: draw/templates/draw/tournament_content.html:310
|
||||||
|
#: draw/templates/draw/tournament_content.html:315
|
||||||
|
#: draw/templates/draw/tournament_content.html:320
|
||||||
|
#: draw/templates/draw/tournament_content.html:324
|
||||||
|
#: draw/templates/draw/tournament_content.html:330
|
||||||
|
#: draw/templates/draw/tournament_content.html:336
|
||||||
|
#: draw/templates/draw/tournament_content.html:342
|
||||||
|
#: draw/templates/draw/tournament_content.html:346
|
||||||
|
#: draw/templates/draw/tournament_content.html:353
|
||||||
|
#: draw/templates/draw/tournament_content.html:360
|
||||||
|
#: draw/templates/draw/tournament_content.html:367
|
||||||
|
#: draw/templates/draw/tournament_content.html:374
|
||||||
|
msgctxt "Role abbreviation"
|
||||||
|
msgid "Rep"
|
||||||
|
msgstr "Déf"
|
||||||
|
|
||||||
|
#: draw/templates/draw/tournament_content.html:311
|
||||||
|
#: draw/templates/draw/tournament_content.html:316
|
||||||
|
#: draw/templates/draw/tournament_content.html:318
|
||||||
|
#: draw/templates/draw/tournament_content.html:326
|
||||||
|
#: draw/templates/draw/tournament_content.html:332
|
||||||
|
#: draw/templates/draw/tournament_content.html:334
|
||||||
|
#: draw/templates/draw/tournament_content.html:340
|
||||||
|
#: draw/templates/draw/tournament_content.html:348
|
||||||
|
#: draw/templates/draw/tournament_content.html:355
|
||||||
|
#: draw/templates/draw/tournament_content.html:362
|
||||||
|
#: draw/templates/draw/tournament_content.html:364
|
||||||
|
#: draw/templates/draw/tournament_content.html:371
|
||||||
|
msgctxt "Role abbreviation"
|
||||||
|
msgid "Rev"
|
||||||
|
msgstr "Rap"
|
||||||
|
|
||||||
|
#: draw/templates/draw/tournament_content.html:312
|
||||||
|
#: draw/templates/draw/tournament_content.html:314
|
||||||
|
#: draw/templates/draw/tournament_content.html:319
|
||||||
|
#: draw/templates/draw/tournament_content.html:327
|
||||||
|
#: draw/templates/draw/tournament_content.html:329
|
||||||
|
#: draw/templates/draw/tournament_content.html:335
|
||||||
|
#: draw/templates/draw/tournament_content.html:341
|
||||||
|
#: draw/templates/draw/tournament_content.html:349
|
||||||
|
#: draw/templates/draw/tournament_content.html:356
|
||||||
|
#: draw/templates/draw/tournament_content.html:358
|
||||||
|
#: draw/templates/draw/tournament_content.html:365
|
||||||
|
#: draw/templates/draw/tournament_content.html:372
|
||||||
|
msgctxt "Role abbreviation"
|
||||||
|
msgid "Opp"
|
||||||
|
msgstr "Opp"
|
||||||
|
|
||||||
|
#: draw/templates/draw/tournament_content.html:325
|
||||||
|
#: draw/templates/draw/tournament_content.html:331
|
||||||
|
#: draw/templates/draw/tournament_content.html:337
|
||||||
|
#: draw/templates/draw/tournament_content.html:339
|
||||||
|
#: draw/templates/draw/tournament_content.html:350
|
||||||
|
#: draw/templates/draw/tournament_content.html:352
|
||||||
|
#: draw/templates/draw/tournament_content.html:359
|
||||||
|
#: draw/templates/draw/tournament_content.html:366
|
||||||
|
#: draw/templates/draw/tournament_content.html:373
|
||||||
|
msgctxt "Role abbreviation"
|
||||||
|
msgid "Obs"
|
||||||
|
msgstr "Obs"
|
||||||
|
|
||||||
#: draw/templates/draw/tournament_content.html:395
|
#: draw/templates/draw/tournament_content.html:395
|
||||||
#: draw/templates/draw/tournament_content.html:414
|
#: draw/templates/draw/tournament_content.html:414
|
||||||
msgid "Abort"
|
msgid "Abort"
|
||||||
|
@ -920,7 +981,7 @@ msgstr "sélectionnée pour la finale"
|
||||||
|
|
||||||
#: participation/admin.py:124 participation/admin.py:188
|
#: participation/admin.py:124 participation/admin.py:188
|
||||||
#: participation/models.py:1696 participation/tables.py:114
|
#: participation/models.py:1696 participation/tables.py:114
|
||||||
msgid "defender"
|
msgid "reporter"
|
||||||
msgstr "défenseur⋅se"
|
msgstr "défenseur⋅se"
|
||||||
|
|
||||||
#: participation/admin.py:128 participation/models.py:1703
|
#: participation/admin.py:128 participation/models.py:1703
|
||||||
|
@ -1027,12 +1088,12 @@ msgid "The following user was not found:"
|
||||||
msgstr "L'utilisateur⋅rice suivant n'a pas été trouvé :"
|
msgstr "L'utilisateur⋅rice suivant n'a pas été trouvé :"
|
||||||
|
|
||||||
#: participation/forms.py:350
|
#: participation/forms.py:350
|
||||||
msgid "The defender, the opponent and the reviewer must be different."
|
msgid "The reporter, the opponent and the reviewer must be different."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Les équipes défenseuse, opposante et rapportrice doivent être différent⋅es."
|
"Les équipes défenseuse, opposante et rapportrice doivent être différent⋅es."
|
||||||
|
|
||||||
#: participation/forms.py:354
|
#: participation/forms.py:354
|
||||||
msgid "This defender did not work on this problem."
|
msgid "This reporter did not work on this problem."
|
||||||
msgstr "Ce⋅tte défenseur⋅se ne travaille pas sur ce problème."
|
msgstr "Ce⋅tte défenseur⋅se ne travaille pas sur ce problème."
|
||||||
|
|
||||||
#: participation/forms.py:373
|
#: participation/forms.py:373
|
||||||
|
@ -1448,7 +1509,7 @@ msgstr "Tirage au sort des solutions"
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"<p>The solutions draw is ended. You can check the result on <a "
|
"<p>The solutions draw is ended. You can check the result on <a "
|
||||||
"href='{draw_url}'>this page</a>.</p><p>For the first round, you will defend "
|
"href='{draw_url}'>this page</a>.</p><p>For the first round, you will present "
|
||||||
"<a href='{solution_url}'>your solution of the problem {problem}</a>.</p>"
|
"<a href='{solution_url}'>your solution of the problem {problem}</a>.</p>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"<p>Le tirage au sort des solutions est terminé. Vous pouvez consulter les "
|
"<p>Le tirage au sort des solutions est terminé. Vous pouvez consulter les "
|
||||||
|
@ -1499,7 +1560,7 @@ msgstr "Premier tour"
|
||||||
#: participation/models.py:986
|
#: participation/models.py:986
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"<p>For the second round, you will defend <a href='{solution_url}'>your "
|
"<p>For the second round, you will present <a href='{solution_url}'>your "
|
||||||
"solution of the problem {problem}</a>.</p>"
|
"solution of the problem {problem}</a>.</p>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"<p>Pour le second tour, vous défendrez <a href='{solution_url}'>votre "
|
"<p>Pour le second tour, vous défendrez <a href='{solution_url}'>votre "
|
||||||
|
@ -1513,7 +1574,7 @@ msgstr "Second tour"
|
||||||
#: participation/models.py:1050
|
#: participation/models.py:1050
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"<p>For the third round, you will defend <a href='{solution_url}'>your "
|
"<p>For the third round, you will present <a href='{solution_url}'>your "
|
||||||
"solution of the problem {problem}</a>.</p>"
|
"solution of the problem {problem}</a>.</p>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"<p>Pour le troisième tour, vous défendrez <a href='{solution_url}'>votre "
|
"<p>Pour le troisième tour, vous défendrez <a href='{solution_url}'>votre "
|
||||||
|
@ -1638,7 +1699,7 @@ msgid "position"
|
||||||
msgstr "position"
|
msgstr "position"
|
||||||
|
|
||||||
#: participation/models.py:1687
|
#: participation/models.py:1687
|
||||||
msgid "defended solution"
|
msgid "reported solution"
|
||||||
msgstr "solution défendue"
|
msgstr "solution défendue"
|
||||||
|
|
||||||
#: participation/models.py:1725
|
#: participation/models.py:1725
|
||||||
|
@ -1647,7 +1708,7 @@ msgstr "pénalités"
|
||||||
|
|
||||||
#: participation/models.py:1727
|
#: participation/models.py:1727
|
||||||
msgid ""
|
msgid ""
|
||||||
"Number of penalties for the defender. The defender will loose a 0.5 "
|
"Number of penalties for the reporter. The reporter will loose a 0.5 "
|
||||||
"coefficient per penalty."
|
"coefficient per penalty."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Nombre de pénalités pour l'équipe défenseuse. Elle perd un coefficient 0.5 "
|
"Nombre de pénalités pour l'équipe défenseuse. Elle perd un coefficient 0.5 "
|
||||||
|
@ -1661,8 +1722,8 @@ msgstr "L'équipe {trigram} n'est pas inscrite dans la poule."
|
||||||
|
|
||||||
#: participation/models.py:1867
|
#: participation/models.py:1867
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Passage of {defender} for problem {problem}"
|
msgid "Passage of {reporter} for problem {problem}"
|
||||||
msgstr "Passage de {defender} pour le problème {problem}"
|
msgstr "Passage de {reporter} pour le problème {problem}"
|
||||||
|
|
||||||
#: participation/models.py:1871 participation/models.py:1880
|
#: participation/models.py:1871 participation/models.py:1880
|
||||||
#: participation/models.py:1969 participation/models.py:2012
|
#: participation/models.py:1969 participation/models.py:2012
|
||||||
|
@ -1716,10 +1777,10 @@ msgstr "solutions"
|
||||||
|
|
||||||
#: participation/models.py:1987
|
#: participation/models.py:1987
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Written review of {team} as {type} for problem {problem} of {defender}"
|
msgid "Written review of {team} as {type} for problem {problem} of {reporter}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Note de synthèse de l'équipe {team} en tant que {type} pour le problème "
|
"Note de synthèse de l'équipe {team} en tant que {type} pour le problème "
|
||||||
"{problem} de {defender}"
|
"{problem} de {reporter}"
|
||||||
|
|
||||||
#: participation/models.py:1995
|
#: participation/models.py:1995
|
||||||
msgid "written review"
|
msgid "written review"
|
||||||
|
@ -1734,11 +1795,11 @@ msgid "jury"
|
||||||
msgstr "jury"
|
msgstr "jury"
|
||||||
|
|
||||||
#: participation/models.py:2017
|
#: participation/models.py:2017
|
||||||
msgid "defender writing note"
|
msgid "reporter writing note"
|
||||||
msgstr "note d'écrit défenseur⋅se"
|
msgstr "note d'écrit défenseur⋅se"
|
||||||
|
|
||||||
#: participation/models.py:2023
|
#: participation/models.py:2023
|
||||||
msgid "defender oral note"
|
msgid "reporter oral note"
|
||||||
msgstr "note d'oral défenseur⋅se"
|
msgstr "note d'oral défenseur⋅se"
|
||||||
|
|
||||||
#: participation/models.py:2029
|
#: participation/models.py:2029
|
||||||
|
@ -1933,7 +1994,7 @@ msgid "Position:"
|
||||||
msgstr "Position :"
|
msgstr "Position :"
|
||||||
|
|
||||||
#: participation/templates/participation/passage_detail.html:28
|
#: participation/templates/participation/passage_detail.html:28
|
||||||
msgid "Defender:"
|
msgid "Reporter:"
|
||||||
msgstr "Défenseur⋅se :"
|
msgstr "Défenseur⋅se :"
|
||||||
|
|
||||||
#: participation/templates/participation/passage_detail.html:31
|
#: participation/templates/participation/passage_detail.html:31
|
||||||
|
@ -1949,11 +2010,11 @@ msgid "Observer:"
|
||||||
msgstr "Observateur⋅rice :"
|
msgstr "Observateur⋅rice :"
|
||||||
|
|
||||||
#: participation/templates/participation/passage_detail.html:42
|
#: participation/templates/participation/passage_detail.html:42
|
||||||
msgid "Defended solution:"
|
msgid "Reported solution:"
|
||||||
msgstr "Solution défendue"
|
msgstr "Solution défendue"
|
||||||
|
|
||||||
#: participation/templates/participation/passage_detail.html:45
|
#: participation/templates/participation/passage_detail.html:45
|
||||||
msgid "Defender penalties count:"
|
msgid "Reporter penalties count:"
|
||||||
msgstr "Nombre de pénalités :"
|
msgstr "Nombre de pénalités :"
|
||||||
|
|
||||||
#: participation/templates/participation/passage_detail.html:48
|
#: participation/templates/participation/passage_detail.html:48
|
||||||
|
@ -1981,11 +2042,11 @@ msgid "Notes detail"
|
||||||
msgstr "Détails des notes"
|
msgstr "Détails des notes"
|
||||||
|
|
||||||
#: participation/templates/participation/passage_detail.html:82
|
#: participation/templates/participation/passage_detail.html:82
|
||||||
msgid "Average points for the defender writing"
|
msgid "Average points for the reporter writing"
|
||||||
msgstr "Moyenne de l'écrit de l'équipe défenseuse"
|
msgstr "Moyenne de l'écrit de l'équipe défenseuse"
|
||||||
|
|
||||||
#: participation/templates/participation/passage_detail.html:90
|
#: participation/templates/participation/passage_detail.html:90
|
||||||
msgid "Average points for the defender oral"
|
msgid "Average points for the reporter oral"
|
||||||
msgstr "Moyenne de l'oral de l'équipe défenseuse"
|
msgstr "Moyenne de l'oral de l'équipe défenseuse"
|
||||||
|
|
||||||
#: participation/templates/participation/passage_detail.html:98
|
#: participation/templates/participation/passage_detail.html:98
|
||||||
|
@ -2013,7 +2074,7 @@ msgid "Average points for the observer oral"
|
||||||
msgstr "Moyenne de l'oral de l'équipe observatrice"
|
msgstr "Moyenne de l'oral de l'équipe observatrice"
|
||||||
|
|
||||||
#: participation/templates/participation/passage_detail.html:140
|
#: participation/templates/participation/passage_detail.html:140
|
||||||
msgid "Defender points"
|
msgid "Reporter points"
|
||||||
msgstr "Points de l'équipe défenseuse"
|
msgstr "Points de l'équipe défenseuse"
|
||||||
|
|
||||||
#: participation/templates/participation/passage_detail.html:148
|
#: participation/templates/participation/passage_detail.html:148
|
||||||
|
@ -2058,7 +2119,7 @@ msgid "Edit jury"
|
||||||
msgstr "Modifier le jury"
|
msgstr "Modifier le jury"
|
||||||
|
|
||||||
#: participation/templates/participation/pool_detail.html:49
|
#: participation/templates/participation/pool_detail.html:49
|
||||||
msgid "Defended solutions:"
|
msgid "Reported solutions:"
|
||||||
msgstr "Solutions défendues :"
|
msgstr "Solutions défendues :"
|
||||||
|
|
||||||
#: participation/templates/participation/pool_detail.html:55
|
#: participation/templates/participation/pool_detail.html:55
|
||||||
|
@ -2755,7 +2816,7 @@ msgid "Notes were successfully uploaded."
|
||||||
msgstr "Les notes ont bien été envoyées."
|
msgstr "Les notes ont bien été envoyées."
|
||||||
|
|
||||||
#: participation/views.py:1507
|
#: participation/views.py:1507
|
||||||
msgid "Defender"
|
msgid "Reporter"
|
||||||
msgstr "Défenseur⋅se"
|
msgstr "Défenseur⋅se"
|
||||||
|
|
||||||
#: participation/views.py:1513
|
#: participation/views.py:1513
|
||||||
|
|
|
@ -51,7 +51,7 @@ class PassageInline(admin.TabularInline):
|
||||||
model = Passage
|
model = Passage
|
||||||
extra = 0
|
extra = 0
|
||||||
ordering = ('position',)
|
ordering = ('position',)
|
||||||
autocomplete_fields = ('defender', 'opponent', 'reviewer', 'observer',)
|
autocomplete_fields = ('reporter', 'opponent', 'reviewer', 'observer',)
|
||||||
show_change_link = True
|
show_change_link = True
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,17 +113,17 @@ class PoolAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
@admin.register(Passage)
|
@admin.register(Passage)
|
||||||
class PassageAdmin(admin.ModelAdmin):
|
class PassageAdmin(admin.ModelAdmin):
|
||||||
list_display = ('__str__', 'defender_trigram', 'solution_number', 'opponent_trigram', 'reviewer_trigram',
|
list_display = ('__str__', 'reporter_trigram', 'solution_number', 'opponent_trigram', 'reviewer_trigram',
|
||||||
'observer_trigram', 'pool_abbr', 'position', 'tournament')
|
'observer_trigram', 'pool_abbr', 'position', 'tournament')
|
||||||
list_filter = ('pool__tournament', 'pool__round', 'pool__letter', 'solution_number',)
|
list_filter = ('pool__tournament', 'pool__round', 'pool__letter', 'solution_number',)
|
||||||
search_fields = ('pool__participations__team__name', 'pool__participations__team__trigram',)
|
search_fields = ('pool__participations__team__name', 'pool__participations__team__trigram',)
|
||||||
ordering = ('pool__tournament', 'pool__round', 'pool__letter', 'position',)
|
ordering = ('pool__tournament', 'pool__round', 'pool__letter', 'position',)
|
||||||
autocomplete_fields = ('pool', 'defender', 'opponent', 'reviewer', 'observer',)
|
autocomplete_fields = ('pool', 'reporter', 'opponent', 'reviewer', 'observer',)
|
||||||
inlines = (NoteInline,)
|
inlines = (NoteInline,)
|
||||||
|
|
||||||
@admin.display(description=_("defender"), ordering='defender__team__trigram')
|
@admin.display(description=_("reporter"), ordering='reporter__team__trigram')
|
||||||
def defender_trigram(self, record: Passage):
|
def reporter_trigram(self, record: Passage):
|
||||||
return record.defender.team.trigram
|
return record.reporter.team.trigram
|
||||||
|
|
||||||
@admin.display(description=_("opponent"), ordering='opponent__team__trigram')
|
@admin.display(description=_("opponent"), ordering='opponent__team__trigram')
|
||||||
def opponent_trigram(self, record: Passage):
|
def opponent_trigram(self, record: Passage):
|
||||||
|
@ -148,13 +148,13 @@ class PassageAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
@admin.register(Note)
|
@admin.register(Note)
|
||||||
class NoteAdmin(admin.ModelAdmin):
|
class NoteAdmin(admin.ModelAdmin):
|
||||||
list_display = ('passage', 'pool', 'jury', 'defender_writing', 'defender_oral',
|
list_display = ('passage', 'pool', 'jury', 'reporter_writing', 'reporter_oral',
|
||||||
'opponent_writing', 'opponent_oral', 'reviewer_writing', 'reviewer_oral',
|
'opponent_writing', 'opponent_oral', 'reviewer_writing', 'reviewer_oral',
|
||||||
'observer_writing', 'observer_oral',)
|
'observer_writing', 'observer_oral',)
|
||||||
list_filter = ('passage__pool__letter', 'passage__solution_number', 'jury',
|
list_filter = ('passage__pool__letter', 'passage__solution_number', 'jury',
|
||||||
'defender_writing', 'defender_oral', 'opponent_writing', 'opponent_oral',
|
'reporter_writing', 'reporter_oral', 'opponent_writing', 'opponent_oral',
|
||||||
'reviewer_writing', 'reviewer_oral', 'observer_writing', 'observer_oral')
|
'reviewer_writing', 'reviewer_oral', 'observer_writing', 'observer_oral')
|
||||||
search_fields = ('jury__user__last_name', 'jury__user__first_name', 'passage__defender__team__trigram',)
|
search_fields = ('jury__user__last_name', 'jury__user__first_name', 'passage__reporter__team__trigram',)
|
||||||
autocomplete_fields = ('jury', 'passage',)
|
autocomplete_fields = ('jury', 'passage',)
|
||||||
|
|
||||||
@admin.display(description=_("pool"))
|
@admin.display(description=_("pool"))
|
||||||
|
@ -180,14 +180,14 @@ class SolutionAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
@admin.register(WrittenReview)
|
@admin.register(WrittenReview)
|
||||||
class WrittenReviewAdmin(admin.ModelAdmin):
|
class WrittenReviewAdmin(admin.ModelAdmin):
|
||||||
list_display = ('participation', 'type', 'defender', 'passage',)
|
list_display = ('participation', 'type', 'reporter', 'passage',)
|
||||||
list_filter = ('participation__tournament', 'type', 'passage__solution_number',)
|
list_filter = ('participation__tournament', 'type', 'passage__solution_number',)
|
||||||
search_fields = ('participation__team__name', 'participation__team__trigram',)
|
search_fields = ('participation__team__name', 'participation__team__trigram',)
|
||||||
autocomplete_fields = ('participation', 'passage',)
|
autocomplete_fields = ('participation', 'passage',)
|
||||||
|
|
||||||
@admin.display(description=_("defender"))
|
@admin.display(description=_("reporter"))
|
||||||
def defender(self, record: WrittenReview):
|
def reporter(self, record: WrittenReview):
|
||||||
return record.passage.defender
|
return record.passage.reporter
|
||||||
|
|
||||||
@admin.display(description=_("problem"))
|
@admin.display(description=_("problem"))
|
||||||
def problem(self, record: WrittenReview):
|
def problem(self, record: WrittenReview):
|
||||||
|
|
|
@ -12,7 +12,7 @@ class NoteViewSet(ModelViewSet):
|
||||||
queryset = Note.objects.all()
|
queryset = Note.objects.all()
|
||||||
serializer_class = NoteSerializer
|
serializer_class = NoteSerializer
|
||||||
filter_backends = [DjangoFilterBackend]
|
filter_backends = [DjangoFilterBackend]
|
||||||
filterset_fields = ['jury', 'passage', 'defender_writing', 'defender_oral', 'opponent_writing',
|
filterset_fields = ['jury', 'passage', 'reporter_writing', 'reporter_oral', 'opponent_writing',
|
||||||
'opponent_oral', 'reviewer_writing', 'reviewer_oral', 'observer_writing', 'observer_oral', ]
|
'opponent_oral', 'reviewer_writing', 'reviewer_oral', 'observer_writing', 'observer_oral', ]
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ class PassageViewSet(ModelViewSet):
|
||||||
queryset = Passage.objects.all()
|
queryset = Passage.objects.all()
|
||||||
serializer_class = PassageSerializer
|
serializer_class = PassageSerializer
|
||||||
filter_backends = [DjangoFilterBackend]
|
filter_backends = [DjangoFilterBackend]
|
||||||
filterset_fields = ['pool', 'solution_number', 'defender', 'opponent', 'reviewer', 'observer', 'pool_tournament', ]
|
filterset_fields = ['pool', 'solution_number', 'reporter', 'opponent', 'reviewer', 'observer', 'pool_tournament', ]
|
||||||
|
|
||||||
|
|
||||||
class PoolViewSet(ModelViewSet):
|
class PoolViewSet(ModelViewSet):
|
||||||
|
|
|
@ -345,18 +345,18 @@ class UploadNotesForm(forms.Form):
|
||||||
class PassageForm(forms.ModelForm):
|
class PassageForm(forms.ModelForm):
|
||||||
def clean(self):
|
def clean(self):
|
||||||
cleaned_data = super().clean()
|
cleaned_data = super().clean()
|
||||||
if "defender" in cleaned_data and "opponent" in cleaned_data and "reviewer" in cleaned_data \
|
if "reporter" in cleaned_data and "opponent" in cleaned_data and "reviewer" in cleaned_data \
|
||||||
and len({cleaned_data["defender"], cleaned_data["opponent"], cleaned_data["reviewer"]}) < 3:
|
and len({cleaned_data["reporter"], cleaned_data["opponent"], cleaned_data["reviewer"]}) < 3:
|
||||||
self.add_error(None, _("The defender, the opponent and the reviewer must be different."))
|
self.add_error(None, _("The reporter, the opponent and the reviewer must be different."))
|
||||||
if "defender" in self.cleaned_data and "solution_number" in self.cleaned_data \
|
if "reporter" in self.cleaned_data and "solution_number" in self.cleaned_data \
|
||||||
and not Solution.objects.filter(participation=cleaned_data["defender"],
|
and not Solution.objects.filter(participation=cleaned_data["reporter"],
|
||||||
problem=cleaned_data["solution_number"]).exists():
|
problem=cleaned_data["solution_number"]).exists():
|
||||||
self.add_error("solution_number", _("This defender did not work on this problem."))
|
self.add_error("solution_number", _("This reporter did not work on this problem."))
|
||||||
return cleaned_data
|
return cleaned_data
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Passage
|
model = Passage
|
||||||
fields = ('position', 'solution_number', 'defender', 'opponent', 'reviewer', 'opponent', 'defender_penalties',)
|
fields = ('position', 'solution_number', 'reporter', 'opponent', 'reviewer', 'opponent', 'reporter_penalties',)
|
||||||
|
|
||||||
|
|
||||||
class WrittenReviewForm(forms.ModelForm):
|
class WrittenReviewForm(forms.ModelForm):
|
||||||
|
@ -386,5 +386,5 @@ class WrittenReviewForm(forms.ModelForm):
|
||||||
class NoteForm(forms.ModelForm):
|
class NoteForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Note
|
model = Note
|
||||||
fields = ('defender_writing', 'defender_oral', 'opponent_writing',
|
fields = ('reporter_writing', 'reporter_oral', 'opponent_writing',
|
||||||
'opponent_oral', 'reviewer_writing', 'reviewer_oral', 'observer_writing', 'observer_oral', )
|
'opponent_oral', 'reviewer_writing', 'reviewer_oral', 'observer_writing', 'observer_oral', )
|
||||||
|
|
|
@ -51,23 +51,23 @@ class Command(BaseCommand):
|
||||||
team3, score3 = sorted_notes[2]
|
team3, score3 = sorted_notes[2]
|
||||||
|
|
||||||
pool1 = tournament.pools.filter(round=1, participations=team2).first()
|
pool1 = tournament.pools.filter(round=1, participations=team2).first()
|
||||||
defender_passage_1 = Passage.objects.get(pool__tournament=tournament, pool__round=1, defender=team2)
|
reporter_passage_1 = Passage.objects.get(pool__tournament=tournament, pool__round=1, reporter=team2)
|
||||||
opponent_passage_1 = Passage.objects.get(pool__tournament=tournament, pool__round=1, opponent=team2)
|
opponent_passage_1 = Passage.objects.get(pool__tournament=tournament, pool__round=1, opponent=team2)
|
||||||
reviewer_passage_1 = Passage.objects.get(pool__tournament=tournament, pool__round=1, reviewer=team2)
|
reviewer_passage_1 = Passage.objects.get(pool__tournament=tournament, pool__round=1, reviewer=team2)
|
||||||
pool2 = tournament.pools.filter(round=2, participations=team2).first()
|
pool2 = tournament.pools.filter(round=2, participations=team2).first()
|
||||||
defender_passage_2 = Passage.objects.get(pool__tournament=tournament, pool__round=2, defender=team2)
|
reporter_passage_2 = Passage.objects.get(pool__tournament=tournament, pool__round=2, reporter=team2)
|
||||||
opponent_passage_2 = Passage.objects.get(pool__tournament=tournament, pool__round=2, opponent=team2)
|
opponent_passage_2 = Passage.objects.get(pool__tournament=tournament, pool__round=2, opponent=team2)
|
||||||
reviewer_passage_2 = Passage.objects.get(pool__tournament=tournament, pool__round=2, reviewer=team2)
|
reviewer_passage_2 = Passage.objects.get(pool__tournament=tournament, pool__round=2, reviewer=team2)
|
||||||
|
|
||||||
line.append(team2.team.trigram)
|
line.append(team2.team.trigram)
|
||||||
line.append(str(pool1.jury_president or ""))
|
line.append(str(pool1.jury_president or ""))
|
||||||
line.append(f"Pb. {defender_passage_1.solution_number}")
|
line.append(f"Pb. {reporter_passage_1.solution_number}")
|
||||||
line.extend([defender_passage_1.average_defender_writing, defender_passage_1.average_defender_oral,
|
line.extend([reporter_passage_1.average_reporter_writing, reporter_passage_1.average_reporter_oral,
|
||||||
opponent_passage_1.average_opponent_writing, opponent_passage_1.average_opponent_oral,
|
opponent_passage_1.average_opponent_writing, opponent_passage_1.average_opponent_oral,
|
||||||
reviewer_passage_1.average_reviewer_writing, reviewer_passage_1.average_reviewer_oral])
|
reviewer_passage_1.average_reviewer_writing, reviewer_passage_1.average_reviewer_oral])
|
||||||
line.append(str(pool2.jury_president or ""))
|
line.append(str(pool2.jury_president or ""))
|
||||||
line.append(f"Pb. {defender_passage_2.solution_number}")
|
line.append(f"Pb. {reporter_passage_2.solution_number}")
|
||||||
line.extend([defender_passage_2.average_defender_writing, defender_passage_2.average_defender_oral,
|
line.extend([reporter_passage_2.average_reporter_writing, reporter_passage_2.average_reporter_oral,
|
||||||
opponent_passage_2.average_opponent_writing, opponent_passage_2.average_opponent_oral,
|
opponent_passage_2.average_opponent_writing, opponent_passage_2.average_opponent_oral,
|
||||||
reviewer_passage_2.average_reviewer_writing, reviewer_passage_2.average_reviewer_oral])
|
reviewer_passage_2.average_reviewer_writing, reviewer_passage_2.average_reviewer_oral])
|
||||||
line.extend([score2, f"{score1:.1f} ({team1.team.trigram})",
|
line.extend([score2, f"{score1:.1f} ({team1.team.trigram})",
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
# Generated by Django 5.0.6 on 2024-07-06 20:00
|
||||||
|
import django
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("participation", "0020_rename_synthesis_writtenreview_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name="note",
|
||||||
|
old_name="defender_oral",
|
||||||
|
new_name="reporter_oral",
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name="note",
|
||||||
|
old_name="defender_writing",
|
||||||
|
new_name="reporter_writing",
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name="passage",
|
||||||
|
old_name="defender",
|
||||||
|
new_name="reporter",
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name="passage",
|
||||||
|
old_name="defender_penalties",
|
||||||
|
new_name="reporter_penalties",
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="passage",
|
||||||
|
name="solution_number",
|
||||||
|
field=models.PositiveSmallIntegerField(
|
||||||
|
choices=[
|
||||||
|
(1, "Problem #1"),
|
||||||
|
(2, "Problem #2"),
|
||||||
|
(3, "Problem #3"),
|
||||||
|
(4, "Problem #4"),
|
||||||
|
(5, "Problem #5"),
|
||||||
|
(6, "Problem #6"),
|
||||||
|
(7, "Problem #7"),
|
||||||
|
(8, "Problem #8"),
|
||||||
|
(9, "Problem #9"),
|
||||||
|
(10, "Problem #10"),
|
||||||
|
],
|
||||||
|
verbose_name="reported solution",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="note",
|
||||||
|
name="reporter_oral",
|
||||||
|
field=models.PositiveSmallIntegerField(
|
||||||
|
choices=[
|
||||||
|
(0, 0),
|
||||||
|
(1, 1),
|
||||||
|
(2, 2),
|
||||||
|
(3, 3),
|
||||||
|
(4, 4),
|
||||||
|
(5, 5),
|
||||||
|
(6, 6),
|
||||||
|
(7, 7),
|
||||||
|
(8, 8),
|
||||||
|
(9, 9),
|
||||||
|
(10, 10),
|
||||||
|
(11, 11),
|
||||||
|
(12, 12),
|
||||||
|
(13, 13),
|
||||||
|
(14, 14),
|
||||||
|
(15, 15),
|
||||||
|
(16, 16),
|
||||||
|
(17, 17),
|
||||||
|
(18, 18),
|
||||||
|
(19, 19),
|
||||||
|
(20, 20),
|
||||||
|
],
|
||||||
|
default=0,
|
||||||
|
verbose_name="reporter oral note",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="note",
|
||||||
|
name="reporter_writing",
|
||||||
|
field=models.PositiveSmallIntegerField(
|
||||||
|
choices=[
|
||||||
|
(0, 0),
|
||||||
|
(1, 1),
|
||||||
|
(2, 2),
|
||||||
|
(3, 3),
|
||||||
|
(4, 4),
|
||||||
|
(5, 5),
|
||||||
|
(6, 6),
|
||||||
|
(7, 7),
|
||||||
|
(8, 8),
|
||||||
|
(9, 9),
|
||||||
|
(10, 10),
|
||||||
|
(11, 11),
|
||||||
|
(12, 12),
|
||||||
|
(13, 13),
|
||||||
|
(14, 14),
|
||||||
|
(15, 15),
|
||||||
|
(16, 16),
|
||||||
|
(17, 17),
|
||||||
|
(18, 18),
|
||||||
|
(19, 19),
|
||||||
|
(20, 20),
|
||||||
|
],
|
||||||
|
default=0,
|
||||||
|
verbose_name="reporter writing note",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="passage",
|
||||||
|
name="reporter",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="+",
|
||||||
|
to="participation.participation",
|
||||||
|
verbose_name="reporter",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="passage",
|
||||||
|
name="reporter_penalties",
|
||||||
|
field=models.PositiveSmallIntegerField(
|
||||||
|
default=0,
|
||||||
|
help_text="Number of penalties for the reporter. The reporter will loose a 0.5 coefficient per penalty.",
|
||||||
|
verbose_name="penalties",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -490,7 +490,7 @@ class Tournament(models.Model):
|
||||||
line = [f"{participation.team.name} ({participation.team.trigram})"]
|
line = [f"{participation.team.name} ({participation.team.trigram})"]
|
||||||
lines.append(line)
|
lines.append(line)
|
||||||
|
|
||||||
passage1 = Passage.objects.get(pool__tournament=self, pool__round=1, defender=participation)
|
passage1 = Passage.objects.get(pool__tournament=self, pool__round=1, reporter=participation)
|
||||||
pool1 = passage1.pool
|
pool1 = passage1.pool
|
||||||
if pool1.participations.count() != 5:
|
if pool1.participations.count() != 5:
|
||||||
position1 = passage1.position
|
position1 = passage1.position
|
||||||
|
@ -502,8 +502,8 @@ class Tournament(models.Model):
|
||||||
line.append(f"=SIERREUR('{_('Pool')} {pool1.short_name}'!$D{pool1.juries.count() + 10 + position1}; 0)")
|
line.append(f"=SIERREUR('{_('Pool')} {pool1.short_name}'!$D{pool1.juries.count() + 10 + position1}; 0)")
|
||||||
line.append(tweak1.diff if tweak1 else 0)
|
line.append(tweak1.diff if tweak1 else 0)
|
||||||
|
|
||||||
if Passage.objects.filter(pool__tournament=self, pool__round=2, defender=participation).exists():
|
if Passage.objects.filter(pool__tournament=self, pool__round=2, reporter=participation).exists():
|
||||||
passage2 = Passage.objects.get(pool__tournament=self, pool__round=2, defender=participation)
|
passage2 = Passage.objects.get(pool__tournament=self, pool__round=2, reporter=participation)
|
||||||
pool2 = passage2.pool
|
pool2 = passage2.pool
|
||||||
if pool2.participations.count() != 5:
|
if pool2.participations.count() != 5:
|
||||||
position2 = passage2.position
|
position2 = passage2.position
|
||||||
|
@ -519,8 +519,8 @@ class Tournament(models.Model):
|
||||||
if settings.NB_ROUNDS >= 3:
|
if settings.NB_ROUNDS >= 3:
|
||||||
line.append(f"=$B{i + 2} + $C{i + 2} + $D{i + 2} + E{i + 2}")
|
line.append(f"=$B{i + 2} + $C{i + 2} + $D{i + 2} + E{i + 2}")
|
||||||
|
|
||||||
if Passage.objects.filter(pool__tournament=self, pool__round=3, defender=participation).exists():
|
if Passage.objects.filter(pool__tournament=self, pool__round=3, reporter=participation).exists():
|
||||||
passage3 = Passage.objects.get(pool__tournament=self, pool__round=3, defender=participation)
|
passage3 = Passage.objects.get(pool__tournament=self, pool__round=3, reporter=participation)
|
||||||
pool3 = passage3.pool
|
pool3 = passage3.pool
|
||||||
if pool3.participations.count() != 5:
|
if pool3.participations.count() != 5:
|
||||||
position3 = passage3.position
|
position3 = passage3.position
|
||||||
|
@ -912,36 +912,36 @@ class Participation(models.Model):
|
||||||
'content': content,
|
'content': content,
|
||||||
})
|
})
|
||||||
elif timezone.now() <= tournament.reviews_first_phase_limit + timedelta(hours=2):
|
elif timezone.now() <= tournament.reviews_first_phase_limit + timedelta(hours=2):
|
||||||
defender_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=1, defender=self)
|
reporter_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=1, reporter=self)
|
||||||
opponent_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=1, opponent=self)
|
opponent_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=1, opponent=self)
|
||||||
reviewer_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=1, reviewer=self)
|
reviewer_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=1, reviewer=self)
|
||||||
observer_passage = Passage.objects.filter(pool__tournament=self.tournament, pool__round=1, observer=self)
|
observer_passage = Passage.objects.filter(pool__tournament=self.tournament, pool__round=1, observer=self)
|
||||||
observer_passage = observer_passage.get() if observer_passage.exists() else None
|
observer_passage = observer_passage.get() if observer_passage.exists() else None
|
||||||
|
|
||||||
defender_text = _("<p>The solutions draw is ended. You can check the result on "
|
reporter_text = _("<p>The solutions draw is ended. You can check the result on "
|
||||||
"<a href='{draw_url}'>this page</a>.</p>"
|
"<a href='{draw_url}'>this page</a>.</p>"
|
||||||
"<p>For the first round, you will defend "
|
"<p>For the first round, you will present "
|
||||||
"<a href='{solution_url}'>your solution of the problem {problem}</a>.</p>")
|
"<a href='{solution_url}'>your solution of the problem {problem}</a>.</p>")
|
||||||
draw_url = reverse_lazy("draw:index")
|
draw_url = reverse_lazy("draw:index")
|
||||||
solution_url = defender_passage.defended_solution.file.url
|
solution_url = reporter_passage.reported_solution.file.url
|
||||||
defender_content = format_lazy(defender_text, draw_url=draw_url,
|
reporter_content = format_lazy(reporter_text, draw_url=draw_url,
|
||||||
solution_url=solution_url, problem=defender_passage.solution_number)
|
solution_url=solution_url, problem=reporter_passage.solution_number)
|
||||||
|
|
||||||
opponent_text = _("<p>You will oppose the solution of the team {opponent} on the "
|
opponent_text = _("<p>You will oppose the solution of the team {opponent} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = opponent_passage.defended_solution.file.url
|
solution_url = opponent_passage.reported_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(opponent_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(opponent_passage.pk,))
|
||||||
opponent_content = format_lazy(opponent_text, opponent=opponent_passage.defender.team.trigram,
|
opponent_content = format_lazy(opponent_text, opponent=opponent_passage.reporter.team.trigram,
|
||||||
solution_url=solution_url,
|
solution_url=solution_url,
|
||||||
problem=opponent_passage.solution_number, passage_url=passage_url)
|
problem=opponent_passage.solution_number, passage_url=passage_url)
|
||||||
|
|
||||||
reviewer_text = _("<p>You will report the solution of the team {reviewer} on the "
|
reviewer_text = _("<p>You will report the solution of the team {reviewer} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = reviewer_passage.defended_solution.file.url
|
solution_url = reviewer_passage.reported_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(reviewer_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(reviewer_passage.pk,))
|
||||||
reviewer_content = format_lazy(reviewer_text, reviewer=reviewer_passage.defender.team.trigram,
|
reviewer_content = format_lazy(reviewer_text, reviewer=reviewer_passage.reporter.team.trigram,
|
||||||
solution_url=solution_url,
|
solution_url=solution_url,
|
||||||
problem=reviewer_passage.solution_number, passage_url=passage_url)
|
problem=reviewer_passage.solution_number, passage_url=passage_url)
|
||||||
|
|
||||||
|
@ -949,10 +949,10 @@ class Participation(models.Model):
|
||||||
observer_text = _("<p>You will observe the solution of the team {observer} on the "
|
observer_text = _("<p>You will observe the solution of the team {observer} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = observer_passage.defended_solution.file.url
|
solution_url = observer_passage.reported_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(observer_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(observer_passage.pk,))
|
||||||
observer_content = format_lazy(observer_text,
|
observer_content = format_lazy(observer_text,
|
||||||
observer=observer_passage.defender.team.trigram,
|
observer=observer_passage.reporter.team.trigram,
|
||||||
solution_url=solution_url,
|
solution_url=solution_url,
|
||||||
problem=observer_passage.solution_number, passage_url=passage_url)
|
problem=observer_passage.solution_number, passage_url=passage_url)
|
||||||
else:
|
else:
|
||||||
|
@ -968,7 +968,7 @@ class Participation(models.Model):
|
||||||
for ext in ["pdf", "tex"])
|
for ext in ["pdf", "tex"])
|
||||||
reviews_templates_content = f"<p>{_('Templates:')} {reviews_templates}</p>"
|
reviews_templates_content = f"<p>{_('Templates:')} {reviews_templates}</p>"
|
||||||
|
|
||||||
content = defender_content + opponent_content + reviewer_content + observer_content \
|
content = reporter_content + opponent_content + reviewer_content + observer_content \
|
||||||
+ reviews_templates_content
|
+ reviews_templates_content
|
||||||
informations.append({
|
informations.append({
|
||||||
'title': _("First round"),
|
'title': _("First round"),
|
||||||
|
@ -977,34 +977,34 @@ class Participation(models.Model):
|
||||||
'content': content,
|
'content': content,
|
||||||
})
|
})
|
||||||
elif timezone.now() <= tournament.reviews_second_phase_limit + timedelta(hours=2):
|
elif timezone.now() <= tournament.reviews_second_phase_limit + timedelta(hours=2):
|
||||||
defender_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=2, defender=self)
|
reporter_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=2, reporter=self)
|
||||||
opponent_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=2, opponent=self)
|
opponent_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=2, opponent=self)
|
||||||
reviewer_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=2, reviewer=self)
|
reviewer_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=2, reviewer=self)
|
||||||
observer_passage = Passage.objects.filter(pool__tournament=self.tournament, pool__round=2, observer=self)
|
observer_passage = Passage.objects.filter(pool__tournament=self.tournament, pool__round=2, observer=self)
|
||||||
observer_passage = observer_passage.get() if observer_passage.exists() else None
|
observer_passage = observer_passage.get() if observer_passage.exists() else None
|
||||||
|
|
||||||
defender_text = _("<p>For the second round, you will defend "
|
reporter_text = _("<p>For the second round, you will present "
|
||||||
"<a href='{solution_url}'>your solution of the problem {problem}</a>.</p>")
|
"<a href='{solution_url}'>your solution of the problem {problem}</a>.</p>")
|
||||||
draw_url = reverse_lazy("draw:index")
|
draw_url = reverse_lazy("draw:index")
|
||||||
solution_url = defender_passage.defended_solution.file.url
|
solution_url = reporter_passage.reported_solution.file.url
|
||||||
defender_content = format_lazy(defender_text, draw_url=draw_url,
|
reporter_content = format_lazy(reporter_text, draw_url=draw_url,
|
||||||
solution_url=solution_url, problem=defender_passage.solution_number)
|
solution_url=solution_url, problem=reporter_passage.solution_number)
|
||||||
|
|
||||||
opponent_text = _("<p>You will oppose the solution of the team {opponent} on the "
|
opponent_text = _("<p>You will oppose the solution of the team {opponent} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = opponent_passage.defended_solution.file.url
|
solution_url = opponent_passage.reported_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(opponent_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(opponent_passage.pk,))
|
||||||
opponent_content = format_lazy(opponent_text, opponent=opponent_passage.defender.team.trigram,
|
opponent_content = format_lazy(opponent_text, opponent=opponent_passage.reporter.team.trigram,
|
||||||
solution_url=solution_url,
|
solution_url=solution_url,
|
||||||
problem=opponent_passage.solution_number, passage_url=passage_url)
|
problem=opponent_passage.solution_number, passage_url=passage_url)
|
||||||
|
|
||||||
reviewer_text = _("<p>You will report the solution of the team {reviewer} on the "
|
reviewer_text = _("<p>You will report the solution of the team {reviewer} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = reviewer_passage.defended_solution.file.url
|
solution_url = reviewer_passage.reported_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(reviewer_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(reviewer_passage.pk,))
|
||||||
reviewer_content = format_lazy(reviewer_text, reviewer=reviewer_passage.defender.team.trigram,
|
reviewer_content = format_lazy(reviewer_text, reviewer=reviewer_passage.reporter.team.trigram,
|
||||||
solution_url=solution_url,
|
solution_url=solution_url,
|
||||||
problem=reviewer_passage.solution_number, passage_url=passage_url)
|
problem=reviewer_passage.solution_number, passage_url=passage_url)
|
||||||
|
|
||||||
|
@ -1012,10 +1012,10 @@ class Participation(models.Model):
|
||||||
observer_text = _("<p>You will observe the solution of the team {observer} on the "
|
observer_text = _("<p>You will observe the solution of the team {observer} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = observer_passage.defended_solution.file.url
|
solution_url = observer_passage.reported_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(observer_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(observer_passage.pk,))
|
||||||
observer_content = format_lazy(observer_text,
|
observer_content = format_lazy(observer_text,
|
||||||
observer=observer_passage.defender.team.trigram,
|
observer=observer_passage.reporter.team.trigram,
|
||||||
solution_url=solution_url,
|
solution_url=solution_url,
|
||||||
problem=observer_passage.solution_number, passage_url=passage_url)
|
problem=observer_passage.solution_number, passage_url=passage_url)
|
||||||
else:
|
else:
|
||||||
|
@ -1031,7 +1031,7 @@ class Participation(models.Model):
|
||||||
for ext in ["pdf", "tex"])
|
for ext in ["pdf", "tex"])
|
||||||
reviews_templates_content = f"<p>{_('Templates:')} {reviews_templates}</p>"
|
reviews_templates_content = f"<p>{_('Templates:')} {reviews_templates}</p>"
|
||||||
|
|
||||||
content = defender_content + opponent_content + reviewer_content + observer_content \
|
content = reporter_content + opponent_content + reviewer_content + observer_content \
|
||||||
+ reviews_templates_content
|
+ reviews_templates_content
|
||||||
informations.append({
|
informations.append({
|
||||||
'title': _("Second round"),
|
'title': _("Second round"),
|
||||||
|
@ -1041,34 +1041,34 @@ class Participation(models.Model):
|
||||||
})
|
})
|
||||||
elif settings.TFJM_APP == "ETEAM" \
|
elif settings.TFJM_APP == "ETEAM" \
|
||||||
and timezone.now() <= tournament.reviews_third_phase_limit + timedelta(hours=2):
|
and timezone.now() <= tournament.reviews_third_phase_limit + timedelta(hours=2):
|
||||||
defender_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=3, defender=self)
|
reporter_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=3, reporter=self)
|
||||||
opponent_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=3, opponent=self)
|
opponent_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=3, opponent=self)
|
||||||
reviewer_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=3, reviewer=self)
|
reviewer_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=3, reviewer=self)
|
||||||
observer_passage = Passage.objects.filter(pool__tournament=self.tournament, pool__round=3, observer=self)
|
observer_passage = Passage.objects.filter(pool__tournament=self.tournament, pool__round=3, observer=self)
|
||||||
observer_passage = observer_passage.get() if observer_passage.exists() else None
|
observer_passage = observer_passage.get() if observer_passage.exists() else None
|
||||||
|
|
||||||
defender_text = _("<p>For the third round, you will defend "
|
reporter_text = _("<p>For the third round, you will present "
|
||||||
"<a href='{solution_url}'>your solution of the problem {problem}</a>.</p>")
|
"<a href='{solution_url}'>your solution of the problem {problem}</a>.</p>")
|
||||||
draw_url = reverse_lazy("draw:index")
|
draw_url = reverse_lazy("draw:index")
|
||||||
solution_url = defender_passage.defended_solution.file.url
|
solution_url = reporter_passage.reported_solution.file.url
|
||||||
defender_content = format_lazy(defender_text, draw_url=draw_url,
|
reporter_content = format_lazy(reporter_text, draw_url=draw_url,
|
||||||
solution_url=solution_url, problem=defender_passage.solution_number)
|
solution_url=solution_url, problem=reporter_passage.solution_number)
|
||||||
|
|
||||||
opponent_text = _("<p>You will oppose the solution of the team {opponent} on the "
|
opponent_text = _("<p>You will oppose the solution of the team {opponent} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = opponent_passage.defended_solution.file.url
|
solution_url = opponent_passage.reported_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(opponent_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(opponent_passage.pk,))
|
||||||
opponent_content = format_lazy(opponent_text, opponent=opponent_passage.defender.team.trigram,
|
opponent_content = format_lazy(opponent_text, opponent=opponent_passage.reporter.team.trigram,
|
||||||
solution_url=solution_url,
|
solution_url=solution_url,
|
||||||
problem=opponent_passage.solution_number, passage_url=passage_url)
|
problem=opponent_passage.solution_number, passage_url=passage_url)
|
||||||
|
|
||||||
reviewer_text = _("<p>You will report the solution of the team {reviewer} on the "
|
reviewer_text = _("<p>You will report the solution of the team {reviewer} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = reviewer_passage.defended_solution.file.url
|
solution_url = reviewer_passage.reported_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(reviewer_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(reviewer_passage.pk,))
|
||||||
reviewer_content = format_lazy(reviewer_text, reviewer=reviewer_passage.defender.team.trigram,
|
reviewer_content = format_lazy(reviewer_text, reviewer=reviewer_passage.reporter.team.trigram,
|
||||||
solution_url=solution_url,
|
solution_url=solution_url,
|
||||||
problem=reviewer_passage.solution_number, passage_url=passage_url)
|
problem=reviewer_passage.solution_number, passage_url=passage_url)
|
||||||
|
|
||||||
|
@ -1076,10 +1076,10 @@ class Participation(models.Model):
|
||||||
observer_text = _("<p>You will observe the solution of the team {observer} on the "
|
observer_text = _("<p>You will observe the solution of the team {observer} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = observer_passage.defended_solution.file.url
|
solution_url = observer_passage.reported_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(observer_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(observer_passage.pk,))
|
||||||
observer_content = format_lazy(observer_text,
|
observer_content = format_lazy(observer_text,
|
||||||
observer=observer_passage.defender.team.trigram,
|
observer=observer_passage.reporter.team.trigram,
|
||||||
solution_url=solution_url,
|
solution_url=solution_url,
|
||||||
problem=observer_passage.solution_number, passage_url=passage_url)
|
problem=observer_passage.solution_number, passage_url=passage_url)
|
||||||
else:
|
else:
|
||||||
|
@ -1095,7 +1095,7 @@ class Participation(models.Model):
|
||||||
for ext in ["pdf", "tex"])
|
for ext in ["pdf", "tex"])
|
||||||
reviews_templates_content = f"<p>{_('Templates:')} {reviews_templates}</p>"
|
reviews_templates_content = f"<p>{_('Templates:')} {reviews_templates}</p>"
|
||||||
|
|
||||||
content = defender_content + opponent_content + reviewer_content + observer_content \
|
content = reporter_content + opponent_content + reviewer_content + observer_content \
|
||||||
+ reviews_templates_content
|
+ reviews_templates_content
|
||||||
informations.append({
|
informations.append({
|
||||||
'title': _("Second round"),
|
'title': _("Second round"),
|
||||||
|
@ -1204,7 +1204,7 @@ class Pool(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def solutions(self):
|
def solutions(self):
|
||||||
return [passage.defended_solution for passage in self.passages.all()]
|
return [passage.reported_solution for passage in self.passages.all()]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def coeff(self):
|
def coeff(self):
|
||||||
|
@ -1251,7 +1251,7 @@ class Pool(models.Model):
|
||||||
header = [
|
header = [
|
||||||
sum(([str(_("Problem #{problem}").format(problem=passage.solution_number))] + (passage_width - 1) * [""]
|
sum(([str(_("Problem #{problem}").format(problem=passage.solution_number))] + (passage_width - 1) * [""]
|
||||||
for passage in passages), start=[str(_("Problem")), ""]),
|
for passage in passages), start=[str(_("Problem")), ""]),
|
||||||
sum(([f"{_('Defender')} ({passage.defender.team.trigram})", "",
|
sum(([f"{_('Reporter')} ({passage.reporter.team.trigram})", "",
|
||||||
f"{_('Opponent')} ({passage.opponent.team.trigram})", "",
|
f"{_('Opponent')} ({passage.opponent.team.trigram})", "",
|
||||||
f"{_('Reviewer')} ({passage.reviewer.team.trigram})", ""]
|
f"{_('Reviewer')} ({passage.reviewer.team.trigram})", ""]
|
||||||
+ ([f"{_('Observer')} ({passage.observer.team.trigram})", ""] if has_observer else [])
|
+ ([f"{_('Observer')} ({passage.observer.team.trigram})", ""] if has_observer else [])
|
||||||
|
@ -1268,7 +1268,7 @@ class Pool(models.Model):
|
||||||
line = [str(jury), jury.id]
|
line = [str(jury), jury.id]
|
||||||
for passage in passages:
|
for passage in passages:
|
||||||
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.reporter_writing, note.reporter_oral, note.opponent_writing, note.opponent_oral,
|
||||||
note.reviewer_writing, note.reviewer_oral])
|
note.reviewer_writing, note.reviewer_oral])
|
||||||
if has_observer:
|
if has_observer:
|
||||||
line.extend([note.observer_writing, note.observer_oral])
|
line.extend([note.observer_writing, note.observer_oral])
|
||||||
|
@ -1284,7 +1284,7 @@ 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 = [str(_("Average")), ""]
|
average = [str(_("Average")), ""]
|
||||||
coeffs = sum(([passage.coeff_defender_writing, passage.coeff_defender_oral,
|
coeffs = sum(([passage.coeff_reporter_writing, passage.coeff_reporter_oral,
|
||||||
passage.coeff_opponent_writing, passage.coeff_opponent_oral,
|
passage.coeff_opponent_writing, passage.coeff_opponent_oral,
|
||||||
passage.coeff_reviewer_writing, passage.coeff_reviewer_oral]
|
passage.coeff_reviewer_writing, passage.coeff_reviewer_oral]
|
||||||
+ ([passage.coeff_observer_writing, passage.coeff_observer_oral] if has_observer else [])
|
+ ([passage.coeff_observer_writing, passage.coeff_observer_oral] if has_observer else [])
|
||||||
|
@ -1330,11 +1330,11 @@ class Pool(models.Model):
|
||||||
pool__round=self.round,
|
pool__round=self.round,
|
||||||
pool__letter=self.letter).order_by('position', 'pool__room')
|
pool__letter=self.letter).order_by('position', 'pool__room')
|
||||||
for i, passage in enumerate(all_passages):
|
for i, passage in enumerate(all_passages):
|
||||||
participation = passage.defender
|
participation = passage.reporter
|
||||||
defender_passage = Passage.objects.get(defender=participation,
|
reporter_passage = Passage.objects.get(reporter=participation,
|
||||||
pool__tournament=self.tournament, pool__round=self.round)
|
pool__tournament=self.tournament, pool__round=self.round)
|
||||||
defender_row = 5 + defender_passage.pool.juries.count()
|
reporter_row = 5 + reporter_passage.pool.juries.count()
|
||||||
defender_col = defender_passage.position - 1
|
reporter_col = reporter_passage.position - 1
|
||||||
|
|
||||||
opponent_passage = Passage.objects.get(opponent=participation,
|
opponent_passage = Passage.objects.get(opponent=participation,
|
||||||
pool__tournament=self.tournament, pool__round=self.round)
|
pool__tournament=self.tournament, pool__round=self.round)
|
||||||
|
@ -1347,8 +1347,8 @@ class Pool(models.Model):
|
||||||
reviewer_col = reviewer_passage.position - 1
|
reviewer_col = reviewer_passage.position - 1
|
||||||
|
|
||||||
formula = "="
|
formula = "="
|
||||||
formula += (f"'{_('Pool')} {defender_passage.pool.short_name}'"
|
formula += (f"'{_('Pool')} {reporter_passage.pool.short_name}'"
|
||||||
f"!{getcol(min_column + defender_col * passage_width)}{defender_row + 3}") # Defender
|
f"!{getcol(min_column + reporter_col * passage_width)}{reporter_row + 3}") # Reporter
|
||||||
formula += (f" + '{_('Pool')} {opponent_passage.pool.short_name}'"
|
formula += (f" + '{_('Pool')} {opponent_passage.pool.short_name}'"
|
||||||
f"!{getcol(min_column + opponent_col * passage_width + 2)}{opponent_row + 3}") # Opponent
|
f"!{getcol(min_column + opponent_col * passage_width + 2)}{opponent_row + 3}") # Opponent
|
||||||
formula += (f" + '{_('Pool')} {reviewer_passage.pool.short_name}'"
|
formula += (f" + '{_('Pool')} {reviewer_passage.pool.short_name}'"
|
||||||
|
@ -1362,8 +1362,8 @@ class Pool(models.Model):
|
||||||
f"!{getcol(min_column + observer_col * passage_width + 6)}{observer_row + 3}")
|
f"!{getcol(min_column + observer_col * passage_width + 6)}{observer_row + 3}")
|
||||||
|
|
||||||
ranking.append([f"{participation.team.name} ({participation.team.trigram})", "",
|
ranking.append([f"{participation.team.name} ({participation.team.trigram})", "",
|
||||||
f"='{_('Pool')} {defender_passage.pool.short_name}'"
|
f"='{_('Pool')} {reporter_passage.pool.short_name}'"
|
||||||
f"!${getcol(3 + defender_col * passage_width)}$1",
|
f"!${getcol(3 + reporter_col * passage_width)}$1",
|
||||||
formula,
|
formula,
|
||||||
f"=RANG(D{max_row + 6 + i}; "
|
f"=RANG(D{max_row + 6 + i}; "
|
||||||
f"D${max_row + 6}:D${max_row + 5 + pool_size})"])
|
f"D${max_row + 6}:D${max_row + 5 + pool_size})"])
|
||||||
|
@ -1430,7 +1430,7 @@ class Pool(models.Model):
|
||||||
(f"A{max_row + 6}:E{max_row + 5 + pool_size}", (0.9, 0.9, 0.9)),]
|
(f"A{max_row + 6}:E{max_row + 5 + pool_size}", (0.9, 0.9, 0.9)),]
|
||||||
# Display penalties in red
|
# Display penalties in red
|
||||||
bg_colors += [(f"{getcol(2 + (passage.position - 1) * passage_width + 2)}{max_row + 2}", (1.0, 0.7, 0.7))
|
bg_colors += [(f"{getcol(2 + (passage.position - 1) * passage_width + 2)}{max_row + 2}", (1.0, 0.7, 0.7))
|
||||||
for passage in self.passages.filter(defender_penalties__gte=1).all()]
|
for passage in self.passages.filter(reporter_penalties__gte=1).all()]
|
||||||
for bg_range, bg_color in bg_colors:
|
for bg_range, bg_color in bg_colors:
|
||||||
r, g, b = bg_color
|
r, g, b = bg_color
|
||||||
format_requests.append({
|
format_requests.append({
|
||||||
|
@ -1684,16 +1684,16 @@ class Passage(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
solution_number = models.PositiveSmallIntegerField(
|
solution_number = models.PositiveSmallIntegerField(
|
||||||
verbose_name=_("defended solution"),
|
verbose_name=_("reported solution"),
|
||||||
choices=[
|
choices=[
|
||||||
(i, format_lazy(_("Problem #{problem}"), problem=i)) for i in range(1, len(settings.PROBLEMS) + 1)
|
(i, format_lazy(_("Problem #{problem}"), problem=i)) for i in range(1, len(settings.PROBLEMS) + 1)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
defender = models.ForeignKey(
|
reporter = models.ForeignKey(
|
||||||
Participation,
|
Participation,
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
verbose_name=_("defender"),
|
verbose_name=_("reporter"),
|
||||||
related_name="+",
|
related_name="+",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1721,17 +1721,17 @@ class Passage(models.Model):
|
||||||
default=None,
|
default=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
defender_penalties = models.PositiveSmallIntegerField(
|
reporter_penalties = models.PositiveSmallIntegerField(
|
||||||
verbose_name=_("penalties"),
|
verbose_name=_("penalties"),
|
||||||
default=0,
|
default=0,
|
||||||
help_text=_("Number of penalties for the defender. "
|
help_text=_("Number of penalties for the reporter. "
|
||||||
"The defender will loose a 0.5 coefficient per penalty."),
|
"The reporter will loose a 0.5 coefficient per penalty."),
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def defended_solution(self) -> "Solution":
|
def reported_solution(self) -> "Solution":
|
||||||
return Solution.objects.get(
|
return Solution.objects.get(
|
||||||
participation=self.defender,
|
participation=self.reporter,
|
||||||
problem=self.solution_number,
|
problem=self.solution_number,
|
||||||
final_solution=self.pool.tournament.final)
|
final_solution=self.pool.tournament.final)
|
||||||
|
|
||||||
|
@ -1740,27 +1740,27 @@ class Passage(models.Model):
|
||||||
return sum(items) / len(items) if items else 0
|
return sum(items) / len(items) if items else 0
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def average_defender_writing(self) -> float:
|
def average_reporter_writing(self) -> float:
|
||||||
return self.avg(note.defender_writing for note in self.notes.all())
|
return self.avg(note.reporter_writing for note in self.notes.all())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def coeff_defender_writing(self) -> float:
|
def coeff_reporter_writing(self) -> float:
|
||||||
return 1 if settings.TFJM_APP == "TFJM" else 2
|
return 1 if settings.TFJM_APP == "TFJM" else 2
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def average_defender_oral(self) -> float:
|
def average_reporter_oral(self) -> float:
|
||||||
return self.avg(note.defender_oral for note in self.notes.all())
|
return self.avg(note.reporter_oral for note in self.notes.all())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def coeff_defender_oral(self) -> float:
|
def coeff_reporter_oral(self) -> float:
|
||||||
coeff = 1.6 if settings.TFJM_APP == "TFJM" else 3
|
coeff = 1.6 if settings.TFJM_APP == "TFJM" else 3
|
||||||
coeff *= 1 - 0.25 * self.defender_penalties
|
coeff *= 1 - 0.25 * self.reporter_penalties
|
||||||
return coeff
|
return coeff
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def average_defender(self) -> float:
|
def average_reporter(self) -> float:
|
||||||
return (self.coeff_defender_writing * self.average_defender_writing
|
return (self.coeff_reporter_writing * self.average_reporter_writing
|
||||||
+ self.coeff_defender_oral * self.average_defender_oral)
|
+ self.coeff_reporter_oral * self.average_reporter_oral)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def average_opponent_writing(self) -> float:
|
def average_opponent_writing(self) -> float:
|
||||||
|
@ -1827,8 +1827,8 @@ class Passage(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def averages(self):
|
def averages(self):
|
||||||
yield self.average_defender_writing
|
yield self.average_reporter_writing
|
||||||
yield self.average_defender_oral
|
yield self.average_reporter_oral
|
||||||
yield self.average_opponent_writing
|
yield self.average_opponent_writing
|
||||||
yield self.average_opponent_oral
|
yield self.average_opponent_oral
|
||||||
yield self.average_reviewer_writing
|
yield self.average_reviewer_writing
|
||||||
|
@ -1838,7 +1838,7 @@ class Passage(models.Model):
|
||||||
yield self.average_observer_oral
|
yield self.average_observer_oral
|
||||||
|
|
||||||
def average(self, participation):
|
def average(self, participation):
|
||||||
avg = self.average_defender if participation == self.defender else self.average_opponent \
|
avg = self.average_reporter if participation == self.reporter else self.average_opponent \
|
||||||
if participation == self.opponent else self.average_reviewer if participation == self.reviewer \
|
if participation == self.opponent else self.average_reviewer if participation == self.reviewer \
|
||||||
else self.average_observer if participation == self.observer else 0
|
else self.average_observer if participation == self.observer else 0
|
||||||
avg *= self.pool.coeff
|
avg *= self.pool.coeff
|
||||||
|
@ -1849,9 +1849,9 @@ class Passage(models.Model):
|
||||||
return reverse_lazy("participation:passage_detail", args=(self.pk,))
|
return reverse_lazy("participation:passage_detail", args=(self.pk,))
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
if self.defender 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.defender.team.trigram))
|
.format(trigram=self.reporter.team.trigram))
|
||||||
if self.opponent not in self.pool.participations.all():
|
if self.opponent 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.opponent.team.trigram))
|
.format(trigram=self.opponent.team.trigram))
|
||||||
|
@ -1864,8 +1864,8 @@ class Passage(models.Model):
|
||||||
return super().clean()
|
return super().clean()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return _("Passage of {defender} for problem {problem}")\
|
return _("Passage of {reporter} for problem {problem}")\
|
||||||
.format(defender=self.defender.team, problem=self.solution_number)
|
.format(reporter=self.reporter.team, problem=self.solution_number)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("passage")
|
verbose_name = _("passage")
|
||||||
|
@ -1984,11 +1984,11 @@ class WrittenReview(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return _("Written review of {team} as {type} for problem {problem} of {defender}").format(
|
return _("Written review of {team} as {type} for problem {problem} of {reporter}").format(
|
||||||
team=self.participation.team.trigram,
|
team=self.participation.team.trigram,
|
||||||
type=self.get_type_display(),
|
type=self.get_type_display(),
|
||||||
problem=self.passage.solution_number,
|
problem=self.passage.solution_number,
|
||||||
defender=self.passage.defender.team.trigram,
|
reporter=self.passage.reporter.team.trigram,
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -2013,14 +2013,14 @@ class Note(models.Model):
|
||||||
related_name="notes",
|
related_name="notes",
|
||||||
)
|
)
|
||||||
|
|
||||||
defender_writing = models.PositiveSmallIntegerField(
|
reporter_writing = models.PositiveSmallIntegerField(
|
||||||
verbose_name=_("defender writing note"),
|
verbose_name=_("reporter writing note"),
|
||||||
choices=[(i, i) for i in range(0, 21)],
|
choices=[(i, i) for i in range(0, 21)],
|
||||||
default=0,
|
default=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
defender_oral = models.PositiveSmallIntegerField(
|
reporter_oral = models.PositiveSmallIntegerField(
|
||||||
verbose_name=_("defender oral note"),
|
verbose_name=_("reporter oral note"),
|
||||||
choices=[(i, i) for i in range(0, 21)],
|
choices=[(i, i) for i in range(0, 21)],
|
||||||
default=0,
|
default=0,
|
||||||
)
|
)
|
||||||
|
@ -2062,8 +2062,8 @@ class Note(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_all(self):
|
def get_all(self):
|
||||||
yield self.defender_writing
|
yield self.reporter_writing
|
||||||
yield self.defender_oral
|
yield self.reporter_oral
|
||||||
yield self.opponent_writing
|
yield self.opponent_writing
|
||||||
yield self.opponent_oral
|
yield self.opponent_oral
|
||||||
yield self.reviewer_writing
|
yield self.reviewer_writing
|
||||||
|
@ -2072,10 +2072,10 @@ class Note(models.Model):
|
||||||
yield self.observer_writing
|
yield self.observer_writing
|
||||||
yield self.observer_oral
|
yield self.observer_oral
|
||||||
|
|
||||||
def set_all(self, defender_writing: int, defender_oral: int, opponent_writing: int, opponent_oral: int,
|
def set_all(self, reporter_writing: int, reporter_oral: int, opponent_writing: int, opponent_oral: int,
|
||||||
reviewer_writing: int, reviewer_oral: int, observer_writing: int = 0, observer_oral: int = 0):
|
reviewer_writing: int, reviewer_oral: int, observer_writing: int = 0, observer_oral: int = 0):
|
||||||
self.defender_writing = defender_writing
|
self.reporter_writing = reporter_writing
|
||||||
self.defender_oral = defender_oral
|
self.reporter_oral = reporter_oral
|
||||||
self.opponent_writing = opponent_writing
|
self.opponent_writing = opponent_writing
|
||||||
self.opponent_oral = opponent_oral
|
self.opponent_oral = opponent_oral
|
||||||
self.reviewer_writing = reviewer_writing
|
self.reviewer_writing = reviewer_writing
|
||||||
|
|
|
@ -108,13 +108,13 @@ class PoolTable(tables.Table):
|
||||||
class PassageTable(tables.Table):
|
class PassageTable(tables.Table):
|
||||||
# FIXME Ne pas afficher l'équipe observatrice si non nécessaire
|
# FIXME Ne pas afficher l'équipe observatrice si non nécessaire
|
||||||
|
|
||||||
defender = tables.LinkColumn(
|
reporter = tables.LinkColumn(
|
||||||
"participation:passage_detail",
|
"participation:passage_detail",
|
||||||
args=[tables.A("id")],
|
args=[tables.A("id")],
|
||||||
verbose_name=_("defender").capitalize,
|
verbose_name=_("reporter").capitalize,
|
||||||
)
|
)
|
||||||
|
|
||||||
def render_defender(self, value):
|
def render_reporter(self, value):
|
||||||
return value.team.trigram
|
return value.team.trigram
|
||||||
|
|
||||||
def render_opponent(self, value):
|
def render_opponent(self, value):
|
||||||
|
@ -131,7 +131,7 @@ class PassageTable(tables.Table):
|
||||||
'class': 'table table-condensed table-striped text-center',
|
'class': 'table table-condensed table-striped text-center',
|
||||||
}
|
}
|
||||||
model = Passage
|
model = Passage
|
||||||
fields = ('defender', 'opponent', 'reviewer', 'observer', 'solution_number', )
|
fields = ('reporter', 'opponent', 'reviewer', 'observer', 'solution_number', )
|
||||||
|
|
||||||
|
|
||||||
class NoteTable(tables.Table):
|
class NoteTable(tables.Table):
|
||||||
|
@ -159,5 +159,5 @@ class NoteTable(tables.Table):
|
||||||
'class': 'table table-condensed table-striped text-center',
|
'class': 'table table-condensed table-striped text-center',
|
||||||
}
|
}
|
||||||
model = Note
|
model = Note
|
||||||
fields = ('jury', 'defender_writing', 'defender_oral', 'opponent_writing', 'opponent_oral',
|
fields = ('jury', 'reporter_writing', 'reporter_oral', 'opponent_writing', 'opponent_oral',
|
||||||
'reviewer_writing', 'reviewer_oral', 'observer_writing', 'observer_oral', 'update',)
|
'reviewer_writing', 'reviewer_oral', 'observer_writing', 'observer_oral', 'update',)
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<div id="form-content">
|
<div id="form-content">
|
||||||
<h4>{% trans "Notes of" %} {{ note.jury }}</h4>
|
<h4>{% trans "Notes of" %} {{ note.jury }}</h4>
|
||||||
<h5>{% trans "Defense of" %} {{ note.passage.defender.team.trigram }}, {% trans "Pb." %} {{ note.passage.solution_number }}</h5>
|
<h5>{% trans "Defense of" %} {{ note.passage.reporter.team.trigram }}, {% trans "Pb." %} {{ note.passage.solution_number }}</h5>
|
||||||
<hr>
|
<hr>
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form|crispy }}
|
{{ form|crispy }}
|
||||||
|
|
|
@ -25,8 +25,8 @@
|
||||||
<dt class="col-sm-3">{% trans "Position:" %}</dt>
|
<dt class="col-sm-3">{% trans "Position:" %}</dt>
|
||||||
<dd class="col-sm-9">{{ passage.position }}</dd>
|
<dd class="col-sm-9">{{ passage.position }}</dd>
|
||||||
|
|
||||||
<dt class="col-sm-3">{% trans "Defender:" %}</dt>
|
<dt class="col-sm-3">{% trans "Reporter:" %}</dt>
|
||||||
<dd class="col-sm-9"><a href="{{ passage.defender.get_absolute_url }}">{{ passage.defender.team }}</a></dd>
|
<dd class="col-sm-9"><a href="{{ passage.reporter.get_absolute_url }}">{{ passage.reporter.team }}</a></dd>
|
||||||
|
|
||||||
<dt class="col-sm-3">{% trans "Opponent:" %}</dt>
|
<dt class="col-sm-3">{% trans "Opponent:" %}</dt>
|
||||||
<dd class="col-sm-9"><a href="{{ passage.opponent.get_absolute_url }}">{{ passage.opponent.team }}</a></dd>
|
<dd class="col-sm-9"><a href="{{ passage.opponent.get_absolute_url }}">{{ passage.opponent.team }}</a></dd>
|
||||||
|
@ -39,11 +39,11 @@
|
||||||
<dd class="col-sm-9"><a href="{{ passage.observer.get_absolute_url }}">{{ passage.observer.team }}</a></dd>
|
<dd class="col-sm-9"><a href="{{ passage.observer.get_absolute_url }}">{{ passage.observer.team }}</a></dd>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<dt class="col-sm-3">{% trans "Defended solution:" %}</dt>
|
<dt class="col-sm-3">{% trans "Reported 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.reported_solution.file.url }}">{{ passage.reported_solution }}</a></dd>
|
||||||
|
|
||||||
<dt class="col-sm-3">{% trans "Defender penalties count:" %}</dt>
|
<dt class="col-sm-3">{% trans "Reporter penalties count:" %}</dt>
|
||||||
<dd class="col-sm-9">{{ passage.defender_penalties }}</dd>
|
<dd class="col-sm-9">{{ passage.reporter_penalties }}</dd>
|
||||||
|
|
||||||
<dt class="col-sm-3">{% trans "Syntheses:" %}</dt>
|
<dt class="col-sm-3">{% trans "Syntheses:" %}</dt>
|
||||||
<dd class="col-sm-9">
|
<dd class="col-sm-9">
|
||||||
|
@ -79,19 +79,19 @@
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<dl class="row">
|
<dl class="row">
|
||||||
<dt class="col-sm-8">
|
<dt class="col-sm-8">
|
||||||
{% trans "Average points for the defender writing" %}
|
{% trans "Average points for the reporter writing" %}
|
||||||
({{ passage.defender.team.trigram }}) :
|
({{ passage.reporter.team.trigram }}) :
|
||||||
</dt>
|
</dt>
|
||||||
<dd class="col-sm-4">
|
<dd class="col-sm-4">
|
||||||
{{ passage.average_defender_writing|floatformat }}/{% if TFJM_APP == "TFJM" %}20{% else %}10{% endif %}
|
{{ passage.average_reporter_writing|floatformat }}/{% if TFJM_APP == "TFJM" %}20{% else %}10{% endif %}
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
<dt class="col-sm-8">
|
<dt class="col-sm-8">
|
||||||
{% trans "Average points for the defender oral" %}
|
{% trans "Average points for the reporter oral" %}
|
||||||
({{ passage.defender.team.trigram }}) :
|
({{ passage.reporter.team.trigram }}) :
|
||||||
</dt>
|
</dt>
|
||||||
<dd class="col-sm-4">
|
<dd class="col-sm-4">
|
||||||
{{ passage.average_defender_oral|floatformat }}/{% if TFJM_APP == "TFJM" %}20{% else %}10{% endif %}
|
{{ passage.average_reporter_oral|floatformat }}/{% if TFJM_APP == "TFJM" %}20{% else %}10{% endif %}
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
<dt class="col-sm-8">
|
<dt class="col-sm-8">
|
||||||
|
@ -137,11 +137,11 @@
|
||||||
|
|
||||||
<dl class="row">
|
<dl class="row">
|
||||||
<dt class="col-sm-8">
|
<dt class="col-sm-8">
|
||||||
{% trans "Defender points" %}
|
{% trans "Reporter points" %}
|
||||||
({{ passage.defender.team.trigram }}) :
|
({{ passage.reporter.team.trigram }}) :
|
||||||
</dt>
|
</dt>
|
||||||
<dd class="col-sm-4">
|
<dd class="col-sm-4">
|
||||||
{{ passage.average_defender|floatformat }}/{% if TFJM_APP == "TFJM" %}52{% else %}50{% endif %}
|
{{ passage.average_reporter|floatformat }}/{% if TFJM_APP == "TFJM" %}52{% else %}50{% endif %}
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
<dt class="col-sm-8">
|
<dt class="col-sm-8">
|
||||||
|
|
|
@ -46,10 +46,10 @@
|
||||||
</a>
|
</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
<dt class="col-sm-3">{% trans "Defended solutions:" %}</dt>
|
<dt class="col-sm-3">{% trans "Reported solutions:" %}</dt>
|
||||||
<dd class="col-sm-9">
|
<dd class="col-sm-9">
|
||||||
{% for passage in pool.passages.all %}
|
{% for passage in pool.passages.all %}
|
||||||
<a href="{{ passage.defended_solution.file.url }}">{{ passage.defender.team.trigram }} — {{ passage.get_solution_number_display }}</a>{% if not forloop.last %}, {% endif %}
|
<a href="{{ passage.reported_solution.file.url }}">{{ passage.reporter.team.trigram }} — {{ passage.get_solution_number_display }}</a>{% if not forloop.last %}, {% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<a href="{% url 'participation:pool_download_solutions' pool_id=pool.id %}" class="badge rounded-pill text-bg-secondary">
|
<a href="{% url 'participation:pool_download_solutions' pool_id=pool.id %}" class="badge rounded-pill text-bg-secondary">
|
||||||
<i class="fas fa-download"></i> {% trans "Download all" %}
|
<i class="fas fa-download"></i> {% trans "Download all" %}
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
<ul class="list-group list-group-flush">
|
<ul class="list-group list-group-flush">
|
||||||
{% for passage in pool.passages.all %}
|
{% for passage in pool.passages.all %}
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
{{ passage.defender.team.trigram }} — {{ passage.get_solution_number_display }} :
|
{{ passage.reporter.team.trigram }} — {{ passage.get_solution_number_display }} :
|
||||||
{% for review in passage.written_reviews.all %}
|
{% for review in passage.written_reviews.all %}
|
||||||
<a href="{{ review.file.url }}">{{ review.participation.team.trigram }} ({{ review.get_type_display }})</a>{% if not forloop.last %}, {% endif %}
|
<a href="{{ review.file.url }}">{{ review.participation.team.trigram }} ({{ review.get_type_display }})</a>{% if not forloop.last %}, {% endif %}
|
||||||
{% empty %}
|
{% empty %}
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
<a href="{% url 'participation:pool_download_written_review' pool_id=pool.id %}" class="badge rounded-pill text-bg-secondary">
|
<a href="{% url 'participation:pool_download_written_reviews' pool_id=pool.id %}" class="badge rounded-pill text-bg-secondary">
|
||||||
<i class="fas fa-download"></i> {% trans "Download all" %}
|
<i class="fas fa-download"></i> {% trans "Download all" %}
|
||||||
</a>
|
</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
{% for passage in passages.all %}
|
{% for passage in passages.all %}
|
||||||
\item D\'efenseur\textperiodcentered{}se au passage {{ forloop.counter }} : \underline{\texttt{~{{ passage.defender.team.trigram }}~}} $\qquad$ probl\`eme \underline{~{{ passage.solution_number }}~}
|
\item D\'efenseur\textperiodcentered{}se au passage {{ forloop.counter }} : \underline{\texttt{~{{ passage.reporter.team.trigram }}~}} $\qquad$ probl\`eme \underline{~{{ passage.solution_number }}~}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%DEFENSEUR
|
%%%%%%%%%%%%%%%%%%%%%DEFENSEUR
|
||||||
\begin{tabular}{|c|p{24mm}|p{11cm}|c|{% for passage in passages.all %}p{2cm}|{% endfor %}}\hline
|
\begin{tabular}{|c|p{24mm}|p{11cm}|c|{% for passage in passages.all %}p{2cm}|{% endfor %}}\hline
|
||||||
\multicolumn{4}{|l|}{Læ {\bf D\'efenseur\textperiodcentered{}se} \normalsize pr\'esente les id\'ees et r\'esultats principaux pour la solution du probl\`eme.} {% for passage in passages.all %}& P.{{ forloop.counter }} - {{ passage.defender.team.trigram }} {% endfor %}\\ \hline \hline
|
\multicolumn{4}{|l|}{Læ {\bf D\'efenseur\textperiodcentered{}se} \normalsize pr\'esente les id\'ees et r\'esultats principaux pour la solution du probl\`eme.} {% for passage in passages.all %}& P.{{ forloop.counter }} - {{ passage.reporter.team.trigram }} {% endfor %}\\ \hline \hline
|
||||||
|
|
||||||
%ECRIT
|
%ECRIT
|
||||||
\multirow{6}{3mm}{\centering \bf\'E\\ C\\ R\\ I\\ T} & \multirow{3}{20mm}{Partie scientifique} & Profondeur et difficulté des éléments présentés & [0,6] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}}
|
\multirow{6}{3mm}{\centering \bf\'E\\ C\\ R\\ I\\ T} & \multirow{3}{20mm}{Partie scientifique} & Profondeur et difficulté des éléments présentés & [0,6] {{ esp|safe }}\\ \cline{3-{{ passages.count|add:4 }}}
|
||||||
|
|
|
@ -46,7 +46,7 @@ Tour {{ pool.round }} \;-- Poule {{ pool.get_letter_display }}{% if pool.partici
|
||||||
\begin{tabular}{|p{40mm}{% for passage in passages.all %}{% if passages.count == 3 %}|p{3cm}|p{3cm}{% else %}|p{2.5cm}|p{2.5cm}{% endif %}{% endfor %}|}\hline
|
\begin{tabular}{|p{40mm}{% for passage in passages.all %}{% if passages.count == 3 %}|p{3cm}|p{3cm}{% else %}|p{2.5cm}|p{2.5cm}{% endif %}{% endfor %}|}\hline
|
||||||
\multirow{2}{40mm}{\LARGE R\^ole} {% for passage in passages.all %}& \multicolumn{2}{c|}{ \Large Probl\`eme {{ passage.solution_number }}}{% endfor %} \\ \cline{2-{{ passages.count|add:passages.count|add:1 }}}
|
\multirow{2}{40mm}{\LARGE R\^ole} {% for passage in passages.all %}& \multicolumn{2}{c|}{ \Large Probl\`eme {{ passage.solution_number }}}{% endfor %} \\ \cline{2-{{ passages.count|add:passages.count|add:1 }}}
|
||||||
{% for passage in passages.all %}& \hspace{4mm} {\Large \'ECRIT} & \hspace{4mm} {\Large ORAL}{% endfor %} \\ \hline
|
{% for passage in passages.all %}& \hspace{4mm} {\Large \'ECRIT} & \hspace{4mm} {\Large ORAL}{% endfor %} \\ \hline
|
||||||
\multirow{2}{35mm}{\LARGE D\'efenseur\textperiodcentered{}se} {% for passage in passages.all %}& \multicolumn{2}{c|}{\Large {{ passage.defender.team.trigram }}}{% endfor %} \\ \cline{2-{{ passages.count|add:passages.count|add:1 }}}
|
\multirow{2}{35mm}{\LARGE D\'efenseur\textperiodcentered{}se} {% for passage in passages.all %}& \multicolumn{2}{c|}{\Large {{ passage.reporter.team.trigram }}}{% endfor %} \\ \cline{2-{{ passages.count|add:passages.count|add:1 }}}
|
||||||
{% for passage in passages.all %}
|
{% for passage in passages.all %}
|
||||||
& \phantom{asd asd} \phantom{asd asd} \centering \normalsize$0\leq x\leq 20$
|
& \phantom{asd asd} \phantom{asd asd} \centering \normalsize$0\leq x\leq 20$
|
||||||
& \phantom{asd asd} \phantom{asd asd} \centering \normalsize$0\leq x\leq 20$
|
& \phantom{asd asd} \phantom{asd asd} \centering \normalsize$0\leq x\leq 20$
|
||||||
|
|
|
@ -1503,10 +1503,10 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
||||||
header_role.addElement(role_tc)
|
header_role.addElement(role_tc)
|
||||||
header_role.addElement(CoveredTableCell())
|
header_role.addElement(CoveredTableCell())
|
||||||
for i in range(pool_size):
|
for i in range(pool_size):
|
||||||
defender_tc = TableCell(valuetype="string", stylename=title_style_left)
|
reporter_tc = TableCell(valuetype="string", stylename=title_style_left)
|
||||||
defender_tc.addElement(P(text=_("Defender")))
|
reporter_tc.addElement(P(text=_("Reporter")))
|
||||||
defender_tc.setAttribute('numbercolumnsspanned', "2")
|
reporter_tc.setAttribute('numbercolumnsspanned', "2")
|
||||||
header_role.addElement(defender_tc)
|
header_role.addElement(reporter_tc)
|
||||||
header_role.addElement(CoveredTableCell())
|
header_role.addElement(CoveredTableCell())
|
||||||
|
|
||||||
opponent_tc = TableCell(valuetype="string", stylename=title_style)
|
opponent_tc = TableCell(valuetype="string", stylename=title_style)
|
||||||
|
@ -1539,13 +1539,13 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
||||||
header_notes.addElement(CoveredTableCell())
|
header_notes.addElement(CoveredTableCell())
|
||||||
|
|
||||||
for i in range(pool_size):
|
for i in range(pool_size):
|
||||||
defender_w_tc = TableCell(valuetype="string", stylename=title_style_botleft)
|
reporter_w_tc = TableCell(valuetype="string", stylename=title_style_botleft)
|
||||||
defender_w_tc.addElement(P(text=f"{_('Writing')} (/{20 if settings.TFJM_APP == 'TFJM' else 10})"))
|
reporter_w_tc.addElement(P(text=f"{_('Writing')} (/{20 if settings.TFJM_APP == 'TFJM' else 10})"))
|
||||||
header_notes.addElement(defender_w_tc)
|
header_notes.addElement(reporter_w_tc)
|
||||||
|
|
||||||
defender_o_tc = TableCell(valuetype="string", stylename=title_style_bot)
|
reporter_o_tc = TableCell(valuetype="string", stylename=title_style_bot)
|
||||||
defender_o_tc.addElement(P(text=f"{_('Oral')} (/{20 if settings.TFJM_APP == 'TFJM' else 10})"))
|
reporter_o_tc.addElement(P(text=f"{_('Oral')} (/{20 if settings.TFJM_APP == 'TFJM' else 10})"))
|
||||||
header_notes.addElement(defender_o_tc)
|
header_notes.addElement(reporter_o_tc)
|
||||||
|
|
||||||
opponent_w_tc = TableCell(valuetype="string", stylename=title_style_bot)
|
opponent_w_tc = TableCell(valuetype="string", stylename=title_style_bot)
|
||||||
opponent_w_tc.addElement(P(text=f"{_('Writing')} (/10)"))
|
opponent_w_tc.addElement(P(text=f"{_('Writing')} (/10)"))
|
||||||
|
@ -1626,13 +1626,13 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
||||||
coeff_row.addElement(coeff_tc)
|
coeff_row.addElement(coeff_tc)
|
||||||
coeff_row.addElement(CoveredTableCell())
|
coeff_row.addElement(CoveredTableCell())
|
||||||
for passage in self.object.passages.all():
|
for passage in self.object.passages.all():
|
||||||
defender_w_tc = TableCell(valuetype="float", value=passage.coeff_defender_writing, stylename=style_left)
|
reporter_w_tc = TableCell(valuetype="float", value=passage.coeff_reporter_writing, stylename=style_left)
|
||||||
defender_w_tc.addElement(P(text=str(passage.coeff_defender_writing)))
|
reporter_w_tc.addElement(P(text=str(passage.coeff_reporter_writing)))
|
||||||
coeff_row.addElement(defender_w_tc)
|
coeff_row.addElement(reporter_w_tc)
|
||||||
|
|
||||||
defender_o_tc = TableCell(valuetype="float", value=passage.coeff_defender_oral, stylename=style)
|
reporter_o_tc = TableCell(valuetype="float", value=passage.coeff_reporter_oral, stylename=style)
|
||||||
defender_o_tc.addElement(P(text=str(passage.coeff_defender_oral)))
|
reporter_o_tc.addElement(P(text=str(passage.coeff_reporter_oral)))
|
||||||
coeff_row.addElement(defender_o_tc)
|
coeff_row.addElement(reporter_o_tc)
|
||||||
|
|
||||||
opponent_w_tc = TableCell(valuetype="float", value=passage.coeff_opponent_writing, stylename=style)
|
opponent_w_tc = TableCell(valuetype="float", value=passage.coeff_opponent_writing, stylename=style)
|
||||||
opponent_w_tc.addElement(P(text=str(passage.coeff_opponent_writing)))
|
opponent_w_tc.addElement(P(text=str(passage.coeff_opponent_writing)))
|
||||||
|
@ -1671,12 +1671,12 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
||||||
for i, passage in enumerate(self.object.passages.all()):
|
for i, passage in enumerate(self.object.passages.all()):
|
||||||
def_w_col = getcol(min_column + passage_width * i)
|
def_w_col = getcol(min_column + passage_width * i)
|
||||||
def_o_col = getcol(min_column + passage_width * i + 1)
|
def_o_col = getcol(min_column + passage_width * i + 1)
|
||||||
defender_tc = TableCell(valuetype="float", value=passage.average_defender, stylename=style_botleft)
|
reporter_tc = TableCell(valuetype="float", value=passage.average_reporter, stylename=style_botleft)
|
||||||
defender_tc.addElement(P(text=str(passage.average_defender)))
|
reporter_tc.addElement(P(text=str(passage.average_reporter)))
|
||||||
defender_tc.setAttribute('numbercolumnsspanned', "2")
|
reporter_tc.setAttribute('numbercolumnsspanned', "2")
|
||||||
defender_tc.setAttribute("formula", f"of:=[.{def_w_col}{max_row + 1}] * [.{def_w_col}{max_row + 2}]"
|
reporter_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}]")
|
f" + [.{def_o_col}{max_row + 1}] * [.{def_o_col}{max_row + 2}]")
|
||||||
subtotal_row.addElement(defender_tc)
|
subtotal_row.addElement(reporter_tc)
|
||||||
subtotal_row.addElement(CoveredTableCell())
|
subtotal_row.addElement(CoveredTableCell())
|
||||||
|
|
||||||
opp_w_col = getcol(min_column + passage_width * i + 2)
|
opp_w_col = getcol(min_column + passage_width * i + 2)
|
||||||
|
@ -1748,7 +1748,7 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
||||||
|
|
||||||
team_tc = TableCell(valuetype="string",
|
team_tc = TableCell(valuetype="string",
|
||||||
stylename=style_botleft if passage.position == pool_size else style_left)
|
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.addElement(P(text=f"{passage.reporter.team.name} ({passage.reporter.team.trigram})"))
|
||||||
team_tc.setAttribute('numbercolumnsspanned', "2")
|
team_tc.setAttribute('numbercolumnsspanned', "2")
|
||||||
team_row.addElement(team_tc)
|
team_row.addElement(team_tc)
|
||||||
|
|
||||||
|
@ -1758,17 +1758,17 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
||||||
problem_tc.setAttribute("formula", f"of:=[.B{3 + passage_width * (passage.position - 1)}]")
|
problem_tc.setAttribute("formula", f"of:=[.B{3 + passage_width * (passage.position - 1)}]")
|
||||||
team_row.addElement(problem_tc)
|
team_row.addElement(problem_tc)
|
||||||
|
|
||||||
defender_pos = passage.position - 1
|
reporter_pos = passage.position - 1
|
||||||
opponent_pos = self.object.passages.get(opponent=passage.defender).position - 1
|
opponent_pos = self.object.passages.get(opponent=passage.reporter).position - 1
|
||||||
reviewer_pos = self.object.passages.get(reviewer=passage.defender).position - 1
|
reviewer_pos = self.object.passages.get(reviewer=passage.reporter).position - 1
|
||||||
observer_pos = self.object.passages.get(observer=passage.defender).position - 1 \
|
observer_pos = self.object.passages.get(observer=passage.reporter).position - 1 \
|
||||||
if has_observer else None
|
if has_observer else None
|
||||||
|
|
||||||
score_tc = TableCell(valuetype="float", value=self.object.average(passage.defender),
|
score_tc = TableCell(valuetype="float", value=self.object.average(passage.reporter),
|
||||||
stylename=style_bot if passage.position == pool_size else style)
|
stylename=style_bot if passage.position == pool_size else style)
|
||||||
score_tc.addElement(P(text=self.object.average(passage.defender)))
|
score_tc.addElement(P(text=self.object.average(passage.reporter)))
|
||||||
formula = "of:="
|
formula = "of:="
|
||||||
formula += getcol(min_column + defender_pos * passage_width) + str(max_row + 3) # Defender
|
formula += getcol(min_column + reporter_pos * passage_width) + str(max_row + 3) # Reporter
|
||||||
formula += " + " + getcol(min_column + opponent_pos * passage_width + 2) + str(max_row + 3) # Opponent
|
formula += " + " + getcol(min_column + opponent_pos * passage_width + 2) + str(max_row + 3) # Opponent
|
||||||
formula += " + " + getcol(min_column + reviewer_pos * passage_width + 4) + str(max_row + 3) # Reviewer
|
formula += " + " + getcol(min_column + reviewer_pos * passage_width + 4) + str(max_row + 3) # Reviewer
|
||||||
if has_observer:
|
if has_observer:
|
||||||
|
@ -1778,9 +1778,9 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
|
||||||
team_row.addElement(score_tc)
|
team_row.addElement(score_tc)
|
||||||
|
|
||||||
score_col = 'C'
|
score_col = 'C'
|
||||||
rank_tc = TableCell(valuetype="float", value=sorted_participations.index(passage.defender) + 1,
|
rank_tc = TableCell(valuetype="float", value=sorted_participations.index(passage.reporter) + 1,
|
||||||
stylename=style_botright if passage.position == pool_size else style_right)
|
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.addElement(P(text=str(sorted_participations.index(passage.reporter) + 1)))
|
||||||
rank_tc.setAttribute("formula", f"of:=RANK([.{score_col}{max_row + 5 + passage.position}]; "
|
rank_tc.setAttribute("formula", f"of:=RANK([.{score_col}{max_row + 5 + passage.position}]; "
|
||||||
f"[.{score_col}${max_row + 6}]:"
|
f"[.{score_col}${max_row + 6}]:"
|
||||||
f"[.{score_col}${max_row + 5 + pool_size}])")
|
f"[.{score_col}${max_row + 5 + pool_size}])")
|
||||||
|
@ -1984,7 +1984,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.reviewer, passage.observer]:
|
and reg.team.participation in [passage.reporter, passage.opponent, passage.reviewer, passage.observer]:
|
||||||
return super().dispatch(request, *args, **kwargs)
|
return super().dispatch(request, *args, **kwargs)
|
||||||
return self.handle_no_permission()
|
return self.handle_no_permission()
|
||||||
|
|
||||||
|
@ -2005,8 +2005,8 @@ class PassageDetailView(LoginRequiredMixin, DetailView):
|
||||||
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')
|
||||||
|
|
||||||
context['notes'].columns['defender_writing'].column.verbose_name += f" ({passage.defender.team.trigram})"
|
context['notes'].columns['reporter_writing'].column.verbose_name += f" ({passage.reporter.team.trigram})"
|
||||||
context['notes'].columns['defender_oral'].column.verbose_name += f" ({passage.defender.team.trigram})"
|
context['notes'].columns['reporter_oral'].column.verbose_name += f" ({passage.reporter.team.trigram})"
|
||||||
context['notes'].columns['opponent_writing'].column.verbose_name += f" ({passage.opponent.team.trigram})"
|
context['notes'].columns['opponent_writing'].column.verbose_name += f" ({passage.opponent.team.trigram})"
|
||||||
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['reviewer_writing'].column.verbose_name += f" ({passage.reviewer.team.trigram})"
|
context['notes'].columns['reviewer_writing'].column.verbose_name += f" ({passage.reviewer.team.trigram})"
|
||||||
|
@ -2101,8 +2101,8 @@ class NoteUpdateView(VolunteerMixin, UpdateView):
|
||||||
|
|
||||||
def get_form(self, form_class=None):
|
def get_form(self, form_class=None):
|
||||||
form = super().get_form(form_class)
|
form = super().get_form(form_class)
|
||||||
form.fields['defender_writing'].label += f" ({self.object.passage.defender.team.trigram})"
|
form.fields['reporter_writing'].label += f" ({self.object.passage.reporter.team.trigram})"
|
||||||
form.fields['defender_oral'].label += f" ({self.object.passage.defender.team.trigram})"
|
form.fields['reporter_oral'].label += f" ({self.object.passage.reporter.team.trigram})"
|
||||||
form.fields['opponent_writing'].label += f" ({self.object.passage.opponent.team.trigram})"
|
form.fields['opponent_writing'].label += f" ({self.object.passage.opponent.team.trigram})"
|
||||||
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['reviewer_writing'].label += f" ({self.object.passage.reviewer.team.trigram})"
|
form.fields['reviewer_writing'].label += f" ({self.object.passage.reviewer.team.trigram})"
|
||||||
|
|
|
@ -837,11 +837,11 @@ class SolutionView(LoginRequiredMixin, View):
|
||||||
solution = Solution.objects.get(file__endswith=filename)
|
solution = Solution.objects.get(file__endswith=filename)
|
||||||
user = request.user
|
user = request.user
|
||||||
if user.registration.participates and user.registration.team.participation:
|
if user.registration.participates and user.registration.team.participation:
|
||||||
passage_participant_qs = Passage.objects.filter(Q(defender=user.registration.team.participation)
|
passage_participant_qs = Passage.objects.filter(Q(reporter=user.registration.team.participation)
|
||||||
| Q(opponent=user.registration.team.participation)
|
| Q(opponent=user.registration.team.participation)
|
||||||
| Q(reviewer=user.registration.team.participation)
|
| Q(reviewer=user.registration.team.participation)
|
||||||
| Q(observer=user.registration.team.participation),
|
| Q(observer=user.registration.team.participation),
|
||||||
defender=solution.participation,
|
reporter=solution.participation,
|
||||||
solution_number=solution.problem)
|
solution_number=solution.problem)
|
||||||
else:
|
else:
|
||||||
passage_participant_qs = Passage.objects.none()
|
passage_participant_qs = Passage.objects.none()
|
||||||
|
@ -853,7 +853,7 @@ class SolutionView(LoginRequiredMixin, View):
|
||||||
or user.registration.is_volunteer
|
or user.registration.is_volunteer
|
||||||
and Passage.objects.filter(Q(pool__juries=user.registration)
|
and Passage.objects.filter(Q(pool__juries=user.registration)
|
||||||
| Q(pool__tournament__in=user.registration.organized_tournaments.all()),
|
| Q(pool__tournament__in=user.registration.organized_tournaments.all()),
|
||||||
defender=solution.participation,
|
reporter=solution.participation,
|
||||||
solution_number=solution.problem).exists()
|
solution_number=solution.problem).exists()
|
||||||
or user.registration.participates and user.registration.team
|
or user.registration.participates and user.registration.team
|
||||||
and (solution.participation.team == user.registration.team or
|
and (solution.participation.team == user.registration.team or
|
||||||
|
@ -881,20 +881,20 @@ class WrittenReviewView(LoginRequiredMixin, View):
|
||||||
path = f"media/reviews/{filename}"
|
path = f"media/reviews/{filename}"
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
raise Http404
|
raise Http404
|
||||||
reviews = WrittenReview.objects.get(file__endswith=filename)
|
review = WrittenReview.objects.get(file__endswith=filename)
|
||||||
user = request.user
|
user = request.user
|
||||||
if not (user.registration.is_admin or user.registration.is_volunteer
|
if not (user.registration.is_admin or user.registration.is_volunteer
|
||||||
and (user.registration in reviews.passage.pool.juries.all()
|
and (user.registration in review.passage.pool.juries.all()
|
||||||
or user.registration in reviews.passage.pool.tournament.organizers.all()
|
or user.registration in review.passage.pool.tournament.organizers.all()
|
||||||
or user.registration.pools_presided.filter(tournament=reviews.passage.pool.tournament).exists())
|
or user.registration.pools_presided.filter(tournament=review.passage.pool.tournament).exists())
|
||||||
or user.registration.participates and user.registration.team == reviews.participation.team):
|
or user.registration.participates and user.registration.team == review.participation.team):
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
# Guess mime type of the file
|
# Guess mime type of the file
|
||||||
mime = Magic(mime=True)
|
mime = Magic(mime=True)
|
||||||
mime_type = mime.from_file(path)
|
mime_type = mime.from_file(path)
|
||||||
ext = mime_type.split("/")[1].replace("jpeg", "jpg")
|
ext = mime_type.split("/")[1].replace("jpeg", "jpg")
|
||||||
# Replace file name
|
# Replace file name
|
||||||
true_file_name = str(reviews) + f".{ext}"
|
true_file_name = str(review) + f".{ext}"
|
||||||
return FileResponse(open(path, "rb"), content_type=mime_type, filename=true_file_name)
|
return FileResponse(open(path, "rb"), content_type=mime_type, filename=true_file_name)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ Round \underline{~~~~} pool \underline{~~~~}
|
||||||
|
|
||||||
\medskip
|
\medskip
|
||||||
|
|
||||||
Problem \underline{~~~~} defended by team \underline{~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
|
Problem \underline{~~~~} reported by team \underline{~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
|
||||||
|
|
||||||
\medskip
|
\medskip
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue