from django.shortcuts import render, get_object_or_404, redirect from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.contrib.auth.decorators import login_required from django.urls import reverse_lazy from .models import Event, Training, Game, EventParticipation from .forms import EventForm, TrainingForm, GameForm, OpenGameForm from accounts.models import CustomUser # Import CustomUser for manage_participation view from django.utils import timezone import datetime def select_event_type(request): return render(request, 'calendars/select_event_type.html') class CoachCheckMixin(UserPassesTestMixin): def test_func(self): user = self.request.user if user.is_superuser: return True team = self.get_object().team return user == team.head_coach or user in team.assistant_coaches.all() class EventCreateView(LoginRequiredMixin, CreateView): model = Event form_class = EventForm template_name = 'calendars/event_form.html' success_url = reverse_lazy('dashboard') def get_form(self, form_class=None): form = super().get_form(form_class) user = self.request.user if not user.is_superuser: coached_teams = user.coached_teams.all() assisted_teams = user.assisted_teams.all() teams = coached_teams | assisted_teams form.fields['team'].queryset = teams return form class TrainingCreateView(LoginRequiredMixin, CreateView): model = Training form_class = TrainingForm template_name = 'calendars/event_form.html' success_url = reverse_lazy('dashboard') def get_form(self, form_class=None): form = super().get_form(form_class) user = self.request.user if not user.is_superuser: coached_teams = user.coached_teams.all() assisted_teams = user.assisted_teams.all() teams = coached_teams | assisted_teams form.fields['team'].queryset = teams return form class GameCreateView(LoginRequiredMixin, CreateView): model = Game form_class = GameForm template_name = 'calendars/event_form.html' success_url = reverse_lazy('dashboard') def get_form(self, form_class=None): form = super().get_form(form_class) user = self.request.user if not user.is_superuser: coached_teams = user.coached_teams.all() assisted_teams = user.assisted_teams.all() teams = coached_teams | assisted_teams form.fields['team'].queryset = teams return form class EventUpdateView(LoginRequiredMixin, CoachCheckMixin, UpdateView): model = Event template_name = 'calendars/event_form.html' success_url = reverse_lazy('dashboard') def get_form_class(self): if hasattr(self.object, 'game'): return GameForm if hasattr(self.object, 'training'): return TrainingForm return EventForm class EventDeleteView(LoginRequiredMixin, CoachCheckMixin, DeleteView): model = Event template_name = 'calendars/event_confirm_delete.html' success_url = reverse_lazy('dashboard') @login_required def manage_participation(request, child_id, event_id, status): child = get_object_or_404(CustomUser, id=child_id) event = get_object_or_404(Event, id=event_id) # Check if the logged-in user is a parent of the child if request.user not in child.parents.all(): # Handle unauthorized access return redirect('dashboard') # Check for parallel events if accepting a support game if status == 'attending' and hasattr(event, 'game') and child.team in event.game.opened_for_teams.all(): # A game's duration is defined as innings * 20 minutes + 1 hour travel. # I will assume 9 innings for now. game_duration = datetime.timedelta(minutes=(9 * 20 + 60)) event_start = event.start_time event_end = event.start_time + game_duration parallel_events = Event.objects.filter( eventparticipation__user=child, eventparticipation__status='attending' ).exclude(id=event.id) for pe in parallel_events: pe_duration = datetime.timedelta(minutes=(9 * 20 + 60)) # Assuming 9 innings for all games pe_start = pe.start_time pe_end = pe.start_time + pe_duration # Check for overlap with a tolerance of +/- 2 hours if (event_start < pe_end + datetime.timedelta(hours=2) and event_end > pe_start - datetime.timedelta(hours=2)): # Handle parallel event conflict return redirect('dashboard') # Or show an error message participation, created = EventParticipation.objects.get_or_create(user=child, event=event) participation.status = status participation.save() return redirect('dashboard') @login_required def open_game(request, game_id): game = get_object_or_404(Game, id=game_id) club = game.team.club # Permission check: only head coach of the team's club can open the game if not request.user.is_superuser and request.user not in club.administrators.all(): return redirect('dashboard') if request.method == 'POST': form = OpenGameForm(request.POST, club=club) if form.is_valid(): teams = form.cleaned_data['teams'] game.opened_for_teams.add(*teams) return redirect('dashboard') else: form = OpenGameForm(club=club) return render(request, 'calendars/open_game.html', {'form': form, 'game': game})