from django.shortcuts import render, get_object_or_404 from django.contrib.auth.decorators import login_required from django.http import HttpResponseForbidden from clubs.models import Team from calendars.models import Game, EventParticipation def _calculate_statistics(team, season=None): """ Calculates statistics for a given team and season. """ games_query = Game.objects.filter(team=team, result__isnull=False).prefetch_related('opened_for_teams') if season: games_query = games_query.filter(season=season) games = games_query.order_by('start_time') wins = 0 losses = 0 runs_scored = 0 runs_allowed = 0 inning_runs = {i: 0 for i in range(1, 10)} streak_counter = 0 last_game_result = None games_with_supporters = 0 total_supporter_player_percentage = 0 for game in games: # Supporter stats if game.opened_for_teams.exists(): games_with_supporters += 1 attending_players = EventParticipation.objects.filter(event=game, status='attending').select_related('user__team') total_attendees = attending_players.count() if total_attendees > 0: supporter_players_count = attending_players.exclude(user__team=game.team).count() supporter_percentage = (supporter_players_count / total_attendees) * 100 total_supporter_player_percentage += supporter_percentage # Standard game stats result = game.result sorted_items = sorted(result.inning_results.items(), key=lambda x: int(x[0].split('_')[1])) home_innings = [ item[1].get('home') for item in sorted_items if isinstance(item[1].get('home'), int) ] away_innings = [ item[1].get('guest') for item in sorted_items if isinstance(item[1].get('guest'), int) ] home_score = sum(home_innings) away_score = sum(away_innings) if game.is_home_game: team_score = home_score opponent_score = away_score else: team_score = away_score opponent_score = home_score runs_scored += team_score runs_allowed += opponent_score if team_score > opponent_score: wins += 1 if last_game_result == 'win': streak_counter += 1 else: streak_counter = 1 last_game_result = 'win' elif team_score < opponent_score: losses += 1 if last_game_result == 'loss': streak_counter += 1 else: streak_counter = 1 last_game_result = 'loss' team_innings = home_innings if game.is_home_game else away_innings for i, runs in enumerate(team_innings): if i + 1 in inning_runs: inning_runs[i + 1] += runs total_games = wins + losses pct = (wins / total_games) * 100 if total_games > 0 else 0 if last_game_result == 'win': streak_str = f"Won {streak_counter}" elif last_game_result == 'loss': streak_str = f"Lost {streak_counter}" else: streak_str = "N/A" if runs_scored > 0 or runs_allowed > 0: pythagorean_pct = (runs_scored**2 / (runs_scored**2 + runs_allowed**2)) * 100 else: pythagorean_pct = 0 avg_supporter_player_percentage = (total_supporter_player_percentage / games_with_supporters) if games_with_supporters > 0 else 0 return { 'team': team, 'wins': wins, 'losses': losses, 'pct': pct, 'streak': streak_str, 'runs_scored': runs_scored, 'runs_allowed': runs_allowed, 'pythagorean_pct': pythagorean_pct, 'inning_runs': inning_runs, 'total_games': total_games, 'games_with_supporters': games_with_supporters, 'avg_supporter_player_percentage': avg_supporter_player_percentage, } @login_required def team_statistics(request, team_id): team = get_object_or_404(Team, pk=team_id) # User must be the head coach of the parent team to view the stats if request.user != team.head_coach: return HttpResponseForbidden("You are not authorized to view this page.") selected_season = request.GET.get('season') # Create a list of the parent team and all its child teams teams_to_display = [team] + list(team.child_teams.all()) # Calculate statistics for each team teams_stats = [] for t in teams_to_display: stats = _calculate_statistics(t, selected_season) teams_stats.append(stats) # Get all available seasons for the filter dropdown available_seasons = Game.objects.values_list('season', flat=True).distinct().order_by('season') context = { 'team': team, # Primary team for page header/auth 'teams_stats': teams_stats, 'available_seasons': available_seasons, 'selected_season': selected_season, } return render(request, 'team_stats/team_statistics.html', context) @login_required def season_report(request, team_id, season): team = get_object_or_404(Team, pk=team_id) # Security check: only head coach can view if request.user != team.head_coach: return HttpResponseForbidden("You are not authorized to view this report.") # 1. Get all players for the team, ordered players = team.players.all().order_by('last_name', 'first_name') player_ids = [p.id for p in players] # 2. Get all games for the team and season games = Game.objects.filter(team=team, season=season).order_by('start_time') game_ids = [g.id for g in games] # 3. Get all relevant participation data in one query participations = EventParticipation.objects.filter( event_id__in=game_ids, user_id__in=player_ids ) # 4. Create a fast lookup map participation_map = { (p.event_id, p.user_id): p.status for p in participations } # 5. Build the final data structure for the template report_data = [] for game in games: statuses = [] for player in players: status = participation_map.get((game.id, player.id), 'maybe') statuses.append(status) report_data.append({ 'game': game, 'statuses': statuses }) context = { 'team': team, 'season': season, 'players': players, 'report_data': report_data, } return render(request, 'team_stats/season_report.html', context)