Commits

Luke Plant committed c338a45

Added AJAX feedback of booking problems onto admin Booking page

Comments (0)

Files changed (6)

cciw/bookings/models.py

                                             year=self.camp.year).price
             self.amount_due = amount
 
-    def get_booking_problems(self):
+    def get_booking_problems(self, booking_sec=False):
         """
         Returns a two tuple (errors, warnings), where 'errors' is a list of
         reasons why booking cannot be done. If empty list, then it can be.
         'warnings' is a list of possible problems that don't stop booking.
+
+        If 'booking_sec', it shows the problems as they should be seen by the
+        booking secretary.
         """
         errors = []
         warnings = []
 
-        if self.state == BOOKING_APPROVED:
+        if self.state == BOOKING_APPROVED and not booking_sec:
             return ([], [])
 
         # Custom price - not auto bookable

cciw/bookings/tests.py

         json = simplejson.loads(resp.content)
         self.assertEqual(json['account']['post_code'], 'ABC')
 
+    def test_booking_problems(self):
+        acc1 = BookingAccount.objects.create(email="foo@foo.com",
+                                             post_code="ABC",
+                                             name="Mr Foo")
+        self.client.login(username=BOOKING_SEC_USERNAME, password=BOOKING_SEC_PASSWORD)
+        resp = self.client.post(reverse('cciw.bookings.views.booking_problems_json'),
+                                {'account':str(acc1.id)})
+
+
+        self.assertEqual(resp.status_code, 200)
+        json = simplejson.loads(resp.content)
+        self.assertEqual(json['valid'], False)
+
+        data = self.place_details.copy()
+        data['account'] = str(acc1.id)
+        data['created_0'] = '1970-01-01' # Simulate form, which doesn't supply created
+        data['created_1'] = '00:00:00'
+        data['state'] = BOOKING_APPROVED
+        data['amount_due'] = '100.00'
+        data['price_type'] = PRICE_CUSTOM
+        resp = self.client.post(reverse('cciw.bookings.views.booking_problems_json'),
+                                data)
+
+        json = simplejson.loads(resp.content)
+        self.assertEqual(json['valid'], True)
+        problems = json['problems']
+        self.assertTrue(u"A custom discount needs to be arranged by the booking secretary" in
+                        problems)
+
 
 class TestAccountOverview(CreatePlaceMixin, TestCase):
 

cciw/bookings/urls.py

              (r'^places-json/$', 'places_json'),
              (r'^account-json/$', 'account_json'),
              (r'^all-account-json/$', 'all_account_json'),
+             (r'^booking-problems-json/$', 'booking_problems_json'),
              (r'^checkout/$', 'list_bookings'),
              (r'^pay/$', 'pay'),
              (r'^pay/done/$', 'pay_done'),

cciw/bookings/views.py

     return retval
 
 
+@booking_secretary_required
+@json_response
+def booking_problems_json(request):
+    """
+    Get the booking problems associated with the data POSTed.
+    """
+    # This is used by the admin.
+    # We have to create a Booking object, but not save it.
+    from .admin import BookingAdminForm
+
+    # Make it easy on front end:
+    data = request.POST.copy()
+    try:
+        data['created'] = data['created_0'] + ' ' + data['created_1']
+    except KeyError:
+        pass
+
+
+    if 'booking_id' in data:
+        booking_obj = Booking.objects.get(id=int(data['booking_id']))
+        form = BookingAdminForm(data, booking_obj)
+    else:
+        form = BookingAdminForm(data)
+
+    retval = {'status': 'success'}
+    if form.is_valid():
+        retval['valid'] = True
+        instance = form.save(commit=False)
+        problems, warnings = instance.get_booking_problems(booking_sec=True)
+        retval['problems'] = problems + warnings
+    else:
+        retval['valid'] = False
+        retval['errors'] = form.errors
+    return retval
+
+
 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)

cciw/cciwmain/static/css/adminextra.css

     list-style: none;
 }
 
+.bookingProblems {
+    padding: 1em;
+    margin: 1em;
+    border: 1px solid red;
+}
+
+.bookingProblems li {
+    font-size: 120%;
+}
+
+
 /* Internet Explorer message */
 #ie-message {
     position: fixed;

templates/admin/bookings/booking/change_form.html

 {% load url from future %}
 {% block after_related_objects %}
 {# Some javascript enhancements  #}
+<div>
+<h2>Problems and warnings:</h2>
+<p>Please check the following list of problems and warnings before saving. They
+include problems that normally will stop a booking from being automatically
+approved, like the camp being out of space, or a custom discount being applied
+for, amd warnings due to likely errors, like booking the same place twice.</p>
+
+<p>The booking secretary has the right to ignore these problems, after
+ checking with the camp leader where necessary.</p>
+
+<div class="bookingProblems" id="id_problems">
+
+</div>
+</div>
 <script type="text/javascript">
 $(document).ready(function() {
     $('#id_address').parent().append('<input type="submit" value="Copy address details from account"' +
         })
     });
 
+    var getBookingProblems = function() {
+        var formData = $('#booking_form').serialize();
+{% if change %}
+        formData = formData + "&booking_id={{ object_id }};";
+{% endif %}
+        $.ajax({
+            type: "POST",
+            url: '{% url "cciw.bookings.views.booking_problems_json" %}',
+            dataType: "json",
+            data: formData,
+            success: function(json) {
+                if (json.valid) {
+                    if (json.problems.length == 0) {
+                        $('#id_problems').html('<p>No problems found</p>');
+                    } else {
+                        $('#id_problems').html('<ul></ul>');
+                        $.each(json.problems, function(idx, val) {
+                            var html = $('<li></li>').text(val);
+                            $('#id_problems ul').append(html);
+                        });
+                    }
+                } else {
+                    $('#id_problems').html('<i>Form has validation errors, ' +
+                        'please correct first. You can see validation errors ' +
+                        'by pressing "Save"</i>');
+                }
+            }});
+    }
+
+    getBookingProblems();
+    $('input,select,textarea').change(getBookingProblems);
+
 
 });
 </script>