diff --git a/mensa_app/views.py b/mensa_app/views.py index 662af6f..c835b67 100644 --- a/mensa_app/views.py +++ b/mensa_app/views.py @@ -1,101 +1,97 @@ -from django.shortcuts import render +from django.shortcuts import render, redirect +from django.views import View +from .forms import OrderConfirmationForm # Ein Formular für die finalen Details +# Importieren Sie notwendige Django-Module (z.B. Django Payments) +import stripe # Beispiel: Stripe Payment Library -# Create your views here. -from django.views.generic import ListView -from .models import Gericht +class CheckoutView(View): + def get(self, request): + # 1. Warenkorb aus der Session laden (vereinfacht dargestellt) + cart_items = self.get_cart_from_session(request) + context = { + 'cart': cart_items, + } + return render(request, 'orders/checkout.html', context) -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 + def post(self, request): + # 2. Bestätigungsdaten validieren (z.B. Lieferadresse falls nötig) + form = OrderConfirmationForm() + if form.is_valid(): + user = request.user + cart_items = self.get_cart_from_session(request) -from django.views.generic import TemplateView -from django.utils import timezone -from datetime import datetime -from .models import Menue, Gericht, SpeiseplanTag + # --- 3. Transaktionsdaten erstellen und speichern --- + total = sum(item['price'] * item['quantity'] for item in cart_items) -class SpeiseplanView(TemplateView): - template_name = 'mensa_app/speiseplan.html' + # Erstelle die Hauptbestellung (STATUS: PENDING) + order = Order.objects.create(user=user, total_price=total, status='PENDING') - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) + # Speichere jeden Artikel als OrderItem + for item in cart_items: + OrderItem.objects.create( + order=order, + menu_item=item['item'], # Angenommen, der Item-Objekt ist verfügbar + quantity=item['quantity'], + price_at_purchase=item['price'] + ) - # 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: + # --- 4. Zahlung verarbeiten (CRITICAL STEP) --- 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() + payment_token = request.POST.get('stripePaymentToken') # Token aus dem Frontend erhalten + + # ACHTUNG: Hier wird das tatsächliche Stripe/PayPal API-Call ausgeführt + charge = stripe.Charge.create( + amount=int(total * 100), # Stripe erwartet Cent + currency='eur', + source=payment_token, + description=f"Mensa Bestellung für {user.username}" + ) - # 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) + # Zahlung erfolgreich! Bestätige die Order im Backend + order.status = 'CONFIRMED' + order.save() + + return redirect('bestellung_erfolgreich') - # 3. Dauerangebote laden (unabhängig vom Tag) - context['dauerangebote'] = Gericht.objects.filter(ist_dauerangebot=True) + except stripe.error.CardError as e: + # Fehlerbehandlung (z.B. falsche Karte, zu viel Geld) + form.add_error('payment', 'Zahlung fehlgeschlagen: ' + str(e)) + except Exception as e: + print(f"Allgemeiner Fehler bei der Zahlung: {e}") - # 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() + return render(request, 'orders/checkout.html', {'form': form}) - 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 +# Hilfsfunktion (muss in die View oder ein Servicescript ausgelagert werden) +def get_cart_from_session(request): + # Logik zum Laden von Menüpunkten und Mengen aus der Session + pass + from django.shortcuts import render, redirect +from django.views import View +from .forms import ReviewForm # Muss ein Formular für Rating und Kommentar enthalten - return context +class ReviewView(View): + def get(self, request): + # Zeigt alle bestehenden Bewertungen (z.B. für das Hauptmenü) + all_reviews = Review.objects.select_related('menu_item').order_by('-created_at') + context = {'reviews': all_reviews} + return render(request, 'reviews/list.html', context) + def post(self, request): + form = ReviewForm(request.POST) + if form.is_valid(): + review_data = form.cleaned_data + + # 1. Den Menüpunkt bestimmen (oder lassen Sie ihn optional) + menu_item = request.GET.get('menu_item') -from django.views.generic import TemplateView -from django.utils import timezone -from django.db.models import Count, Sum -from datetime import datetime -from .models import Bestellung, SpeiseplanTag, Gericht, Menue - -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? + # 2. Review erstellen + Review.objects.create( + user=request.user, + menu_item=menu_item, # Kann None sein + rating=review_data['rating'], + comment=review_data['comment'] ) - .order_by('menue__gericht__name') - ) - context['summary_stats'] = summary_stats + return redirect('nach_bewertung') - # 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 + # Bei Fehler: Formular mit Fehlern erneut anzeigen + return render(request, 'reviews/list.html', {'form': form, 'reviews': Review.objects.all()})