mirror of
https://gitlab.com/animath/si/plateforme.git
synced 2025-06-24 12:28:49 +02:00
Split 5-teams pols in two pools for each room
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
@ -10,7 +10,7 @@ from django.core.validators import MaxValueValidator, MinValueValidator, RegexVa
|
||||
from django.db import models
|
||||
from django.db.models import Index
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils import timezone
|
||||
from django.utils import timezone, translation
|
||||
from django.utils.crypto import get_random_string
|
||||
from django.utils.text import format_lazy
|
||||
from django.utils.timezone import localtime
|
||||
@ -430,7 +430,9 @@ class Tournament(models.Model):
|
||||
self.notes_sheet_id = spreadsheet.id
|
||||
self.save()
|
||||
|
||||
def update_ranking_spreadsheet(self):
|
||||
def update_ranking_spreadsheet(self): # noqa: C901
|
||||
translation.activate('fr')
|
||||
|
||||
gc = gspread.service_account_from_dict(settings.GOOGLE_SERVICE_CLIENT)
|
||||
spreadsheet = gc.open_by_key(self.notes_sheet_id)
|
||||
worksheets = spreadsheet.worksheets()
|
||||
@ -444,27 +446,35 @@ class Tournament(models.Model):
|
||||
|
||||
header = [["Équipe", "Score jour 1", "Harmonisation 1", "Score jour 2", "Harmonisation 2", "Total", "Rang"]]
|
||||
lines = []
|
||||
participations = self.participations.filter(pools__round=1, pools__tournament=self).all()
|
||||
participations = self.participations.filter(pools__round=1, pools__tournament=self).distinct().all()
|
||||
for i, participation in enumerate(participations):
|
||||
line = [f"{participation.team.name} ({participation.team.trigram})"]
|
||||
lines.append(line)
|
||||
|
||||
pool1 = self.pools.get(round=1, participations=participation)
|
||||
passage1 = pool1.passages.get(defender=participation)
|
||||
passage1 = Passage.objects.get(pool__tournament=self, pool__round=1, defender=participation)
|
||||
pool1 = passage1.pool
|
||||
if pool1.participations.count() != 5:
|
||||
position1 = passage1.position
|
||||
else:
|
||||
position1 = (passage1.position - 1) * 2 + pool1.room
|
||||
tweak1_qs = Tweak.objects.filter(pool=pool1, participation=participation)
|
||||
tweak1 = tweak1_qs.get() if tweak1_qs.exists() else None
|
||||
|
||||
line.append(f"=SIERREUR('Poule {pool1.short_name}'!$D{pool1.juries.count() + 10 + passage1.position}; 0)")
|
||||
line.append(f"=SIERREUR('Poule {pool1.short_name}'!$D{pool1.juries.count() + 10 + position1}; 0)")
|
||||
line.append(tweak1.diff if tweak1 else 0)
|
||||
|
||||
if self.pools.filter(round=2, participations=participation).exists():
|
||||
pool2 = self.pools.get(round=2, participations=participation)
|
||||
passage2 = pool2.passages.get(defender=participation)
|
||||
if Passage.objects.filter(pool__tournament=self, pool__round=2, defender=participation).exists():
|
||||
passage2 = Passage.objects.get(pool__tournament=self, pool__round=2, defender=participation)
|
||||
pool2 = passage2.pool
|
||||
if pool2.participations.count() != 5:
|
||||
position2 = passage2.position
|
||||
else:
|
||||
position2 = (passage2.position - 1) * 2 + pool2.room
|
||||
tweak2_qs = Tweak.objects.filter(pool=pool2, participation=participation)
|
||||
tweak2 = tweak2_qs.get() if tweak2_qs.exists() else None
|
||||
|
||||
line.append(
|
||||
f"=SIERREUR('Poule {pool2.short_name}'!$D{pool2.juries.count() + 10 + passage2.position}; 0)")
|
||||
f"=SIERREUR('Poule {pool2.short_name}'!$D{pool2.juries.count() + 10 + position2}; 0)")
|
||||
line.append(tweak2.diff if tweak2 else 0)
|
||||
else:
|
||||
# User has no second pool yet
|
||||
@ -936,13 +946,23 @@ class Pool(models.Model):
|
||||
)
|
||||
|
||||
letter = models.PositiveSmallIntegerField(
|
||||
verbose_name=_('letter'),
|
||||
choices=[
|
||||
(1, 'A'),
|
||||
(2, 'B'),
|
||||
(3, 'C'),
|
||||
(4, 'D'),
|
||||
],
|
||||
verbose_name=_('letter'),
|
||||
)
|
||||
|
||||
room = models.PositiveSmallIntegerField(
|
||||
verbose_name=_("room"),
|
||||
choices=[
|
||||
(1, _("Room 1")),
|
||||
(2, _("Room 2")),
|
||||
],
|
||||
default=1,
|
||||
help_text=_("For 5-teams pools only"),
|
||||
)
|
||||
|
||||
participations = models.ManyToManyField(
|
||||
@ -983,7 +1003,10 @@ class Pool(models.Model):
|
||||
|
||||
@property
|
||||
def short_name(self):
|
||||
return f"{self.get_letter_display()}{self.round}"
|
||||
short_name = f"{self.get_letter_display()}{self.round}"
|
||||
if self.participations.count() == 5:
|
||||
short_name += f" — {self.get_room_display()}"
|
||||
return short_name
|
||||
|
||||
@property
|
||||
def solutions(self):
|
||||
@ -1006,6 +1029,8 @@ class Pool(models.Model):
|
||||
return super().validate_constraints()
|
||||
|
||||
def update_spreadsheet(self): # noqa: C901
|
||||
translation.activate('fr')
|
||||
|
||||
# Create tournament sheet if it does not exist
|
||||
self.tournament.create_spreadsheet()
|
||||
|
||||
@ -1085,18 +1110,38 @@ class Pool(models.Model):
|
||||
ranking = [
|
||||
["Équipe", "", "Problème", "Total", "Rang"],
|
||||
]
|
||||
for passage in passages:
|
||||
all_passages = Passage.objects.filter(pool__tournament=self.tournament,
|
||||
pool__round=self.round,
|
||||
pool__letter=self.letter).order_by('position', 'pool__room')
|
||||
for i, passage in enumerate(all_passages):
|
||||
participation = passage.defender
|
||||
defender_pos = passage.position - 1
|
||||
opponent_pos = passages.get(opponent=passage.defender).position - 1
|
||||
reporter_pos = passages.get(reporter=passage.defender).position - 1
|
||||
defender_passage = Passage.objects.get(defender=participation,
|
||||
pool__tournament=self.tournament, pool__round=self.round)
|
||||
defender_row = 5 + defender_passage.pool.juries.count()
|
||||
defender_col = defender_passage.position - 1
|
||||
|
||||
opponent_passage = Passage.objects.get(opponent=participation,
|
||||
pool__tournament=self.tournament, pool__round=self.round)
|
||||
opponent_row = 5 + opponent_passage.pool.juries.count()
|
||||
opponent_col = opponent_passage.position - 1
|
||||
|
||||
reporter_passage = Passage.objects.get(reporter=participation,
|
||||
pool__tournament=self.tournament, pool__round=self.round)
|
||||
reporter_row = 5 + reporter_passage.pool.juries.count()
|
||||
reporter_col = reporter_passage.position - 1
|
||||
|
||||
formula = "="
|
||||
formula += getcol(min_column + defender_pos * passage_width) + str(max_row + 3) # Defender
|
||||
formula += " + " + getcol(min_column + opponent_pos * passage_width + 2) + str(max_row + 3) # Opponent
|
||||
formula += " + " + getcol(min_column + reporter_pos * passage_width + 4) + str(max_row + 3) # Reporter
|
||||
formula += (f"'Poule {defender_passage.pool.short_name}'"
|
||||
f"!{getcol(min_column + defender_col * passage_width)}{defender_row + 3}") # Defender
|
||||
formula += (f" + 'Poule {opponent_passage.pool.short_name}'"
|
||||
f"!{getcol(min_column + opponent_col * passage_width + 2)}{opponent_row + 3}") # Opponent
|
||||
formula += (f" + 'Poule {reporter_passage.pool.short_name}'"
|
||||
f"!{getcol(min_column + reporter_col * passage_width + 4)}{reporter_row + 3}") # Reporter
|
||||
ranking.append([f"{participation.team.name} ({participation.team.trigram})", "",
|
||||
f"=${getcol(3 + (passage.position - 1) * passage_width)}$1", formula,
|
||||
f"=RANG(D{max_row + 5 + passage.position}; "
|
||||
f"='Poule {defender_passage.pool.short_name}'"
|
||||
f"!${getcol(3 + defender_col * passage_width)}$1",
|
||||
formula,
|
||||
f"=RANG(D{max_row + 6 + i}; "
|
||||
f"D${max_row + 6}:D${max_row + 5 + pool_size})"])
|
||||
|
||||
all_values = header + notes + footer + ranking
|
||||
@ -1147,10 +1192,10 @@ class Pool(models.Model):
|
||||
|
||||
# Set background color for headers and footers
|
||||
bg_colors = [("A1:AF", (1, 1, 1)),
|
||||
(f"A1:{getcol(2 + pool_size * passage_width)}3", (0.8, 0.8, 0.8)),
|
||||
(f"A1:{getcol(2 + passages.count() * passage_width)}3", (0.8, 0.8, 0.8)),
|
||||
(f"A{min_row - 1}:B{max_row}", (0.95, 0.95, 0.95)),
|
||||
(f"A{max_row + 1}:B{max_row + 3}", (0.8, 0.8, 0.8)),
|
||||
(f"C{max_row + 1}:{getcol(2 + pool_size * passage_width)}{max_row + 3}", (0.9, 0.9, 0.9)),
|
||||
(f"C{max_row + 1}:{getcol(2 + passages.count() * passage_width)}{max_row + 3}", (0.9, 0.9, 0.9)),
|
||||
(f"A{max_row + 5}:E{max_row + 5}", (0.8, 0.8, 0.8)),
|
||||
(f"A{max_row + 6}:E{max_row + 5 + pool_size}", (0.9, 0.9, 0.9)),]
|
||||
for bg_range, bg_color in bg_colors:
|
||||
@ -1233,11 +1278,11 @@ class Pool(models.Model):
|
||||
|
||||
# Define borders
|
||||
border_ranges = [("A1:AF", "0000"),
|
||||
(f"A1:{getcol(2 + pool_size * passage_width)}{max_row + 3}", "1111"),
|
||||
(f"A1:{getcol(2 + passages.count() * passage_width)}{max_row + 3}", "1111"),
|
||||
(f"A{max_row + 5}:E{max_row + pool_size + 5}", "1111"),
|
||||
(f"A1:B{max_row + 3}", "1113"),
|
||||
(f"C1:{getcol(2 + (pool_size - 1) * passage_width)}1", "1113")]
|
||||
for i in range(pool_size - 1):
|
||||
(f"C1:{getcol(2 + (passages.count() - 1) * passage_width)}1", "1113")]
|
||||
for i in range(passages.count() - 1):
|
||||
border_ranges.append((f"{getcol(1 + (i + 1) * passage_width)}2"
|
||||
f":{getcol(2 + (i + 1) * passage_width)}2", "1113"))
|
||||
border_ranges.append((f"{getcol(2 + (i + 1) * passage_width)}3"
|
||||
@ -1264,7 +1309,7 @@ class Pool(models.Model):
|
||||
})
|
||||
|
||||
# Add range conditions
|
||||
for i in range(pool_size):
|
||||
for i in range(passages.count()):
|
||||
for j in range(passage_width):
|
||||
column = getcol(min_column + i * passage_width + j)
|
||||
min_note = 0
|
||||
@ -1286,9 +1331,9 @@ class Pool(models.Model):
|
||||
})
|
||||
|
||||
# Set number format, display only one decimal
|
||||
number_format_ranges = [f"C{max_row + 1}:{getcol(2 + passage_width * pool_size)}{max_row + 1}",
|
||||
f"C{max_row + 3}:{getcol(2 + passage_width * pool_size)}{max_row + 3}",
|
||||
f"D{max_row + 6}:D{max_row + 5 + pool_size}",]
|
||||
number_format_ranges = [f"C{max_row + 1}:{getcol(2 + passage_width * passages.count())}{max_row + 1}",
|
||||
f"C{max_row + 3}:{getcol(2 + passage_width * passages.count())}{max_row + 3}",
|
||||
f"D{max_row + 6}:D{max_row + 5 + passages.count()}",]
|
||||
for number_format_range in number_format_ranges:
|
||||
format_requests.append({
|
||||
"repeatCell": {
|
||||
@ -1383,7 +1428,7 @@ class Pool(models.Model):
|
||||
class Meta:
|
||||
verbose_name = _("pool")
|
||||
verbose_name_plural = _("pools")
|
||||
ordering = ('round', 'letter',)
|
||||
ordering = ('round', 'letter', 'room',)
|
||||
|
||||
|
||||
class Passage(models.Model):
|
||||
|
Reference in New Issue
Block a user