diff --git a/tournaments/models/match.py b/tournaments/models/match.py index 9caada4..3bc686a 100644 --- a/tournaments/models/match.py +++ b/tournaments/models/match.py @@ -52,7 +52,8 @@ class Match(models.Model): items = [] if self.round: items.append(self.round.name()) - items.append(f" #{self.index_in_round() + 1}") + if self.round.index > 0: + items.append(f" #{self.index_in_round() + 1}") elif self.group_stage: items.append(self.group_stage.name()) items.append(f"Match #{self.index + 1}") @@ -133,7 +134,7 @@ class Match(models.Model): is_winner = False scores = [] walk_out = None - team = Team(image, names, scores, weight, is_winner, walk_out) + team = Team(None, image, names, scores, weight, is_winner, walk_out) return team def live_teams(self): @@ -347,8 +348,9 @@ class Match(models.Model): # return sort_score class Team: - def __init__(self, image, names, scores, weight, is_winner, walk_out): + def __init__(self, id, image, names, scores, weight, is_winner, walk_out): # print(f"image = {image}, names= {names}, scores ={scores}, weight={weight}, win={is_winner}") + self.id = id self.image = image self.names = names self.scores = scores @@ -358,6 +360,7 @@ class Team: def to_dict(self): return { + "id": self.id, "image": self.image, "names": self.names, "scores": self.scores, diff --git a/tournaments/models/player_registration.py b/tournaments/models/player_registration.py index b35badb..32fd930 100644 --- a/tournaments/models/player_registration.py +++ b/tournaments/models/player_registration.py @@ -1,6 +1,7 @@ from django.db import models from . import TeamRegistration, PlayerSexType, PlayerDataSource, PlayerPaymentType import uuid +from django.utils import timezone class PlayerRegistration(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True) @@ -48,3 +49,30 @@ class PlayerRegistration(models.Model): name_parts = self.last_name.split(" ") name = f"{self.first_name[0]}. {name_parts[0]}" return name + + def clean_club_name(self): + if self.club_name: + return self.club_name.split(' (')[0] + return "Non renseigné" + + def calculate_age(self): + if self.birthdate: + try: + birth_year = int(self.birthdate[-4:]) # Assumes birthdate ends with YYYY + current_year = timezone.now().year + return current_year - birth_year + except (ValueError, TypeError, IndexError): + return None + return None + + def format_ordinal(self): + if self.rank is None: + if self.sex == PlayerSexType.FEMALE: + return "Non Classée" + return "Non Classé" + + if self.rank == 1: + if self.sex == PlayerSexType.FEMALE: + return "1ère" + return "1er" + return f"{self.rank}ème" diff --git a/tournaments/models/team_registration.py b/tournaments/models/team_registration.py index 272163d..d1c4545 100644 --- a/tournaments/models/team_registration.py +++ b/tournaments/models/team_registration.py @@ -3,6 +3,7 @@ from django.db.models.sql.query import Q from . import Tournament, GroupStage, Match import uuid from django.utils import timezone +from django.db.models import Count class TeamRegistration(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True) @@ -61,6 +62,15 @@ class TeamRegistration(models.Model): else: return "no players" + def formatted_team_names(self): + if self.name: + return self.name + names = [pr.last_name for pr in self.playerregistration_set.all()][:2] # Take max first 2 + joined_names = " / ".join(names) + if joined_names: + return f"Paire {joined_names}" + return "Détail de l'équipe" + def next_match(self): all_matches = [ts.match for ts in self.teamscore_set.all()] now = timezone.now() @@ -102,3 +112,81 @@ class TeamRegistration(models.Model): else: # print("no date") return None + + def get_matches(self): + matches = Match.objects.filter(team_scores__team_registration=self).distinct() + print(f"All matches for team {self.id}: {matches.count()}") + for match in matches: + print(f"Match {match.id}: start_date={match.start_date}, end_date={match.end_date}") + return matches + + def get_upcoming_matches(self): + matches = self.get_matches() + upcoming = matches.filter(end_date__isnull=True).order_by('start_date') + print(f"Upcoming matches count: {upcoming.count()}") + return [match.live_match() for match in upcoming] + + def get_completed_matches(self): + matches = self.get_matches() + completed = matches.filter(end_date__isnull=False).order_by('-end_date') + print(f"Completed matches count: {completed.count()}") + return [match.live_match() for match in completed] + + def get_statistics(self): + + stats = { + 'final_ranking': self.get_final_ranking(), + 'points_earned': self.get_points_earned(), + 'initial_stage': self.get_initial_stage(), + 'matches_played': self.count_matches_played(), + 'victory_ratio': self.calculate_victory_ratio() + } + return stats + + def get_initial_stage(self): + matches = self.get_matches().order_by('start_date') + first_match = matches.first() + if first_match: + if first_match.group_stage: + return "Poule" + elif first_match.round: + return first_match.round.name() + return None + + + def get_final_ranking(self): + if self.final_ranking: + if self.final_ranking == 1: + return "1er" + return f"{self.final_ranking}e" + return None + + def get_points_earned(self): + return self.points_earned + + def calculate_total_duration(self): + total_seconds = 0 + for match in self.get_matches().filter(end_date__isnull=False): + if match.start_date and match.end_date: + duration = (match.end_date - match.start_date).total_seconds() + total_seconds += duration + + if total_seconds > 0: + hours = int(total_seconds // 3600) + minutes = int((total_seconds % 3600) // 60) + if hours > 0: + return f"{hours}h{minutes:02d}" + return f"{minutes}min" + return None + + def count_matches_played(self): + return self.get_matches().filter(end_date__isnull=False).count() + + def calculate_victory_ratio(self): + matches = self.get_matches().filter(end_date__isnull=False) + total_matches = matches.count() + if total_matches > 0: + wins = matches.filter(winning_team_id=self.id).count() + ratio = (wins / total_matches) * 100 + return f"{wins}/{total_matches}" + return None diff --git a/tournaments/models/team_score.py b/tournaments/models/team_score.py index 3c510b2..fdbde13 100644 --- a/tournaments/models/team_score.py +++ b/tournaments/models/team_score.py @@ -71,10 +71,12 @@ class TeamScore(models.Model): def live_team(self, match): if self.team_registration: + id = self.team_registration.id image = self.team_registration.logo weight = self.team_registration.weight is_winner = self.team_registration.id == match.winning_team_id else: + id = None image = None weight= None is_winner = False @@ -82,5 +84,5 @@ class TeamScore(models.Model): scores = self.scores_array() walk_out = self.walk_out from .match import Team # Import Team only when needed - team = Team(image, names, scores, weight, is_winner, walk_out) + team = Team(id, image, names, scores, weight, is_winner, walk_out) return team diff --git a/tournaments/models/tournament.py b/tournaments/models/tournament.py index a0123b2..64f91fd 100644 --- a/tournaments/models/tournament.py +++ b/tournaments/models/tournament.py @@ -239,7 +239,7 @@ class Tournament(models.Model): names = team.names stage = team.stage weight = team.weight - summon = TeamSummon(names, team.date, weight, stage, "", team.image, self.day_duration) + summon = TeamSummon(team.team_registration.id, names, team.date, weight, stage, "", team.image, self.day_duration) summons.append(summon) else: print('>>> team_summons') @@ -250,7 +250,7 @@ class Tournament(models.Model): names = team_registration.team_names() stage = next_match.summon_stage_name() weight = team_registration.weight - summon = TeamSummon(names, next_match.local_start_date(), weight, stage, next_match.court_name(next_match.court_index), team_registration.logo, self.day_duration) + summon = TeamSummon(team_registration.id, names, next_match.local_start_date(), weight, stage, next_match.court_name(next_match.court_index), team_registration.logo, self.day_duration) summons.append(summon) summons.sort(key=lambda s: (s.date is None, s.date or datetime.min)) @@ -271,7 +271,7 @@ class Tournament(models.Model): names = team_registration.team_names() ranking = team_registration.final_ranking points = team_registration.points_earned - team = TeamRanking(names, ranking, points, team_registration.logo) + team = TeamRanking(team_registration.id, names, ranking, points, team_registration.logo) rankings.append(team) rankings.sort(key=lambda r: r.ranking) @@ -750,9 +750,8 @@ class Tournament(models.Model): return group_stages def display_rankings(self): - if self.publish_rankings is True and self.end_date is not None: - return True - return False + return True + def display_tournament(self): if self.publish_tournament: @@ -910,7 +909,8 @@ class MatchGroup: self.matches = matches class TeamSummon: - def __init__(self, names, date, weight, stage, court, image, day_duration): + def __init__(self, id, names, date, weight, stage, court, image, day_duration): + self.id = id self.names = names self.date = date self.weight = weight @@ -930,6 +930,7 @@ class TeamSummon: def to_dict(self): return { + "id": self.id, "names": self.names, "date": self.formatted_date(), "weight": self.weight, @@ -968,7 +969,8 @@ class TeamItem: } class TeamRanking: - def __init__(self, names, ranking, points, image): + def __init__(self, id, names, ranking, points, image): + self.id = id self.names = names self.ranking = ranking self.formatted_ranking = self.ordinal(ranking) @@ -999,6 +1001,7 @@ class TeamRanking: def to_dict(self): return { + "id": self.id, "names": self.names, "ranking": self.ranking, "formatted_ranking": self.formatted_ranking, diff --git a/tournaments/static/tournaments/css/style.css b/tournaments/static/tournaments/css/style.css index 7f0e7a1..9c1b320 100644 --- a/tournaments/static/tournaments/css/style.css +++ b/tournaments/static/tournaments/css/style.css @@ -714,3 +714,22 @@ h-margin { .right-content { margin-left: auto; } + +.match-result a { + text-decoration: none; + color: inherit; + display: block; + padding: 2px 8px; + border-radius: 6px; +} + +.match-result a:hover { + background-color: #fae7ce; + color: #707070; +} + +.single-line { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/tournaments/templates/tournaments/match_cell.html b/tournaments/templates/tournaments/match_cell.html index cbed073..bcbeb05 100644 --- a/tournaments/templates/tournaments/match_cell.html +++ b/tournaments/templates/tournaments/match_cell.html @@ -11,9 +11,11 @@