diff --git a/tournaments/models/tournament.py b/tournaments/models/tournament.py index 10f59f3..37ed021 100644 --- a/tournaments/models/tournament.py +++ b/tournaments/models/tournament.py @@ -324,6 +324,10 @@ class Tournament(models.Model): print("else", index, self.team_count) return -1 + def group_stage_spots(self): + """Returns the total number of spots in all group stages.""" + return sum(gs.size for gs in self.groupstage_set.all()) + def teams(self, include_waiting_list): """ Get sorted list of teams for the tournament. @@ -358,6 +362,14 @@ class Tournament(models.Model): (team_reg.registration_date and team_reg.registration_date <= closed_date) ) + # Set initial stage + if team_reg.group_stage_position is not None: + team.set_stage("Poule") + elif team_reg.bracket_position is not None: + team.set_stage("Tableau") + else: + team.set_stage("Attente") + # Categorize team if team_reg.wild_card_bracket: wildcard_bracket.append(team) @@ -368,13 +380,15 @@ class Tournament(models.Model): else: waiting_teams.append(team) - # Set initial stage - if team_reg.group_stage_position is not None: - team.set_stage("Poule") - elif team_reg.bracket_position is not None: - team.set_stage("Tableau") - else: - team.set_stage("Attente") + + # Initialize group stage spots + group_stage_spots = self.group_stage_spots() + bracket_seeds = self.team_count - group_stage_spots - len(wildcard_bracket) + group_stage_team_count = group_stage_spots - len(wildcard_group_stage) + if group_stage_team_count < 0: + group_stage_team_count = 0 + if bracket_seeds < 0: + bracket_seeds = 0 # Sort teams based on tournament rules if self.team_sorting == TeamSortingType.INSCRIPTION_DATE: @@ -394,25 +408,45 @@ class Tournament(models.Model): complete_teams.sort(key=lambda t: (t.initial_weight, t.team_registration.id)) waiting_teams.sort(key=lambda t: (t.initial_weight, t.team_registration.id)) - # Determine final team list based on tournament settings - if len(complete_teams) <= self.team_count: - all_teams = wildcard_bracket + wildcard_group_stage + complete_teams - if include_waiting_list: - all_teams.extend(waiting_teams) - return all_teams + wildcard_group_stage.sort(key=lambda t: (t.initial_weight, t.team_registration.id)) + wildcard_bracket.sort(key=lambda t: (t.initial_weight, t.team_registration.id)) # Split teams into main bracket and waiting list - qualified_teams = complete_teams[:self.team_count] - excess_teams = complete_teams[self.team_count:] + computed_team_count = self.team_count - len(wildcard_bracket) - len(wildcard_group_stage) + if computed_team_count < 0: + computed_team_count = 0 + qualified_teams = complete_teams[:computed_team_count] + excess_teams = complete_teams[computed_team_count:] + + qualified_teams.sort(key=lambda t: (t.initial_weight, t.team_registration.id)) + excess_teams.sort(key=lambda t: (t.initial_weight, t.team_registration.id)) # Combine all waiting list teams waiting_list = excess_teams + waiting_teams + if self.team_sorting == TeamSortingType.INSCRIPTION_DATE: + waiting_list.sort(key=lambda t: ( + t.registration_date is None, + t.registration_date or datetime.min, + t.initial_weight, + t.team_registration.id + )) + else: + waiting_list.sort(key=lambda t: (t.initial_weight, t.team_registration.id)) # Return final sorted list - if include_waiting_list: - return wildcard_bracket + wildcard_group_stage + qualified_teams + waiting_list - return wildcard_bracket + wildcard_group_stage + qualified_teams + bracket_teams = qualified_teams[:bracket_seeds] + wildcard_bracket + gs_teams = qualified_teams[bracket_seeds:(bracket_seeds+group_stage_team_count)] + wildcard_group_stage + bracket_teams.sort(key=lambda t: (t.initial_weight, t.team_registration.id)) + gs_teams.sort(key=lambda t: (t.initial_weight, t.team_registration.id)) + all_teams = bracket_teams + gs_teams + for team in bracket_teams: + team.set_stage("Tableau") + for team in gs_teams: + team.set_stage("Poule") + if include_waiting_list: + all_teams.extend(waiting_list) + return all_teams def match_groups(self, broadcasted, group_stage_id, round_id):