tickets: Send a confirmation when a payment is processed.
[matthijs/projects/dorestad-bookings.git] / tickets / views.py
index 63cf28610311b7afff27af37b7cd6e259baa53a6..7c9e9fa419c1ce9a700314bb6ad16f43394beb58 100644 (file)
@@ -1,13 +1,56 @@
 # Create your views here.
 
+import datetime
+
 import django
 from django.shortcuts import render_to_response
+from django.template import RequestContext
 
 from models import Booking
 
 class BookingForm(django.forms.ModelForm):
     class Meta:
         model=Booking
+        exclude=['payment']
+
+def confirm_booking(booking, template):
+    from django.core.mail import EmailMessage
+
+    context = {'booking' : booking}
+
+    rendered = django.template.loader.render_to_string(template, context)
+    (headers, body) = rendered.strip().split('\n\n', 1)
+
+    # Turn the headers into a dict so EmailMessage can turn them into a
+    # string again. Bit pointless, but it works. 
+    # Perhaps we should just use python email stuff directly. OTOH, we
+    # still always need to parse for the From header.
+
+    headers_dict = {}
+    # If no From header is present, let EmailMessage do the default
+    # thing
+    from_email = None
+    for header in headers.split('\n'):
+        (field, value) = header.split(':')
+        if (field == 'From'):
+            from_email = value
+        elif (field == 'Subject'):
+            subject = value
+        else:
+            # Don't put From and Subject in the dict, else they'll be
+            # present twice.
+            headers_dict[field] = value
+
+    msg = EmailMessage(
+        # Only setting the From address through headers won't set the
+        # envelope address right.
+        from_email = from_email,
+        subject    = subject,
+        body       = body,
+        to         = [booking.email],
+        headers    = headers_dict
+    )
+    msg.send()
 
 def book(request):
     if request.method == "POST":
@@ -17,6 +60,68 @@ def book(request):
 
     if f.is_valid():
         booking = f.save()
-        return render_to_response('tickets/booked.html', {'booking' : booking})
+        confirm_booking(booking, 'tickets/booked.eml')
+        return render_to_response('tickets/booked.html', {'booking' : booking}, context_instance=RequestContext(request))
+
+    return render_to_response('tickets/bookingform.html', {'form' : f}, context_instance=RequestContext(request))
+
+# These two forms are used for entering payment details. They aren't
+# very different, so it should really be possible to merge them (but
+# initial attempts to add the confirm field dynamically or setting its
+# value dynamically, didn't work out all too well, so leave it at this
+# for now).
+class PaymentForm(django.forms.Form):
+    bookings = django.forms.models.ModelMultipleChoiceField(
+        queryset=Booking.objects.filter(payment__isnull=True).order_by('pk'),
+        widget=django.forms.CheckboxSelectMultiple,
+        label="Reserveringen")
+
+class PaymentConfirmForm(django.forms.Form):
+    bookings = django.forms.models.ModelMultipleChoiceField(
+        queryset=Booking.objects.filter(payment__isnull=True).order_by('pk'),
+        widget=django.forms.MultipleHiddenInput,
+        label="Reserveringen")
+    # This field is used to distinguish these two forms
+    confirm = django.forms.BooleanField(initial=True, widget=django.forms.HiddenInput)
+
+def payments(request):
+    c = {}
+    bookings = None
+    if request.method != "POST":
+        # First step: Just show an empty form
+        f = PaymentForm()
+    elif not 'confirm' in request.POST:
+        # Second step: Process form and show a summary for confirmation
+        f = PaymentForm(request.POST)
+        if f.is_valid():
+            bookings = f.cleaned_data['bookings']
+            # Output a confirmation form
+            f = PaymentConfirmForm()
+            f.initial['bookings'] = bookings
+            c['confirm'] = True
+    else:
+        # Third step: Summary was confirmed, do the work
+        f = PaymentConfirmForm(request.POST)
+        if f.is_valid():
+            bookings = f.cleaned_data['bookings']
+
+            # Do the work
+            for b in bookings:
+                b.payment = datetime.datetime.now()
+                b.save()
+                confirm_booking(b, 'tickets/payed.eml')
+
+            # Don't show the form again
+            f = None
+            c['confirmed'] = True
+
+    # Add the form to show
+    c['form'] = f
+
+    # Add some data about the selected bookings
+    if bookings:
+        c['bookings'] = bookings
+        c['numtickets'] = sum([b.tickets for b in bookings])
+        c['amount'] = sum([b.price for b in bookings])
 
-    return render_to_response('tickets/bookingform.html', {'form' : f})
+    return render_to_response('tickets/payments.html', c, context_instance=RequestContext(request))