0002-api-add-a-suspend-action-on-Booking-40018.patch
chrono/agendas/models.py | ||
---|---|---|
475 | 475 |
self.secondary_booking_set.update(in_waiting_list=False) |
476 | 476 |
self.save() |
477 | 477 | |
478 |
def suspend(self): |
|
479 |
self.in_waiting_list = True |
|
480 |
with transaction.atomic(): |
|
481 |
self.secondary_booking_set.update(in_waiting_list=True) |
|
482 |
self.save() |
|
483 | ||
478 | 484 |
def get_ics(self, request=None): |
479 | 485 |
ics = vobject.iCalendar() |
480 | 486 |
ics.add('prodid').value = '-//Entr\'ouvert//NON SGML Publik' |
chrono/api/urls.py | ||
---|---|---|
48 | 48 |
url(r'^booking/(?P<booking_pk>\w+)/$', views.booking), |
49 | 49 |
url(r'^booking/(?P<booking_pk>\w+)/cancel/$', views.cancel_booking, name='api-cancel-booking'), |
50 | 50 |
url(r'^booking/(?P<booking_pk>\w+)/accept/$', views.accept_booking, name='api-accept-booking'), |
51 |
url(r'^booking/(?P<booking_pk>\w+)/suspend/$', views.suspend_booking, name='api-suspend-booking'), |
|
51 | 52 |
url(r'^booking/(?P<booking_pk>\w+)/ics/$', views.booking_ics, name='api-booking-ics'), |
52 | 53 |
] |
chrono/api/views.py | ||
---|---|---|
658 | 658 |
response['api']['accept_url'] = request.build_absolute_uri( |
659 | 659 |
reverse('api-accept-booking', kwargs={'booking_pk': primary_booking.id}) |
660 | 660 |
) |
661 |
else: |
|
662 |
response['api']['suspend_url'] = request.build_absolute_uri( |
|
663 |
reverse('api-suspend-booking', kwargs={'booking_pk': primary_booking.pk}) |
|
664 |
) |
|
661 | 665 |
if agenda.kind == 'meetings': |
662 | 666 |
response['end_datetime'] = format_response_datetime(events[-1].end_datetime) |
663 | 667 |
response['duration'] = (events[-1].end_datetime - events[-1].start_datetime).seconds // 60 |
... | ... | |
776 | 780 |
accept_booking = AcceptBooking.as_view() |
777 | 781 | |
778 | 782 | |
783 |
class SuspendBooking(APIView): |
|
784 |
''' |
|
785 |
Suspend a accepted booking. |
|
786 | ||
787 |
It will return error codes if the booking was cancelled before (code 1) and |
|
788 |
if the bookingis already in waiting list (code 2). |
|
789 |
''' |
|
790 | ||
791 |
permission_classes = (permissions.IsAuthenticated,) |
|
792 | ||
793 |
def post(self, request, booking_pk=None, format=None): |
|
794 |
booking = get_object_or_404(Booking, pk=booking_pk) |
|
795 |
if booking.cancellation_datetime: |
|
796 |
response = { |
|
797 |
'err': 1, |
|
798 |
'err_class': 'booking is cancelled', |
|
799 |
'err_desc': _('booking is cancelled'), |
|
800 |
} |
|
801 |
return Response(response) |
|
802 |
if booking.in_waiting_list: |
|
803 |
response = { |
|
804 |
'err': 2, |
|
805 |
'err_class': 'booking is already in waiting list', |
|
806 |
'err_desc': _('booking is already in waiting list'), |
|
807 |
} |
|
808 |
return Response(response) |
|
809 |
booking.suspend() |
|
810 |
response = {'err': 0, 'booking_id': booking.pk} |
|
811 |
return Response(response) |
|
812 | ||
813 | ||
814 |
suspend_booking = SuspendBooking.as_view() |
|
815 | ||
816 | ||
779 | 817 |
class SlotStatus(APIView): |
780 | 818 |
permission_classes = (permissions.IsAuthenticated,) |
781 | 819 |
tests/test_api.py | ||
---|---|---|
410 | 410 |
Booking.objects.get(id=resp.json['booking_id']) |
411 | 411 |
assert resp.json['datetime'] == localtime(event.start_datetime).strftime('%Y-%m-%d %H:%M:%S') |
412 | 412 |
assert 'accept_url' not in resp.json['api'] |
413 |
assert 'suspend_url' in resp.json['api'] |
|
413 | 414 |
assert 'cancel_url' in resp.json['api'] |
414 | 415 |
assert 'ics_url' in resp.json['api'] |
416 |
assert urlparse.urlparse(resp.json['api']['suspend_url']).netloc |
|
415 | 417 |
assert urlparse.urlparse(resp.json['api']['cancel_url']).netloc |
416 | 418 |
assert urlparse.urlparse(resp.json['api']['ics_url']).netloc |
417 | 419 |
assert Booking.objects.count() == 1 |
... | ... | |
606 | 608 |
Booking.objects.get(id=primary_booking_id) |
607 | 609 |
assert resp.json['datetime'] == localtime(event.start_datetime).strftime('%Y-%m-%d %H:%M:%S') |
608 | 610 |
assert 'accept_url' not in resp.json['api'] |
611 |
assert 'suspend_url' in resp.json['api'] |
|
609 | 612 |
assert 'cancel_url' in resp.json['api'] |
613 |
assert urlparse.urlparse(resp.json['api']['suspend_url']).netloc |
|
610 | 614 |
assert urlparse.urlparse(resp.json['api']['cancel_url']).netloc |
611 | 615 |
assert Booking.objects.count() == 3 |
612 | 616 |
# these 3 bookings are related, the first is the primary one |
... | ... | |
1201 | 1205 |
assert resp.json['err'] == 0 |
1202 | 1206 |
assert resp.json['in_waiting_list'] is True |
1203 | 1207 |
assert 'accept_url' in resp.json['api'] |
1208 |
assert 'suspend_url' not in resp.json['api'] |
|
1204 | 1209 |
assert 'cancel_url' in resp.json['api'] |
1205 | 1210 |
assert 'ics_url' in resp.json['api'] |
1206 | 1211 |
assert urlparse.urlparse(resp.json['api']['accept_url']).netloc |
... | ... | |
1263 | 1268 |
assert Booking.objects.filter(in_waiting_list=False).count() == 0 |
1264 | 1269 | |
1265 | 1270 | |
1271 |
def test_suspend_booking(app, some_data, user): |
|
1272 |
agenda_id = Agenda.objects.filter(label=u'Foo bar')[0].id |
|
1273 |
event = Event.objects.filter(agenda_id=agenda_id).exclude(start_datetime__lt=now())[0] |
|
1274 |
event.waiting_list_places = 5 |
|
1275 |
event.save() |
|
1276 | ||
1277 |
# create a booking not on the waiting list |
|
1278 |
booking = Booking.objects.create(event=event, in_waiting_list=False) |
|
1279 |
assert booking.in_waiting_list is False |
|
1280 | ||
1281 |
app.authorization = ('Basic', ('john.doe', 'password')) |
|
1282 |
resp = app.post('/api/booking/%s/suspend/' % booking.pk) |
|
1283 |
booking.refresh_from_db() |
|
1284 |
assert booking.in_waiting_list is True |
|
1285 | ||
1286 |
# suspend a booking that doesn't exist |
|
1287 |
resp = app.post('/api/booking/0/suspend/', status=404) |
|
1288 | ||
1289 |
# suspend a booking that is in the waiting list |
|
1290 |
resp = app.post('/api/booking/%s/suspend/' % booking.pk, status=200) |
|
1291 |
assert resp.json['err'] == 2 |
|
1292 | ||
1293 |
# suspend a booking that was cancelled before |
|
1294 |
booking.in_waiting_list = False |
|
1295 |
booking.cancel() |
|
1296 |
resp = app.post('/api/booking/%s/suspend/' % booking.pk, status=200) |
|
1297 |
assert resp.json['err'] == 1 |
|
1298 |
assert booking.in_waiting_list is False |
|
1299 | ||
1300 | ||
1266 | 1301 |
def test_multiple_booking_api(app, some_data, user): |
1267 | 1302 |
agenda = Agenda.objects.filter(label=u'Foo bar')[0] |
1268 | 1303 |
event = [x for x in Event.objects.filter(agenda=agenda) if x.in_bookable_period()][0] |
1269 |
- |