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.
199 lines
7.1 KiB
Python
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)
|