Matthias Nagel 223dd65382 Fix: Chronologische Sortierung der Events im Dashboard
Stellt sicher, dass die Event-Listen ('Your Events' und 'Children Events')
im Dashboard konsistent chronologisch nach dem  sortiert sind.

Obwohl die Datenbankabfragen bereits eine Sortierung enthielten, ging diese
durch die anschließende Verarbeitung in Python-Listen verloren. Die Listen
werden nun nach ihrer Erstellung explizit in Python sortiert.

Änderungen:
- Die -Liste wird nach ihrer Befüllung nach
   sortiert.
- Die  für jedes Kind wird ebenfalls nach
   sortiert, bevor sie dem Kontext hinzugefügt wird.
2025-11-21 23:03:44 +01:00

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