# views.py from django.db.models import Count, Sum from django.shortcuts import render from django.utils import timezone from datetime import datetime from django.views.generic import ListView, TemplateView from django.views.generic.edit import CreateView from django.shortcuts import redirect, reverse # Importiere die Redirect-Funktion from .forms import GerichtForm # Importiere dein neues Formular from .models import Gericht, Menue, SpeiseplanTag, Bestellung class GerichtListView(ListView): model = Gericht template_name = 'mensa_app/gericht_liste.html' # Der Pfad zum Template context_object_name = 'alle_gerichte' # Der Name, den wir im Template nutzen class SpeiseplanView(TemplateView): template_name = 'mensa_app/speiseplan.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 1. Datum aus der URL holen (z.B. ?datum=2023-10-27) # Wenn kein Datum angegeben ist, nehmen wir heute. date_str = self.request.GET.get('datum') if date_str: try: target_date = datetime.strptime(date_str, '%Y-%m-%d').date() except ValueError: target_date = timezone.glob.now().date() else: target_date = timezone.now().date() # 2. Menüs für diesen spezifischen Tag laden # Wir suchen alle Menüs, deren Tag das target_date hat context['target_date'] = target_date context['menues_day'] = Menue.objects.filter(tag__datum=target_date) # 3. Dauerangebote laden (unabhängig vom Tag) context['dauerangebote'] = Gericht.objects.filter(ist_dauerangebot=True) # 4. Pager-Logik: Vorherigen und nächsten Tag finden # Wir suchen in der Tabelle SpeiseplanTag nach dem Tag davor/danach prev_tag = SpeiseplanTag.objects.filter(datum__lt=target_date).order_by('-datum').first() next_tag = SpeiseplanTag.objects.filter(datum__gt=target_date).order_by('datum').first() context['prev_date'] = prev_tag.datum.strftime('%Y-%m-%d') if prev_tag else None context['next_date'] = next_tag.datum.strftime('%Y-%m-%d') if next_tag else None return context class BestellSummaryView(TemplateView): template_name = 'mensa_app/bestell_summary.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 1. Datum aus der URL holen (wie beim Speiseplan) date_str = self.request.GET. get('datum') if date_str: try: target_date = datetime.strptime(date_str, '%Y-%m-%d').date() except ValueError: target_date = timezone.now().date() else: target_date = timezone.now().date() context['target_date'] = target_date # 2. Aggregation: Bestellungen nach Gericht gruppieren # Wir suchen alle Bestellungen, deren Menü am target_date stattfindet summary_stats = ( Bestellung.objects.filter(menue__tag__datum=target_date) .values('menue__gericht__name', 'menue__gericht__kategorie__name') # Gruppierung nach Name & Kategorie .annotate( anzahl=Count('id'), # Wie viele wurden bestellt? umsatz=Sum('menue__preis') # Was macht das für einen Umsatz? ) .order_by('menue__gericht__name') ) context['summary_stats'] = summary_stats # 3. Pager-Logik (identisch mit dem Speiseplan-View) prev_tag = SpeiseplanTag.objects.filter(datum__lt=target_date).order_by('-datum').first() next_tag = SpeiseplanTag.objects.filter(datum__gt=target_date).order_by('datum').first() context['prev_date'] = prev_tag.datum.strftime('%Y-%m-%d') if prev_tag else None context['next_date'] = next_tag.datum.strftime('%Y-%m-%d') if next_tag else None # 4. Gesamtzahlen für die Übersicht context['total_bestellungen'] = Bestellung.objects.filter(menue__tag__datum=target_date).count() context['total_umsatz'] = Bestellung.objects.filter(menue__tag__datum=target_date).aggregate(Sum('menue__preis'))['menue__preis__sum'] or 0 return context class GerichtCreateView(CreateView): """ View zur Erstellung eines neuen Gerichts. Nutzt das benutzerdefinierte GerichtForm für die gesamte Steuerung. """ model = Gericht form_class = GerichtForm # Verwendet unser Custom-Formular template_name = 'mensa_app/add_gericht.html' def get_success_url(self): # Die Methode wird ausgeführt, nachdem die View erfolgreich ist objekt = self.object # Gibt uns das gerade gespeicherte Objekt zurück return reverse('speisekarte') def form_valid(self, form): """ Die korrigierte Version der Form-Validierung. Das 'form' Argument wird hier explizit als zweites Argument deklariert, um den TypeError zu verhindern. """ # 1.!!! WICHTIG: Das Aufrufen von super().form_valid() MUSS der allererste Befehl sein! # Django speichert damit das Hauptobjekt (das Gericht) und übergibt es als self.object super().form_valid(form) # Jetzt sind wir sicher, dass das Objekt gespeichert wurde und Zugriff auf das neu erstellte Objekt haben: newly_created_dish = self.object # 2. Bilder verarbeiten (Der kritische Schritt nach der Speicherung) uploaded_files = self.request.FILES.getlist('bilder') # Achtung: self.request wird hier genutzt! if uploaded_files: for file in uploaded_files: try: GerichtBild.objects.create( gericht=newly_created_dish, image=file, sort_order=0 # Setze eine Standardreihenfolge ) except Exception as e: print(f"WARNUNG beim Speichern des Bildes {file.name}: {e}") # Wir müssen danach explizit den Return-Wert festlegen, damit Django weitergeleitet werden kann. return super().form_valid(form) # Optional: Setzen des initialen Datenzustands (z.B. Datum, falls relevant) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) return context