from django.shortcuts import render from django.contrib.auth.decorators import login_required from calendars.models import Event, EventParticipation, Game from clubs.models import Team from accounts.models import CustomUser from django.db.models import Q from django.utils import timezone import datetime from itertools import chain def get_all_child_teams(parent_team): """ Iteratively gets all child teams for a given team. """ children = [] teams_to_check = list(parent_team.child_teams.all()) while teams_to_check: team = teams_to_check.pop(0) if team not in children: children.append(team) teams_to_check.extend(list(team.child_teams.all())) return children @login_required def dashboard(request): user = request.user events_with_participation = [] children_events = [] # Get user's own events player_teams = [] if hasattr(user, 'team') and user.team: player_teams = [user.team] coached_teams_qs = user.coached_teams.all() # A head coach also manages all child teams expanded_coached_teams = list(coached_teams_qs) for team in coached_teams_qs: expanded_coached_teams.extend(get_all_child_teams(team)) assisted_teams = user.assisted_teams.all() all_teams = list(set(chain(player_teams, expanded_coached_teams, assisted_teams))) now = timezone.now() three_hours_ago = now - datetime.timedelta(hours=3) week_ago = now - datetime.timedelta(weeks=1) if all_teams: user_events = Event.objects.filter(team__in=all_teams) opened_games = Event.objects.filter(game__opened_for_teams__in=all_teams) events = (user_events | opened_games).distinct().filter( Q(end_time__gte=week_ago) | Q(end_time__isnull=True, start_time__gte=week_ago) ).select_related('game', 'training').prefetch_related('team__players', 'eventparticipation_set__user', 'game__opened_for_teams').order_by('start_time') for event in events: participations = event.eventparticipation_set.all() accepted_count = sum(1 for p in participations if p.status == 'attending') required_players = event.game.min_players if hasattr(event, 'game') else 0 player_participations = [] team_players = event.team.players.all() # Add players from opened teams if hasattr(event, 'game'): for team in event.game.opened_for_teams.all(): team_players = team_players | team.players.all() team_players = team_players.distinct() participation_map = {p.user_id: p.status for p in participations} for player in team_players: status = participation_map.get(player.id, 'maybe') player_participations.append({'player': player, 'status': status}) days_until_event = (event.start_time - timezone.now()).days local_start_time = timezone.localtime(event.start_time) events_with_participation.append({ 'event': event, 'accepted_count': accepted_count, 'required_players': required_players, 'player_participations': player_participations, 'days_until_event': days_until_event, 'local_start_time_iso': local_start_time.isoformat() }) # Sort the final list by event start time events_with_participation.sort(key=lambda x: x['event'].start_time) # Get children's events if hasattr(user, 'children'): print('haschild') for child in user.children.all(): child_events_list = [] if child.team: child_user_events = Event.objects.filter(team=child.team) child_opened_games = Event.objects.filter(game__opened_for_teams=child.team) child_events = (child_user_events | child_opened_games).distinct().filter( Q(end_time__gte=three_hours_ago) | Q(end_time__isnull=True, start_time__gte=three_hours_ago) ).select_related('game', 'training').order_by('start_time') for event in child_events: participation, created = EventParticipation.objects.get_or_create(user=child, event=event) child_events_list.append({'event': event, 'participation': participation}) # Sort each child's event list child_events_list.sort(key=lambda x: x['event'].start_time) children_events.append({'child': child, 'events': child_events_list}) context = { 'events_with_participation': events_with_participation, 'children_events': children_events, 'now': timezone.now() } return render(request, 'dashboard/dashboard.html', context) @login_required def player_list(request): user = request.user coached_teams = user.coached_teams.all() assisted_teams = user.assisted_teams.all() all_coached_teams = list(coached_teams) for team in coached_teams: all_coached_teams.extend(get_all_child_teams(team)) all_teams = set(list(all_coached_teams) + list(assisted_teams)) players = CustomUser.objects.filter(team__in=all_teams).distinct() context = { 'players': players, 'teams': all_teams } return render(request, 'dashboard/player_list.html', context) @login_required def past_games(request): user = request.user user_teams = set() # Player's team if user.team: user_teams.add(user.team) # Coached teams for team in user.coached_teams.all(): user_teams.add(team) user_teams.update(get_all_child_teams(team)) # Assisted teams for team in user.assisted_teams.all(): user_teams.add(team) # Parents' children's teams if hasattr(user, 'children'): for child in user.children.all(): if child.team: user_teams.add(child.team) # Fetch past games for all collected teams games_qs = Game.objects.filter( team__in=list(user_teams), start_time__lt=timezone.now(), result__isnull=False ).select_related('team', 'result').order_by('team__name', '-start_time') # Group games by team games_by_team = {} for game in games_qs: if game.team not in games_by_team: games_by_team[game.team] = [] # Prepare scoreline data result = game.result sorted_items = sorted(result.inning_results.items(), key=lambda x: int(x[0].split('_')[1])) home_innings = [item[1].get('home', 'X') for item in sorted_items] away_innings = [item[1].get('guest', 'X') for item in sorted_items] # Pad innings to 9 home_innings.extend([''] * (9 - len(home_innings))) away_innings.extend([''] * (9 - len(away_innings))) home_score = sum(i for i in home_innings if isinstance(i, int)) away_score = sum(i for i in away_innings if isinstance(i, int)) game_data = { 'game': game, 'home_score': home_score, 'away_score': away_score, 'home_innings': home_innings[:9], 'away_innings': away_innings[:9] } games_by_team[game.team].append(game_data) context = { 'games_by_team': games_by_team } return render(request, 'dashboard/past_games.html', context)