Luke Plant avatar Luke Plant committed 480cdb3

Enhanced admin for bookings, adding button that sets correct price

Also removed use of FixPriceMixin for admin, since it only works for
current year and the admin may want to look at past years.

Comments (0)

Files changed (6)

cciw/bookings/admin.py

 from django.contrib import admin
 from django import forms
 
-from cciw.bookings.forms import FixPriceMixin
 from cciw.bookings.models import Price, BookingAccount, Booking, ChequePayment, RefundPayment
 from cciw.cciwmain.common import get_thisyear
 from cciw.utils.views import close_window_response
                              widget=AccountAutoCompleteWidget('account',
                                                               attrs={'size':'70'}))
 
-class BookingAdminForm(FixPriceMixin, forms.ModelForm):
+class BookingAdminForm(forms.ModelForm):
 
     account = account_autocomplete_field()
 
     def __init__(self, *args, **kwargs):
         super(BookingAdminForm, self).__init__(*args, **kwargs)
-        self.fix_price_choices()
 
     class Meta:
         model = Booking

cciw/bookings/forms.py

 
 
 class FixPriceMixin(object):
+    """
+    Changes the 'price_type' field to include prices from the current year.
+    """
     def fix_price_choices(self):
         price_choices = self.fields['price_type'].choices
         prices = dict((p.price_type, p.price) for p in Price.objects.filter(year=get_thisyear()))

cciw/bookings/models.py

     confirmed_booking.boolean = True
 
     def expected_amount_due(self):
+        if self.price_type == PRICE_CUSTOM:
+            return None
         if self.state == BOOKING_CANCELLED:
             return Price.objects.get(year=self.camp.year,
                                      price_type=PRICE_DEPOSIT).price

cciw/bookings/urls.py

              (r'^all-account-json/$', 'all_account_json'),
              (r'^booking-problems-json/$', 'booking_problems_json'),
              (r'^place-availability-json/$', 'place_availability_json'),
+             (r'^expected-amount-json/$', 'get_expected_amount_due'),
              (r'^checkout/$', 'list_bookings'),
              (r'^pay/$', 'pay'),
              (r'^pay/done/$', 'pay_done'),

cciw/bookings/views.py

     return retval
 
 
+@csrf_exempt
+@json_response
+def get_expected_amount_due(request):
+    fail = {'status':'success',
+            'amount': None}
+    try:
+        # Need to construct a partial object, that won't pass validation,
+        # so do manual parsing of posted vars.
+        b = Booking(price_type=int(request.POST['price_type']),
+                    south_wales_transport='south_wales_transport' in request.POST,
+                    camp_id=int(request.POST['camp']))
+    except ValueError, KeyError: # not a valid price_type/camp, data missing
+        return fail
+    try:
+        amount = b.expected_amount_due()
+    except Price.DoesNotExist:
+        return fail
+
+    if amount is not None:
+        amount = str(amount) # convert decimal
+    return {'status': 'success',
+            'amount': amount}
+
+
 def make_state_token(bookings):
     # Hash some key data about booking, without which the booking isn't valid.
     bookings.sort(key=lambda b: b.id)

templates/admin/bookings/booking/change_form.html

         })
     };
 
+    $('#id_amount_due').after('<input type="submit" id="id_amount_due_auto" value="">');
+    $('#id_amount_due_auto').hide();
+
+    var getExpectedAmountDue = function() {
+        $.ajax({
+            type: "POST",
+            url: '{% url "cciw.bookings.views.get_expected_amount_due" %}',
+            data: $('#booking_form').serialize(),
+            dataType: "json",
+            success: function(json) {
+                if (json.status == 'success') {
+                    if (json.amount == null) {
+                        $('#id_amount_due_auto').hide();
+                    } else {
+                        $('#id_amount_due_auto').show().val('Set to £' + json.amount.toString());
+                        $('#id_amount_due_auto').click(function(ev) {
+                            ev.preventDefault();
+                            $('#id_amount_due').val(json.amount.toString());
+                        });
+                    }
+                }
+            }
+        });
+    };
+
     getBookingProblems();
     $('input,select,textarea').change(getBookingProblems);
 
     getPlaceAvailability();
     $('#id_camp').change(getPlaceAvailability);
 
+    getExpectedAmountDue();
+    $('#id_south_wales_transport,#id_price_type,#id_camp').change(getExpectedAmountDue);
+
 });
 </script>
 {% endblock %}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.