a6dff544363d6f6107337f56f3c69de29534ac92
[matthijs/projects/dorestad-bookings.git] / tickets / views.py
1 # Create your views here.
2
3 import datetime
4
5 import django
6 from django.shortcuts import render_to_response
7 from django.template import RequestContext
8 from django.contrib.auth.decorators import permission_required
9
10 from models import Booking, TICKET_PRICE
11
12 class BookingForm(django.forms.ModelForm):
13     class Meta:
14         model=Booking
15         exclude=['payment']
16
17 def confirm_booking(booking, template):
18     from django.core.mail import EmailMessage
19
20     context = {'booking' : booking}
21
22     rendered = django.template.loader.render_to_string(template, context)
23     (headers, body) = rendered.strip().split('\n\n', 1)
24
25     # Turn the headers into a dict so EmailMessage can turn them into a
26     # string again. Bit pointless, but it works. 
27     # Perhaps we should just use python email stuff directly. OTOH, we
28     # still always need to parse for the From header.
29
30     headers_dict = {}
31     # If no From header is present, let EmailMessage do the default
32     # thing
33     from_email = None
34     for header in headers.split('\n'):
35         (field, value) = header.split(':')
36         if (field == 'From'):
37             from_email = value
38         elif (field == 'Subject'):
39             subject = value
40         else:
41             # Don't put From and Subject in the dict, else they'll be
42             # present twice.
43             headers_dict[field] = value
44
45     msg = EmailMessage(
46         # Only setting the From address through headers won't set the
47         # envelope address right.
48         from_email = from_email,
49         subject    = subject,
50         body       = body,
51         to         = [booking.email],
52         headers    = headers_dict
53     )
54     msg.send()
55
56 def book(request):
57     if request.method == "POST":
58         f = BookingForm(request.POST)
59     else:
60         f = BookingForm()
61
62     if f.is_valid():
63         booking = f.save()
64         confirm_booking(booking, 'tickets/booked.eml')
65         return render_to_response('tickets/booked.html', {'booking' : booking}, context_instance=RequestContext(request))
66
67     return render_to_response('tickets/bookingform.html', {'form' : f, 'price' : TICKET_PRICE}, context_instance=RequestContext(request))
68
69 # These two forms are used for entering payment details. They aren't
70 # very different, so it should really be possible to merge them (but
71 # initial attempts to add the confirm field dynamically or setting its
72 # value dynamically, didn't work out all too well, so leave it at this
73 # for now).
74 class PaymentForm(django.forms.Form):
75     bookings = django.forms.models.ModelMultipleChoiceField(
76         queryset=Booking.objects.filter(payment__isnull=True).order_by('pk'),
77         widget=django.forms.CheckboxSelectMultiple,
78         label="Reserveringen")
79
80 class PaymentConfirmForm(django.forms.Form):
81     bookings = django.forms.models.ModelMultipleChoiceField(
82         queryset=Booking.objects.filter(payment__isnull=True).order_by('pk'),
83         widget=django.forms.MultipleHiddenInput,
84         label="Reserveringen")
85     # This field is used to distinguish these two forms
86     confirm = django.forms.BooleanField(initial=True, widget=django.forms.HiddenInput)
87
88 @permission_required('tickets.change_booking')
89 def payments(request):
90     c = {}
91     bookings = None
92     if request.method != "POST":
93         # First step: Just show an empty form
94         f = PaymentForm()
95     elif not 'confirm' in request.POST:
96         # Second step: Process form and show a summary for confirmation
97         f = PaymentForm(request.POST)
98         if f.is_valid():
99             bookings = f.cleaned_data['bookings']
100             # Output a confirmation form
101             f = PaymentConfirmForm()
102             f.initial['bookings'] = bookings
103             c['confirm'] = True
104     else:
105         # Third step: Summary was confirmed, do the work
106         f = PaymentConfirmForm(request.POST)
107         if f.is_valid():
108             bookings = f.cleaned_data['bookings']
109
110             # Do the work
111             for b in bookings:
112                 b.payment = datetime.datetime.now()
113                 b.save()
114                 confirm_booking(b, 'tickets/payed.eml')
115
116             # Don't show the form again
117             f = None
118             c['confirmed'] = True
119
120     # Add the form to show
121     c['form'] = f
122
123     # Add some data about the selected bookings
124     if bookings:
125         c['bookings'] = bookings
126         c['numtickets'] = sum([b.tickets for b in bookings])
127         c['amount'] = sum([b.price for b in bookings])
128
129     return render_to_response('tickets/payments.html', c, context_instance=RequestContext(request))