diff --git a/apps/participation/migrations/0004_passage_defender_penalties.py b/apps/participation/migrations/0004_passage_defender_penalties.py
new file mode 100644
index 0000000..0738a3c
--- /dev/null
+++ b/apps/participation/migrations/0004_passage_defender_penalties.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1.7 on 2021-04-03 19:57
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('participation', '0003_tournament_remote'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='passage',
+ name='defender_penalties',
+ field=models.PositiveSmallIntegerField(default=0, help_text='Number of penalties for the defender. The defender will loose a 0.5 coefficient per penalty.', verbose_name='penalties'),
+ ),
+ ]
diff --git a/apps/participation/models.py b/apps/participation/models.py
index 9d02a64..b134119 100644
--- a/apps/participation/models.py
+++ b/apps/participation/models.py
@@ -432,6 +432,13 @@ class Passage(models.Model):
related_name="+",
)
+ defender_penalties = models.PositiveSmallIntegerField(
+ verbose_name=_("penalties"),
+ default=0,
+ help_text=_("Number of penalties for the defender. "
+ "The defender will loose a 0.5 coefficient per penalty."),
+ )
+
@property
def defended_solution(self) -> "Solution":
return Solution.objects.get(
@@ -439,44 +446,44 @@ class Passage(models.Model):
problem=self.solution_number,
final_solution=self.pool.tournament.final)
- def avg(self, iterator) -> int:
+ def avg(self, iterator) -> float:
items = [i for i in iterator if i]
return sum(items) / len(items) if items else 0
@property
- def average_defender_writing(self) -> int:
+ def average_defender_writing(self) -> float:
return self.avg(note.defender_writing for note in self.notes.all())
@property
- def average_defender_oral(self) -> int:
+ def average_defender_oral(self) -> float:
return self.avg(note.defender_oral for note in self.notes.all())
@property
- def average_defender(self) -> int:
- return self.average_defender_writing + 2 * self.average_defender_oral
+ def average_defender(self) -> float:
+ return self.average_defender_writing + (2 - 0.5 * self.defender_penalties) * self.average_defender_oral
@property
- def average_opponent_writing(self) -> int:
+ def average_opponent_writing(self) -> float:
return self.avg(note.opponent_writing for note in self.notes.all())
@property
- def average_opponent_oral(self) -> int:
+ def average_opponent_oral(self) -> float:
return self.avg(note.opponent_oral for note in self.notes.all())
@property
- def average_opponent(self) -> int:
+ def average_opponent(self) -> float:
return self.average_opponent_writing + 2 * self.average_opponent_oral
@property
- def average_reporter_writing(self) -> int:
+ def average_reporter_writing(self) -> float:
return self.avg(note.reporter_writing for note in self.notes.all())
@property
- def average_reporter_oral(self) -> int:
+ def average_reporter_oral(self) -> float:
return self.avg(note.reporter_oral for note in self.notes.all())
@property
- def average_reporter(self) -> int:
+ def average_reporter(self) -> float:
return self.average_reporter_writing + self.average_reporter_oral
def average(self, participation):
diff --git a/apps/participation/templates/participation/passage_detail.html b/apps/participation/templates/participation/passage_detail.html
index 0fae622..6a64cb5 100644
--- a/apps/participation/templates/participation/passage_detail.html
+++ b/apps/participation/templates/participation/passage_detail.html
@@ -28,6 +28,9 @@
{% trans "Place:" %}
{{ passage.place }}
+ {% trans "Defender penalties count:" %}
+ {{ passage.defender_penalties }}
+
{% trans "Syntheses:" %}
{% for synthesis in passage.syntheses.all %}
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index edce286..bc79c94 100644
--- a/locale/fr/LC_MESSAGES/django.po
+++ b/locale/fr/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: TFJM\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-03-15 10:16+0100\n"
+"POT-Creation-Date: 2021-04-03 21:58+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Yohann D'ANELLO \n"
"Language-Team: LANGUAGE \n"
@@ -286,8 +286,8 @@ msgstr "L'équipe est sélectionnée pour la finale."
msgid "Participation of the team {name} ({trigram})"
msgstr "Participation de l'équipe {name} ({trigram})"
-#: apps/participation/models.py:331 apps/participation/models.py:523
-#: apps/participation/models.py:561
+#: apps/participation/models.py:331 apps/participation/models.py:530
+#: apps/participation/models.py:568
msgid "participation"
msgstr "participation"
@@ -337,7 +337,7 @@ msgstr "Où est-ce que les solutions sont défendues ?"
msgid "defended solution"
msgstr "solution défendue"
-#: apps/participation/models.py:410 apps/participation/models.py:530
+#: apps/participation/models.py:410 apps/participation/models.py:537
#, python-brace-format
msgid "Problem #{problem}"
msgstr "Problème n°{problem}"
@@ -346,110 +346,122 @@ msgstr "Problème n°{problem}"
msgid "defender"
msgstr "défenseur"
-#: apps/participation/models.py:424 apps/participation/models.py:573
+#: apps/participation/models.py:424 apps/participation/models.py:580
msgid "opponent"
msgstr "opposant"
-#: apps/participation/models.py:431 apps/participation/models.py:574
+#: apps/participation/models.py:431 apps/participation/models.py:581
msgid "reporter"
msgstr "rapporteur"
-#: apps/participation/models.py:491 apps/participation/models.py:494
-#: apps/participation/models.py:497
+#: apps/participation/models.py:436
+msgid "penalties"
+msgstr "pénalités"
+
+#: apps/participation/models.py:438
+msgid ""
+"Number of penalties for the defender. The defender will loose a 0.5 "
+"coefficient per penalty."
+msgstr ""
+"Nombre de pénalités pour le défenseur. Le défenseur perd un coefficient 0.5 "
+"sur sa solution écrite par pénalité."
+
+#: apps/participation/models.py:498 apps/participation/models.py:501
+#: apps/participation/models.py:504
#, python-brace-format
msgid "Team {trigram} is not registered in the pool."
msgstr "L'équipe {trigram} n'est pas inscrite dans la poule."
-#: apps/participation/models.py:502
+#: apps/participation/models.py:509
#, python-brace-format
msgid "Passage of {defender} for problem {problem}"
msgstr "Passage de {defender} pour le problème {problem}"
-#: apps/participation/models.py:506 apps/participation/models.py:568
-#: apps/participation/models.py:606
+#: apps/participation/models.py:513 apps/participation/models.py:575
+#: apps/participation/models.py:613
msgid "passage"
msgstr "passage"
-#: apps/participation/models.py:507
+#: apps/participation/models.py:514
msgid "passages"
msgstr "passages"
-#: apps/participation/models.py:528
+#: apps/participation/models.py:535
msgid "problem"
msgstr "numéro de problème"
-#: apps/participation/models.py:535
+#: apps/participation/models.py:542
msgid "solution for the final tournament"
msgstr "solution pour la finale"
-#: apps/participation/models.py:540 apps/participation/models.py:579
+#: apps/participation/models.py:547 apps/participation/models.py:586
msgid "file"
msgstr "fichier"
-#: apps/participation/models.py:548
+#: apps/participation/models.py:555
#, python-brace-format
msgid "Solution of team {team} for problem {problem}"
msgstr "Solution de l'équipe {team} pour le problème {problem}"
-#: apps/participation/models.py:552
+#: apps/participation/models.py:559
msgid "solution"
msgstr "solution"
-#: apps/participation/models.py:553
+#: apps/participation/models.py:560
msgid "solutions"
msgstr "solutions"
-#: apps/participation/models.py:587
+#: apps/participation/models.py:594
#, python-brace-format
msgid "Synthesis for the {type} of the {passage}"
msgstr "Synthèse pour {type} du {passage}"
-#: apps/participation/models.py:590
+#: apps/participation/models.py:597
msgid "synthesis"
msgstr "note de synthèse"
-#: apps/participation/models.py:591
+#: apps/participation/models.py:598
msgid "syntheses"
msgstr "notes de synthèse"
-#: apps/participation/models.py:599
+#: apps/participation/models.py:606
msgid "jury"
msgstr "jury"
-#: apps/participation/models.py:611
+#: apps/participation/models.py:618
msgid "defender writing note"
msgstr "note d'écrit du défenseur"
-#: apps/participation/models.py:617
+#: apps/participation/models.py:624
msgid "defender oral note"
msgstr "note d'oral du défenseur"
-#: apps/participation/models.py:623
+#: apps/participation/models.py:630
msgid "opponent writing note"
msgstr "note d'écrit de l'opposant"
-#: apps/participation/models.py:629
+#: apps/participation/models.py:636
msgid "opponent oral note"
msgstr "note d'oral de l'opposant"
-#: apps/participation/models.py:635
+#: apps/participation/models.py:642
msgid "reporter writing note"
msgstr "not d'écrit du rapporteur"
-#: apps/participation/models.py:641
+#: apps/participation/models.py:648
msgid "reporter oral note"
msgstr "note d'oral du rapporteur"
-#: apps/participation/models.py:650
+#: apps/participation/models.py:657
#, python-brace-format
msgid "Notes of {jury} for {passage}"
msgstr "Notes de {jury} pour le {passage}"
-#: apps/participation/models.py:657
+#: apps/participation/models.py:664
msgid "note"
msgstr "note"
-#: apps/participation/models.py:658
+#: apps/participation/models.py:665
msgid "notes"
msgstr "notes"
@@ -524,14 +536,14 @@ msgid "Join"
msgstr "Rejoindre"
#: apps/participation/templates/participation/note_form.html:11
-#: apps/participation/templates/participation/passage_detail.html:44
-#: apps/participation/templates/participation/passage_detail.html:100
-#: apps/participation/templates/participation/passage_detail.html:105
+#: apps/participation/templates/participation/passage_detail.html:47
+#: apps/participation/templates/participation/passage_detail.html:103
+#: apps/participation/templates/participation/passage_detail.html:108
#: apps/participation/templates/participation/pool_detail.html:55
#: apps/participation/templates/participation/pool_detail.html:73
#: apps/participation/templates/participation/pool_detail.html:78
-#: apps/participation/templates/participation/team_detail.html:111
-#: apps/participation/templates/participation/team_detail.html:175
+#: apps/participation/templates/participation/team_detail.html:113
+#: apps/participation/templates/participation/team_detail.html:177
#: apps/participation/templates/participation/tournament_form.html:12
#: apps/participation/templates/participation/update_team.html:12
#: apps/registration/templates/registration/payment_form.html:49
@@ -585,8 +597,8 @@ msgid "Upload solution"
msgstr "Envoyer une solution"
#: apps/participation/templates/participation/participation_detail.html:50
-#: apps/participation/templates/participation/passage_detail.html:110
-#: apps/participation/templates/participation/team_detail.html:170
+#: apps/participation/templates/participation/passage_detail.html:113
+#: apps/participation/templates/participation/team_detail.html:172
#: apps/participation/templates/participation/upload_motivation_letter.html:13
#: apps/participation/templates/participation/upload_solution.html:11
#: apps/participation/templates/participation/upload_synthesis.html:11
@@ -625,64 +637,68 @@ msgid "Place:"
msgstr "Lieu :"
#: apps/participation/templates/participation/passage_detail.html:31
+msgid "Defender penalties count:"
+msgstr "Nombre de pénalités :"
+
+#: apps/participation/templates/participation/passage_detail.html:34
msgid "Syntheses:"
msgstr "Notes de synthèse :"
-#: apps/participation/templates/participation/passage_detail.html:36
+#: apps/participation/templates/participation/passage_detail.html:39
msgid "No synthesis was uploaded yet."
msgstr "Aucune note de synthèse n'a encore été envoyée."
-#: apps/participation/templates/participation/passage_detail.html:43
-#: apps/participation/templates/participation/passage_detail.html:104
+#: apps/participation/templates/participation/passage_detail.html:46
+#: apps/participation/templates/participation/passage_detail.html:107
msgid "Update notes"
msgstr "Modifier les notes"
-#: apps/participation/templates/participation/passage_detail.html:48
-#: apps/participation/templates/participation/passage_detail.html:109
+#: apps/participation/templates/participation/passage_detail.html:51
+#: apps/participation/templates/participation/passage_detail.html:112
msgid "Upload synthesis"
msgstr "Envoyer une note de synthèse"
-#: apps/participation/templates/participation/passage_detail.html:56
+#: apps/participation/templates/participation/passage_detail.html:59
msgid "Notes detail"
msgstr "Détails des notes"
-#: apps/participation/templates/participation/passage_detail.html:63
+#: apps/participation/templates/participation/passage_detail.html:66
msgid "Average points for the defender writing:"
msgstr "Moyenne de l'écrit du défenseur :"
-#: apps/participation/templates/participation/passage_detail.html:66
+#: apps/participation/templates/participation/passage_detail.html:69
msgid "Average points for the defender oral:"
msgstr "Moyenne de l'oral du défenseur :"
-#: apps/participation/templates/participation/passage_detail.html:69
+#: apps/participation/templates/participation/passage_detail.html:72
msgid "Average points for the opponent writing:"
msgstr "Moyenne de l'écrit de l'opposant :"
-#: apps/participation/templates/participation/passage_detail.html:72
+#: apps/participation/templates/participation/passage_detail.html:75
msgid "Average points for the opponent oral:"
msgstr "Moyenne de l'oral de l'opposant :"
-#: apps/participation/templates/participation/passage_detail.html:75
+#: apps/participation/templates/participation/passage_detail.html:78
msgid "Average points for the reporter writing:"
msgstr "Moyenne de l'écrit du rapporteur :"
-#: apps/participation/templates/participation/passage_detail.html:78
+#: apps/participation/templates/participation/passage_detail.html:81
msgid "Average points for the reporter oral:"
msgstr "Moyenne de l'oral du rapporteur :"
-#: apps/participation/templates/participation/passage_detail.html:85
+#: apps/participation/templates/participation/passage_detail.html:88
msgid "Defender points:"
msgstr "Points du défenseur :"
-#: apps/participation/templates/participation/passage_detail.html:88
+#: apps/participation/templates/participation/passage_detail.html:91
msgid "Opponent points:"
msgstr "Points de l'opposant :"
-#: apps/participation/templates/participation/passage_detail.html:91
+#: apps/participation/templates/participation/passage_detail.html:94
msgid "Reporter points:"
msgstr "Points du rapporteur :"
-#: apps/participation/templates/participation/passage_detail.html:99
+#: apps/participation/templates/participation/passage_detail.html:102
#: apps/participation/templates/participation/passage_form.html:11
msgid "Update passage"
msgstr "Modifier le passage"
@@ -800,21 +816,21 @@ msgstr "Télécharger"
msgid "Replace"
msgstr "Remplacer"
-#: apps/participation/templates/participation/team_detail.html:106
+#: apps/participation/templates/participation/team_detail.html:107
msgid "Download all submitted authorizations"
msgstr "Télécharger toutes les autorisations soumises"
-#: apps/participation/templates/participation/team_detail.html:113
-#: apps/participation/templates/participation/team_detail.html:180
+#: apps/participation/templates/participation/team_detail.html:115
+#: apps/participation/templates/participation/team_detail.html:182
#: apps/participation/templates/participation/team_leave.html:11
msgid "Leave"
msgstr "Quitter"
-#: apps/participation/templates/participation/team_detail.html:123
+#: apps/participation/templates/participation/team_detail.html:125
msgid "Access to team participation"
msgstr "Accéder à la participation de l'équipe"
-#: apps/participation/templates/participation/team_detail.html:130
+#: apps/participation/templates/participation/team_detail.html:132
msgid ""
"Your team has at least 4 members and a coach and all authorizations were "
"given: the team can be validated."
@@ -822,11 +838,11 @@ msgstr ""
"Votre équipe contient au moins 4 personnes et un encadrant et toutes les "
"autorisations ont été données : l'équipe peut être validée."
-#: apps/participation/templates/participation/team_detail.html:135
+#: apps/participation/templates/participation/team_detail.html:137
msgid "Submit my team to validation"
msgstr "Soumettre mon équipe à validation"
-#: apps/participation/templates/participation/team_detail.html:141
+#: apps/participation/templates/participation/team_detail.html:143
msgid ""
"Your team must be composed of 4 members and a coach and each member must "
"upload their authorizations and confirm its email address."
@@ -834,15 +850,15 @@ msgstr ""
"Votre équipe doit être composée d'au moins 4 membres et un encadrant et "
"chaque membre doit envoyer ses autorisations et confirmé son adresse e-mail."
-#: apps/participation/templates/participation/team_detail.html:146
+#: apps/participation/templates/participation/team_detail.html:148
msgid "This team didn't ask for validation yet."
msgstr "L'équipe n'a pas encore demandé à être validée."
-#: apps/participation/templates/participation/team_detail.html:152
+#: apps/participation/templates/participation/team_detail.html:154
msgid "Your validation is pending."
msgstr "Votre validation est en attente."
-#: apps/participation/templates/participation/team_detail.html:156
+#: apps/participation/templates/participation/team_detail.html:158
msgid ""
"The team requested to be validated. You may now control the authorizations "
"and confirm that they can participate."
@@ -850,25 +866,25 @@ msgstr ""
"L'équipe a demandé à être validée. Vous pouvez désormais contrôler les "
"différentes autorisations et confirmer qu'elle peut participer."
-#: apps/participation/templates/participation/team_detail.html:162
+#: apps/participation/templates/participation/team_detail.html:164
msgid "Validate"
msgstr "Valider"
-#: apps/participation/templates/participation/team_detail.html:163
+#: apps/participation/templates/participation/team_detail.html:165
msgid "Invalidate"
msgstr "Invalider"
-#: apps/participation/templates/participation/team_detail.html:169
+#: apps/participation/templates/participation/team_detail.html:171
#: apps/participation/views.py:323
msgid "Upload motivation letter"
msgstr "Envoyer la lettre de motivation"
-#: apps/participation/templates/participation/team_detail.html:174
+#: apps/participation/templates/participation/team_detail.html:176
msgid "Update team"
msgstr "Modifier l'équipe"
-#: apps/participation/templates/participation/team_detail.html:179
-#: apps/participation/views.py:424
+#: apps/participation/templates/participation/team_detail.html:181
+#: apps/participation/views.py:423
msgid "Leave team"
msgstr "Quitter l'équipe"
@@ -990,12 +1006,12 @@ msgstr "Vous êtes déjà dans une équipe."
msgid "Join team"
msgstr "Rejoindre une équipe"
-#: apps/participation/views.py:150 apps/participation/views.py:430
-#: apps/participation/views.py:463
+#: apps/participation/views.py:150 apps/participation/views.py:429
+#: apps/participation/views.py:462
msgid "You are not in a team."
msgstr "Vous n'êtes pas dans une équipe."
-#: apps/participation/views.py:151 apps/participation/views.py:464
+#: apps/participation/views.py:151 apps/participation/views.py:463
msgid "You don't participate, so you don't have any team."
msgstr "Vous ne participez pas, vous n'avez donc pas d'équipe."
@@ -1040,49 +1056,49 @@ msgstr "Vous devez spécifier si vous validez l'inscription ou non."
msgid "Update team {trigram}"
msgstr "Mise à jour de l'équipe {trigram}"
-#: apps/participation/views.py:361 apps/participation/views.py:410
+#: apps/participation/views.py:361 apps/participation/views.py:409
#, python-brace-format
msgid "Motivation letter of {team}.{ext}"
msgstr "Lettre de motivation de {team}.{ext}"
-#: apps/participation/views.py:391
+#: apps/participation/views.py:390
#, python-brace-format
msgid "Photo authorization of {participant}.{ext}"
msgstr "Autorisation de droit à l'image de {participant}.{ext}"
-#: apps/participation/views.py:397
+#: apps/participation/views.py:396
#, python-brace-format
msgid "Parental authorization of {participant}.{ext}"
msgstr "Autorisation parentale de {participant}.{ext}"
-#: apps/participation/views.py:404
+#: apps/participation/views.py:403
#, python-brace-format
msgid "Health sheet of {participant}.{ext}"
msgstr "Fiche sanitaire de {participant}.{ext}"
-#: apps/participation/views.py:414
+#: apps/participation/views.py:413
#, python-brace-format
msgid "Photo authorizations of team {trigram}.zip"
msgstr "Autorisations de droit à l'image de l'équipe {trigram}.zip"
-#: apps/participation/views.py:432
+#: apps/participation/views.py:431
msgid "The team is already validated or the validation is pending."
msgstr "La validation de l'équipe est déjà faite ou en cours."
-#: apps/participation/views.py:478
+#: apps/participation/views.py:477
msgid "The team is not validated yet."
msgstr "L'équipe n'est pas encore validée."
-#: apps/participation/views.py:490
+#: apps/participation/views.py:489
#, python-brace-format
msgid "Participation of team {trigram}"
msgstr "Participation de l'équipe {trigram}"
-#: apps/participation/views.py:579
+#: apps/participation/views.py:578
msgid "You can't upload a solution after the deadline."
msgstr "Vous ne pouvez pas envoyer de solution après la date limite."
-#: apps/participation/views.py:760
+#: apps/participation/views.py:759
msgid "You can't upload a synthesis after the deadline."
msgstr "Vous ne pouvez pas envoyer de note de synthèse après la date limite."
@@ -1490,11 +1506,11 @@ msgid ""
msgstr ""
"Vous pouvez payer par carte bancaire sur notre page Hello Asso. Pour rendre la validation du "
-"paiement plus facile, merci d'utiliser la même "
-"adresse e-mail que vous utilisez sur cette plateforme. La "
-"vérification du paiement sera faite automatiquement sous 10 minutes, vous "
-"n'avez pas nécessairement besoin de remplir ce formulaire."
+"tfjm-2021\">notre page Hello Asso. Pour rendre la validation du paiement "
+"plus facile, merci d'utiliser la même adresse e-"
+"mail que vous utilisez sur cette plateforme. La vérification du "
+"paiement sera faite automatiquement sous 10 minutes, vous n'avez pas "
+"nécessairement besoin de remplir ce formulaire."
#: apps/registration/templates/registration/payment_form.html:27
msgid ""