Matthias Nagel a37954de65 Feat: Spiele-Historie-Ansicht für alle Team-User
Fügt eine neue Seite 'Spiele-Historie' hinzu, die allen Nutzern, die mit
einem oder mehreren Teams in Verbindung stehen (als Spieler, Head Coach,
Assistant Coach oder Elternteil), eine Übersicht über vergangene Spiele
ihrer Teams bietet. Die Spiele sind pro Team aufgeschlüsselt und zeigen
detaillierte Scorelines inklusive Inning-Ergebnissen an.

Änderungen umfassen:
- Neue View  in  zur Ermittlung der
  zugehörigen Teams und Abfrage der Spielhistorie.
- Aktualisierung der  in der View, um Inning-Scores auf 9
  Einträge aufzufüllen und so die Template-Logik zu vereinfachen.
- Neue URL-Konfiguration in .
- Neues Template  für die
  Darstellung der Spielhistorie mit detaillierter Scoreline pro Inning.
- Ergänzung eines Navigationslinks in  für
  authentifizierte Benutzer.
2025-11-19 10:00:58 +01:00

199 lines
7.1 KiB
Python

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()
})
# 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})
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)