Commits

Luke Plant  committed 85c5709

Fixed BookingAccount to deal with concurrent saves so that total_received is not overwritten

  • Participants
  • Parent commits 7b8dbea
  • Branches bookings

Comments (0)

Files changed (2)

File cciw/bookings/models.py

         unique_together = [('name', 'post_code'),
                            ('name', 'email')]
 
+    def save(self, **kwargs):
+        # We have to ensure that only receive_payment touches the total_received
+        # field when doing updates
+        if self.id is None:
+            return super(BookingAccount, self).save(**kwargs)
+        else:
+            update_fields = [f for f in self._meta.fields if
+                             f.name != 'id' and f.name != 'total_received']
+            update_kwargs = dict((f.attname, getattr(self, f.attname)) for
+                                 f in update_fields)
+            BookingAccount.objects.filter(id=self.id).update(**update_kwargs)
+
     # Business methods:
 
     def get_balance(self, confirmed_only=False):

File cciw/bookings/tests.py

 
         # Put some money in my account.
         acc = self.get_account()
-        acc.total_received = acc.bookings.all()[0].amount_due
+        acc.receive_payment(acc.bookings.all()[0].amount_due)
         acc.save()
 
         # Book
         self.assertTrue(self.place_details['name'] in mail.outbox[0].body)
         self.assertTrue('Another Child' in mail.outbox[0].body)
 
+    def test_concurrent_save(self):
+        acc1 = BookingAccount.objects.create(email='foo@foo.com')
+        acc2 = BookingAccount.objects.get(email='foo@foo.com')
+
+        acc1.receive_payment(Decimal('100.00'))
+
+        self.assertEqual(BookingAccount.objects.get(email='foo@foo.com').total_received,
+                         Decimal('100.00'))
+
+        acc2.save() # this will have total_received = 0.00
+
+        self.assertEqual(BookingAccount.objects.get(email='foo@foo.com').total_received,
+                         Decimal('100.00'))
+
 
 class TestAjaxViews(CreatePlaceMixin, TestCase):
     # Basic tests to ensure that the views that serve AJAX return something