api: cancel booking in recurring fillslot - instead of delete (#61066)
This commit is contained in:
parent
7eb1fcf7e4
commit
f65717725b
|
@ -1647,8 +1647,22 @@ class RecurringFillslots(APIView):
|
|||
agendas, payload['slots'], start_datetime, end_datetime, user_external_id
|
||||
).values_list('pk', flat=True)
|
||||
|
||||
events_to_book = events_to_book.exclude(booking__user_external_id=user_external_id)
|
||||
# outdated bookings to remove (cancelled bookings to replace by an active booking)
|
||||
events_cancelled_to_delete = events_to_book.filter(
|
||||
booking__user_external_id=user_external_id,
|
||||
booking__cancellation_datetime__isnull=False,
|
||||
full=False,
|
||||
)
|
||||
# book only events without active booking for the user
|
||||
events_to_book = events_to_book.exclude(
|
||||
pk__in=Booking.objects.filter(
|
||||
event__in=events_to_book,
|
||||
user_external_id=user_external_id,
|
||||
cancellation_datetime__isnull=True,
|
||||
).values('event')
|
||||
)
|
||||
|
||||
# exclude full events
|
||||
full_events = list(events_to_book.filter(full=True))
|
||||
events_to_book = events_to_book.filter(full=False)
|
||||
|
||||
|
@ -1662,16 +1676,28 @@ class RecurringFillslots(APIView):
|
|||
extra_data = {k: v for k, v in request.data.items() if k not in payload}
|
||||
bookings = [make_booking(event, payload, extra_data) for event in events_to_book]
|
||||
|
||||
bookings_to_cancel = Booking.objects.filter(
|
||||
user_external_id=user_external_id, event__in=events_to_unbook, cancellation_datetime__isnull=True
|
||||
)
|
||||
|
||||
with transaction.atomic():
|
||||
deleted_count = Booking.objects.filter(
|
||||
user_external_id=user_external_id, event__in=events_to_unbook
|
||||
).delete()[0]
|
||||
# cancel existing bookings
|
||||
cancellation_datetime = now()
|
||||
Booking.objects.filter(primary_booking__in=bookings_to_cancel).update(
|
||||
cancellation_datetime=cancellation_datetime
|
||||
)
|
||||
cancelled_count = bookings_to_cancel.update(cancellation_datetime=cancellation_datetime)
|
||||
# and delete outdated cancelled bookings
|
||||
Booking.objects.filter(
|
||||
user_external_id=user_external_id, event__in=events_cancelled_to_delete
|
||||
).delete()
|
||||
# create missing bookings
|
||||
Booking.objects.bulk_create(bookings)
|
||||
|
||||
response = {
|
||||
'err': 0,
|
||||
'booking_count': len(bookings),
|
||||
'cancelled_booking_count': deleted_count,
|
||||
'cancelled_booking_count': cancelled_count,
|
||||
'full_events': [get_event_detail(request, x, multiple_agendas=True) for x in full_events],
|
||||
}
|
||||
if payload.get('include_booked_events_detail'):
|
||||
|
|
|
@ -2394,7 +2394,115 @@ def test_recurring_events_api_fillslots_waiting_list(app, user, freezer):
|
|||
assert events.filter(booked_waiting_list_places=2).count() == 5
|
||||
|
||||
|
||||
def test_recurring_events_api_fillslots_change_bookings(app, user, freezer):
|
||||
def test_recurring_events_api_fillslots_book_with_cancelled(app, user, freezer):
|
||||
freezer.move_to('2021-09-06 12:00')
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events', minimal_booking_delay=0)
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
event = Event.objects.create(
|
||||
label='Event',
|
||||
start_datetime=now(),
|
||||
recurrence_days=[0, 1], # Monday, Tuesday
|
||||
places=1,
|
||||
waiting_list_places=1,
|
||||
agenda=agenda,
|
||||
recurrence_end_date=now() + datetime.timedelta(days=21),
|
||||
)
|
||||
event.create_all_recurrences()
|
||||
|
||||
# create cancelled bookings for the user
|
||||
event_1_0 = event.get_or_create_event_recurrence(event.start_datetime)
|
||||
booking_1_0 = Booking.objects.create(event=event_1_0, user_external_id='user_id')
|
||||
booking_1_0.cancel()
|
||||
assert booking_1_0.cancellation_datetime is not None
|
||||
event_1_1 = event.get_or_create_event_recurrence(event.start_datetime + datetime.timedelta(days=1))
|
||||
booking_1_1 = Booking.objects.create(event=event_1_1, user_external_id='user_id')
|
||||
booking_1_1.cancel()
|
||||
assert booking_1_1.cancellation_datetime is not None
|
||||
# and non cancelled bookings for the user
|
||||
event_2_0 = event.get_or_create_event_recurrence(event.start_datetime + datetime.timedelta(days=7))
|
||||
booking_2_0 = Booking.objects.create(event=event_2_0, user_external_id='user_id')
|
||||
assert booking_2_0.cancellation_datetime is None
|
||||
event_2_1 = event.get_or_create_event_recurrence(event.start_datetime + datetime.timedelta(days=8))
|
||||
booking_2_1 = Booking.objects.create(event=event_2_1, user_external_id='user_id')
|
||||
assert booking_2_1.cancellation_datetime is None
|
||||
# and bookings for another user
|
||||
Booking.objects.create(event=event_1_0, user_external_id='user_id_foobar')
|
||||
other_booking = Booking.objects.create(event=event_2_0, user_external_id='user_id_foobar')
|
||||
other_booking.cancel()
|
||||
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
fillslots_url = '/api/agendas/recurring-events/fillslots/?agendas=%s&action=book' % agenda.slug
|
||||
params = {'user_external_id': 'user_id'}
|
||||
|
||||
# Book Monday
|
||||
params['slots'] = 'foo-bar@event:0'
|
||||
resp = app.post_json(fillslots_url, params=params)
|
||||
assert resp.json['booking_count'] == 2
|
||||
assert resp.json['cancelled_booking_count'] == 0
|
||||
assert Booking.objects.filter(user_external_id='user_id').count() == 5
|
||||
assert Booking.objects.filter(user_external_id='user_id', cancellation_datetime__isnull=True).count() == 4
|
||||
assert Booking.objects.filter(user_external_id='user_id', event__start_datetime__week_day=2).count() == 3
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id',
|
||||
event__start_datetime__week_day=2,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 3
|
||||
)
|
||||
assert Booking.objects.filter(user_external_id='user_id', event__start_datetime__week_day=3).count() == 2
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id',
|
||||
event__start_datetime__week_day=3,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 1
|
||||
)
|
||||
|
||||
assert Booking.objects.filter(pk=booking_1_0.pk).exists() is False # cancelled booking deleted
|
||||
booking_1_1.refresh_from_db()
|
||||
booking_2_0.refresh_from_db()
|
||||
booking_2_1.refresh_from_db()
|
||||
assert booking_1_1.cancellation_datetime is not None
|
||||
assert booking_2_0.cancellation_datetime is None
|
||||
assert booking_2_1.cancellation_datetime is None
|
||||
|
||||
# Book Tuesday
|
||||
params['slots'] = 'foo-bar@event:1'
|
||||
resp = app.post_json(fillslots_url, params=params)
|
||||
assert resp.json['booking_count'] == 2
|
||||
assert resp.json['cancelled_booking_count'] == 0
|
||||
assert Booking.objects.filter(user_external_id='user_id').count() == 6
|
||||
assert Booking.objects.filter(user_external_id='user_id', cancellation_datetime__isnull=True).count() == 6
|
||||
assert Booking.objects.filter(user_external_id='user_id', event__start_datetime__week_day=2).count() == 3
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id',
|
||||
event__start_datetime__week_day=2,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 3
|
||||
)
|
||||
assert Booking.objects.filter(user_external_id='user_id', event__start_datetime__week_day=3).count() == 3
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id',
|
||||
event__start_datetime__week_day=3,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 3
|
||||
)
|
||||
|
||||
assert Booking.objects.filter(pk=booking_1_0.pk).exists() is False # cancelled booking deleted
|
||||
assert Booking.objects.filter(pk=booking_1_1.pk).exists() is False # cancelled booking deleted
|
||||
booking_2_0.refresh_from_db()
|
||||
booking_2_1.refresh_from_db()
|
||||
assert booking_2_0.cancellation_datetime is None
|
||||
assert booking_2_1.cancellation_datetime is None
|
||||
|
||||
|
||||
def test_recurring_events_api_fillslots_update(app, user, freezer):
|
||||
freezer.move_to('2021-09-06 12:00')
|
||||
agenda = Agenda.objects.create(
|
||||
label='Foo bar', kind='events', minimal_booking_delay=0, maximal_booking_delay=0
|
||||
|
@ -2443,11 +2551,35 @@ def test_recurring_events_api_fillslots_change_bookings(app, user, freezer):
|
|||
resp = app.post_json(fillslots_url, params=params)
|
||||
assert resp.json['booking_count'] == 4
|
||||
assert resp.json['cancelled_booking_count'] == 8
|
||||
assert Booking.objects.count() == 152
|
||||
assert Booking.objects.filter(event__start_datetime__week_day=2).count() == 52
|
||||
assert Booking.objects.filter(event__start_datetime__week_day=3).count() == 4
|
||||
assert Booking.objects.filter(event__start_datetime__week_day=5).count() == 48
|
||||
assert Booking.objects.filter(event__start_datetime__week_day=6).count() == 48
|
||||
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 152
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__start_datetime__week_day=2,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 52
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__start_datetime__week_day=3,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 4
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__start_datetime__week_day=5,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 48
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__start_datetime__week_day=6,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 48
|
||||
)
|
||||
|
||||
# remove delays
|
||||
agenda.minimal_booking_delay = 0
|
||||
|
@ -2457,24 +2589,55 @@ def test_recurring_events_api_fillslots_change_bookings(app, user, freezer):
|
|||
resp = app.post_json(fillslots_url, params=params)
|
||||
assert resp.json['booking_count'] == 48
|
||||
assert resp.json['cancelled_booking_count'] == 96
|
||||
assert Booking.objects.count() == 104
|
||||
assert Booking.objects.filter(event__start_datetime__week_day=2).count() == 52
|
||||
assert Booking.objects.filter(event__start_datetime__week_day=3).count() == 52
|
||||
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 104
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__start_datetime__week_day=2,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 52
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__start_datetime__week_day=3,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 52
|
||||
)
|
||||
|
||||
# Booking again does nothing
|
||||
resp = app.post_json(fillslots_url, params=params)
|
||||
assert resp.json['booking_count'] == 0
|
||||
assert resp.json['cancelled_booking_count'] == 0
|
||||
assert Booking.objects.count() == 104
|
||||
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 104
|
||||
|
||||
params = {'user_external_id': 'user_id_2'}
|
||||
params['slots'] = 'foo-bar@event:0,foo-bar@event:3'
|
||||
resp = app.post_json(fillslots_url, params=params)
|
||||
assert resp.json['booking_count'] == 104
|
||||
assert resp.json['cancelled_booking_count'] == 0
|
||||
assert Booking.objects.count() == 208
|
||||
assert Booking.objects.filter(event__start_datetime__week_day=2).count() == 104
|
||||
assert Booking.objects.filter(event__start_datetime__week_day=5).count() == 52
|
||||
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 208
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__start_datetime__week_day=2,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 104
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__start_datetime__week_day=3,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 52
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__start_datetime__week_day=5,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 52
|
||||
)
|
||||
events = Event.objects.filter(primary_event__isnull=False)
|
||||
assert events.filter(booked_places=1).count() == 156
|
||||
assert events.filter(booked_waiting_list_places=1).count() == 52
|
||||
|
@ -2483,9 +2646,28 @@ def test_recurring_events_api_fillslots_change_bookings(app, user, freezer):
|
|||
resp = app.post_json(fillslots_url, params=params)
|
||||
assert resp.json['booking_count'] == 104
|
||||
assert resp.json['cancelled_booking_count'] == 104
|
||||
assert Booking.objects.count() == 208
|
||||
assert Booking.objects.filter(event__start_datetime__week_day=3).count() == 104
|
||||
assert Booking.objects.filter(event__start_datetime__week_day=6).count() == 52
|
||||
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 208
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__start_datetime__week_day=2,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 52
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__start_datetime__week_day=3,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 104
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__start_datetime__week_day=6,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 52
|
||||
)
|
||||
events = Event.objects.filter(primary_event__isnull=False)
|
||||
assert events.filter(booked_places=1).count() == 156
|
||||
assert events.filter(booked_waiting_list_places=1).count() == 52
|
||||
|
@ -2494,7 +2676,13 @@ def test_recurring_events_api_fillslots_change_bookings(app, user, freezer):
|
|||
resp = app.post_json(fillslots_url + '&date_end=2022-01-01', params=params)
|
||||
assert resp.json['booking_count'] == 0
|
||||
assert resp.json['cancelled_booking_count'] == 70
|
||||
assert Booking.objects.filter(user_external_id='user_id_2').count() == 34
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id_2',
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 34
|
||||
)
|
||||
|
||||
# past bookings are left in place
|
||||
freezer.move_to('2021-10-04 12:00') # first Monday of october
|
||||
|
@ -2502,14 +2690,33 @@ def test_recurring_events_api_fillslots_change_bookings(app, user, freezer):
|
|||
resp = app.post_json(fillslots_url + '&date_start=2021-10-11&date_end=2022-01-01', params=params)
|
||||
assert resp.json['booking_count'] == 0
|
||||
assert resp.json['cancelled_booking_count'] == 2 # only first week of october was cancelled
|
||||
assert Booking.objects.filter(user_external_id='user_id_2').count() == 32
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id_2',
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 32
|
||||
)
|
||||
|
||||
# passing empty slots cancels all bookings
|
||||
params['slots'] = ''
|
||||
resp = app.post_json(fillslots_url, params=params)
|
||||
assert resp.json['cancelled_booking_count'] == 24
|
||||
assert Booking.objects.filter(user_external_id='user_id_2').count() == 8
|
||||
assert Booking.objects.filter(user_external_id='user_id_2', event__start_datetime__gt=now()).count() == 0
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id_2',
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 8
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id_2',
|
||||
event__start_datetime__gt=now(),
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 0
|
||||
)
|
||||
|
||||
# only recurring events are impacted
|
||||
normal_event = Event.objects.create(
|
||||
|
@ -2521,7 +2728,121 @@ def test_recurring_events_api_fillslots_change_bookings(app, user, freezer):
|
|||
assert Booking.objects.filter(user_external_id='user_id', event=normal_event).count() == 1
|
||||
|
||||
|
||||
def test_recurring_events_api_unbook(app, user, freezer):
|
||||
def test_recurring_events_api_fillslots_update_with_cancelled(app, user, freezer):
|
||||
freezer.move_to('2021-09-06 12:00')
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events', minimal_booking_delay=0)
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
event = Event.objects.create(
|
||||
label='Event',
|
||||
start_datetime=now(),
|
||||
recurrence_days=[0, 1], # Monday, Tuesday
|
||||
places=1,
|
||||
waiting_list_places=1,
|
||||
agenda=agenda,
|
||||
recurrence_end_date=now() + datetime.timedelta(days=21),
|
||||
)
|
||||
event.create_all_recurrences()
|
||||
|
||||
# create cancelled bookings for the user
|
||||
event_1_0 = event.get_or_create_event_recurrence(event.start_datetime)
|
||||
booking_1_0 = Booking.objects.create(event=event_1_0, user_external_id='user_id')
|
||||
booking_1_0.cancel()
|
||||
assert booking_1_0.cancellation_datetime is not None
|
||||
event_1_1 = event.get_or_create_event_recurrence(event.start_datetime + datetime.timedelta(days=1))
|
||||
booking_1_1 = Booking.objects.create(event=event_1_1, user_external_id='user_id')
|
||||
booking_1_1.cancel()
|
||||
assert booking_1_1.cancellation_datetime is not None
|
||||
# and non cancelled bookings for the user
|
||||
event_2_0 = event.get_or_create_event_recurrence(event.start_datetime + datetime.timedelta(days=7))
|
||||
booking_2_0 = Booking.objects.create(event=event_2_0, user_external_id='user_id')
|
||||
assert booking_2_0.cancellation_datetime is None
|
||||
event_2_1 = event.get_or_create_event_recurrence(event.start_datetime + datetime.timedelta(days=8))
|
||||
booking_2_1 = Booking.objects.create(event=event_2_1, user_external_id='user_id')
|
||||
assert booking_2_1.cancellation_datetime is None
|
||||
# secondary booking for this one
|
||||
booking_2_1_secondary = Booking.objects.create(event=event_2_1, primary_booking=booking_2_1)
|
||||
# and bookings for another user
|
||||
Booking.objects.create(event=event_1_0, user_external_id='user_id_foobar')
|
||||
other_booking = Booking.objects.create(event=event_2_0, user_external_id='user_id_foobar')
|
||||
other_booking.cancel()
|
||||
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
fillslots_url = '/api/agendas/recurring-events/fillslots/?agendas=%s&action=update' % agenda.slug
|
||||
params = {'user_external_id': 'user_id'}
|
||||
|
||||
# Book Monday
|
||||
params['slots'] = 'foo-bar@event:0'
|
||||
resp = app.post_json(fillslots_url, params=params)
|
||||
assert resp.json['booking_count'] == 2
|
||||
assert resp.json['cancelled_booking_count'] == 1
|
||||
assert Booking.objects.filter(user_external_id='user_id').count() == 5
|
||||
assert Booking.objects.filter(user_external_id='user_id', cancellation_datetime__isnull=True).count() == 3
|
||||
assert Booking.objects.filter(user_external_id='user_id', event__start_datetime__week_day=2).count() == 3
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id',
|
||||
event__start_datetime__week_day=2,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 3
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(event__start_datetime__week_day=3, primary_booking__isnull=True).count() == 2
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id',
|
||||
event__start_datetime__week_day=3,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 0
|
||||
)
|
||||
|
||||
assert Booking.objects.filter(pk=booking_1_0.pk).exists() is False # cancelled booking deleted
|
||||
booking_1_1.refresh_from_db()
|
||||
booking_2_0.refresh_from_db()
|
||||
booking_2_1.refresh_from_db()
|
||||
booking_2_1_secondary.refresh_from_db()
|
||||
assert booking_1_1.cancellation_datetime is not None
|
||||
assert booking_2_0.cancellation_datetime is None
|
||||
assert booking_2_1.cancellation_datetime is not None
|
||||
assert booking_2_1_secondary.cancellation_datetime is not None
|
||||
|
||||
# Book Tuesday
|
||||
params['slots'] = 'foo-bar@event:1'
|
||||
resp = app.post_json(fillslots_url, params=params)
|
||||
assert resp.json['booking_count'] == 3
|
||||
assert resp.json['cancelled_booking_count'] == 3
|
||||
assert Booking.objects.filter(user_external_id='user_id').count() == 6
|
||||
assert Booking.objects.filter(user_external_id='user_id', cancellation_datetime__isnull=True).count() == 3
|
||||
assert Booking.objects.filter(user_external_id='user_id', event__start_datetime__week_day=2).count() == 3
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id',
|
||||
event__start_datetime__week_day=2,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 0
|
||||
)
|
||||
assert Booking.objects.filter(user_external_id='user_id', event__start_datetime__week_day=3).count() == 3
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id',
|
||||
event__start_datetime__week_day=3,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 3
|
||||
)
|
||||
|
||||
assert Booking.objects.filter(pk=booking_1_0.pk).exists() is False # cancelled booking deleted
|
||||
assert Booking.objects.filter(pk=booking_1_1.pk).exists() is False # cancelled booking deleted
|
||||
assert Booking.objects.filter(pk=booking_2_1.pk).exists() is False # cancelled booking deleted
|
||||
assert Booking.objects.filter(pk=booking_2_1_secondary.pk).exists() is False # cancelled booking deleted
|
||||
booking_2_0.refresh_from_db()
|
||||
assert booking_2_0.cancellation_datetime is not None
|
||||
|
||||
|
||||
def test_recurring_events_api_fillslots_unbook(app, user, freezer):
|
||||
freezer.move_to('2021-09-06 12:00')
|
||||
agenda = Agenda.objects.create(
|
||||
label='Foo bar', kind='events', minimal_booking_delay=0, maximal_booking_delay=0
|
||||
|
@ -2569,9 +2890,21 @@ def test_recurring_events_api_unbook(app, user, freezer):
|
|||
assert resp.json['booking_count'] == 0
|
||||
assert resp.json['cancelled_booking_count'] == 4
|
||||
|
||||
assert Booking.objects.count() == 152
|
||||
assert Booking.objects.filter(event__primary_event=event).count() == 100
|
||||
assert Booking.objects.filter(event__primary_event=sunday_event).count() == 52
|
||||
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 152
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=event,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 100
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=sunday_event,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 52
|
||||
)
|
||||
|
||||
# remove delays
|
||||
agenda.minimal_booking_delay = 0
|
||||
|
@ -2582,9 +2915,28 @@ def test_recurring_events_api_unbook(app, user, freezer):
|
|||
assert resp.json['booking_count'] == 0
|
||||
assert resp.json['cancelled_booking_count'] == 48
|
||||
|
||||
assert Booking.objects.count() == 104
|
||||
assert Booking.objects.filter(event__primary_event=event).count() == 52
|
||||
assert Booking.objects.filter(event__primary_event=sunday_event).count() == 52
|
||||
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 104
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=event,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 52
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=event,
|
||||
cancellation_datetime__isnull=False,
|
||||
).count()
|
||||
== 52
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=sunday_event,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 52
|
||||
)
|
||||
|
||||
params['slots'] = 'foo-bar@sunday-event:6'
|
||||
resp = app.post_json(
|
||||
|
@ -2593,15 +2945,42 @@ def test_recurring_events_api_unbook(app, user, freezer):
|
|||
assert resp.json['booking_count'] == 0
|
||||
assert resp.json['cancelled_booking_count'] == 9
|
||||
|
||||
assert Booking.objects.count() == 95
|
||||
assert Booking.objects.filter(event__primary_event=event).count() == 52
|
||||
assert Booking.objects.filter(event__primary_event=sunday_event).count() == 43
|
||||
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 95
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=event,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 52
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=event,
|
||||
cancellation_datetime__isnull=False,
|
||||
).count()
|
||||
== 52
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=sunday_event,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 43
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=sunday_event,
|
||||
cancellation_datetime__isnull=False,
|
||||
).count()
|
||||
== 9
|
||||
)
|
||||
assert not Booking.objects.filter(
|
||||
event__primary_event=sunday_event,
|
||||
event__start_datetime__range=(
|
||||
datetime.date(year=2022, month=1, day=1),
|
||||
datetime.date(year=2022, month=3, day=1),
|
||||
),
|
||||
cancellation_datetime__isnull=True,
|
||||
).exists()
|
||||
|
||||
freezer.move_to('2022-01-01 12:00')
|
||||
|
@ -2611,12 +2990,26 @@ def test_recurring_events_api_unbook(app, user, freezer):
|
|||
assert resp.json['booking_count'] == 0
|
||||
assert resp.json['cancelled_booking_count'] == 35
|
||||
|
||||
assert Booking.objects.count() == 60
|
||||
assert Booking.objects.filter(event__primary_event=event).count() == 17
|
||||
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 60
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=event,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 17
|
||||
)
|
||||
assert not Booking.objects.filter(
|
||||
event__primary_event=event, event__start_datetime__gt=datetime.date(year=2022, month=1, day=1)
|
||||
event__primary_event=event,
|
||||
event__start_datetime__gt=datetime.date(year=2022, month=1, day=1),
|
||||
cancellation_datetime__isnull=True,
|
||||
).exists()
|
||||
assert Booking.objects.filter(event__primary_event=sunday_event).count() == 43
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=sunday_event,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 43
|
||||
)
|
||||
|
||||
# unbooking when there are no bookings does nothing
|
||||
params['user_external_id'] = 'user_id_2'
|
||||
|
@ -2625,6 +3018,117 @@ def test_recurring_events_api_unbook(app, user, freezer):
|
|||
assert resp.json['cancelled_booking_count'] == 0
|
||||
|
||||
|
||||
def test_recurring_events_api_fillslots_unbook_with_cancelled(app, user, freezer):
|
||||
freezer.move_to('2021-09-06 12:00')
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
event = Event.objects.create(
|
||||
label='Event',
|
||||
start_datetime=now(),
|
||||
recurrence_days=[0, 1], # Monday, Tuesday
|
||||
places=1,
|
||||
waiting_list_places=1,
|
||||
agenda=agenda,
|
||||
recurrence_end_date=now() + datetime.timedelta(days=21),
|
||||
)
|
||||
event.create_all_recurrences()
|
||||
|
||||
# create cancelled bookings for the user
|
||||
event_1_0 = event.get_or_create_event_recurrence(event.start_datetime)
|
||||
booking_1_0 = Booking.objects.create(event=event_1_0, user_external_id='user_id')
|
||||
booking_1_0.cancel()
|
||||
assert booking_1_0.cancellation_datetime is not None
|
||||
event_1_1 = event.get_or_create_event_recurrence(event.start_datetime + datetime.timedelta(days=1))
|
||||
booking_1_1 = Booking.objects.create(event=event_1_1, user_external_id='user_id')
|
||||
booking_1_1.cancel()
|
||||
assert booking_1_1.cancellation_datetime is not None
|
||||
# and non cancelled bookings for the user
|
||||
event_2_0 = event.get_or_create_event_recurrence(event.start_datetime + datetime.timedelta(days=7))
|
||||
booking_2_0 = Booking.objects.create(event=event_2_0, user_external_id='user_id')
|
||||
assert booking_2_0.cancellation_datetime is None
|
||||
event_2_1 = event.get_or_create_event_recurrence(event.start_datetime + datetime.timedelta(days=8))
|
||||
booking_2_1 = Booking.objects.create(event=event_2_1, user_external_id='user_id')
|
||||
assert booking_2_1.cancellation_datetime is None
|
||||
# and bookings for another user
|
||||
Booking.objects.create(event=event_1_0, user_external_id='user_id_foobar')
|
||||
other_booking = Booking.objects.create(event=event_2_0, user_external_id='user_id_foobar')
|
||||
other_booking.cancel()
|
||||
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
fillslots_url = '/api/agendas/recurring-events/fillslots/?agendas=%s&action=unbook' % agenda.slug
|
||||
params = {'user_external_id': 'user_id'}
|
||||
|
||||
# unbook Monday
|
||||
params['slots'] = 'foo-bar@event:0'
|
||||
resp = app.post_json(fillslots_url, params=params)
|
||||
assert resp.json['booking_count'] == 0
|
||||
assert resp.json['cancelled_booking_count'] == 1
|
||||
assert Booking.objects.filter(user_external_id='user_id').count() == 4
|
||||
assert Booking.objects.filter(user_external_id='user_id', cancellation_datetime__isnull=True).count() == 1
|
||||
assert Booking.objects.filter(user_external_id='user_id', event__start_datetime__week_day=2).count() == 2
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id',
|
||||
event__start_datetime__week_day=2,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 0
|
||||
)
|
||||
assert Booking.objects.filter(user_external_id='user_id', event__start_datetime__week_day=3).count() == 2
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id',
|
||||
event__start_datetime__week_day=3,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 1
|
||||
)
|
||||
|
||||
booking_1_0.refresh_from_db()
|
||||
booking_1_1.refresh_from_db()
|
||||
booking_2_0.refresh_from_db()
|
||||
booking_2_1.refresh_from_db()
|
||||
assert booking_1_0.cancellation_datetime is not None
|
||||
assert booking_1_1.cancellation_datetime is not None
|
||||
assert booking_2_0.cancellation_datetime is not None
|
||||
assert booking_2_1.cancellation_datetime is None
|
||||
|
||||
# unbook Tuesday
|
||||
params['slots'] = 'foo-bar@event:1'
|
||||
resp = app.post_json(fillslots_url, params=params)
|
||||
assert resp.json['booking_count'] == 0
|
||||
assert resp.json['cancelled_booking_count'] == 1
|
||||
assert Booking.objects.filter(user_external_id='user_id').count() == 4
|
||||
assert Booking.objects.filter(user_external_id='user_id', cancellation_datetime__isnull=True).count() == 0
|
||||
assert Booking.objects.filter(user_external_id='user_id', event__start_datetime__week_day=2).count() == 2
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id',
|
||||
event__start_datetime__week_day=2,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 0
|
||||
)
|
||||
assert Booking.objects.filter(user_external_id='user_id', event__start_datetime__week_day=3).count() == 2
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
user_external_id='user_id',
|
||||
event__start_datetime__week_day=3,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 0
|
||||
)
|
||||
|
||||
booking_1_0.refresh_from_db()
|
||||
booking_1_1.refresh_from_db()
|
||||
booking_2_0.refresh_from_db()
|
||||
booking_2_1.refresh_from_db()
|
||||
assert booking_1_0.cancellation_datetime is not None
|
||||
assert booking_1_1.cancellation_datetime is not None
|
||||
assert booking_2_0.cancellation_datetime is not None
|
||||
assert booking_2_1.cancellation_datetime is not None
|
||||
|
||||
|
||||
@pytest.mark.freeze_time('2021-09-06 12:00')
|
||||
def test_recurring_events_api_fillslots_subscribed(app, user):
|
||||
category = Category.objects.create(label='Category A')
|
||||
|
@ -2705,12 +3209,20 @@ def test_recurring_events_api_fillslots_subscribed(app, user):
|
|||
resp = app.post_json(fillslots_url % 'all', params=params)
|
||||
assert resp.json['booking_count'] == 12
|
||||
assert resp.json['cancelled_booking_count'] == 10
|
||||
assert Booking.objects.count() == 12
|
||||
booked_events_first_agenda = Event.objects.filter(primary_event=event, booking__isnull=False)
|
||||
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 12
|
||||
booked_events_first_agenda = Event.objects.filter(
|
||||
primary_event=event,
|
||||
booking__isnull=False,
|
||||
booking__cancellation_datetime__isnull=True,
|
||||
)
|
||||
assert [
|
||||
x.strftime('%d/%m/%Y') for x in booked_events_first_agenda.values_list('start_datetime', flat=True)
|
||||
] == ['21/09/2021', '28/09/2021', '05/10/2021', '12/10/2021', '19/10/2021']
|
||||
booked_events_second_agenda = Event.objects.filter(primary_event=sunday_event, booking__isnull=False)
|
||||
booked_events_second_agenda = Event.objects.filter(
|
||||
primary_event=sunday_event,
|
||||
booking__isnull=False,
|
||||
booking__cancellation_datetime__isnull=True,
|
||||
)
|
||||
assert [
|
||||
x.strftime('%d/%m/%Y') for x in booked_events_second_agenda.values_list('start_datetime', flat=True)
|
||||
] == ['19/12/2021', '26/12/2021', '02/01/2022', '09/01/2022', '16/01/2022', '23/01/2022', '30/01/2022']
|
||||
|
@ -2732,8 +3244,12 @@ def test_recurring_events_api_fillslots_subscribed(app, user):
|
|||
params = {'user_external_id': 'yyy', 'slots': 'second-agenda@sunday-event:6'}
|
||||
resp = app.post_json(fillslots_url % 'category-b', params=params)
|
||||
assert resp.json['booking_count'] == 3
|
||||
assert Booking.objects.count() == 15
|
||||
booked_events_user_yyy = Event.objects.filter(primary_event=sunday_event, booking__user_external_id='yyy')
|
||||
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 15
|
||||
booked_events_user_yyy = Event.objects.filter(
|
||||
primary_event=sunday_event,
|
||||
booking__user_external_id='yyy',
|
||||
booking__cancellation_datetime__isnull=True,
|
||||
)
|
||||
assert [
|
||||
x.strftime('%d/%m/%Y') for x in booked_events_user_yyy.values_list('start_datetime', flat=True)
|
||||
] == ['12/09/2021', '07/11/2021', '14/11/2021']
|
||||
|
@ -2805,10 +3321,28 @@ def test_recurring_events_api_fillslots_multiple_agendas(app, user):
|
|||
assert resp.json['booking_count'] == 0
|
||||
assert resp.json['cancelled_booking_count'] == 2
|
||||
|
||||
assert Booking.objects.count() == 19
|
||||
assert Booking.objects.filter(event__primary_event=event_a).count() == 12
|
||||
assert Booking.objects.filter(event__primary_event=event_b).count() == 0
|
||||
assert Booking.objects.filter(event__primary_event=event_c).count() == 7
|
||||
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 19
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=event_a,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 12
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=event_b,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 0
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=event_c,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 7
|
||||
)
|
||||
|
||||
# update bookings
|
||||
params = {'user_external_id': 'user_id', 'slots': 'first-agenda@b:1'}
|
||||
|
@ -2816,9 +3350,27 @@ def test_recurring_events_api_fillslots_multiple_agendas(app, user):
|
|||
|
||||
assert resp.json['booking_count'] == 5
|
||||
assert resp.json['cancelled_booking_count'] == 19
|
||||
assert Booking.objects.filter(event__primary_event=event_a).count() == 0
|
||||
assert Booking.objects.filter(event__primary_event=event_b).count() == 5
|
||||
assert Booking.objects.filter(event__primary_event=event_c).count() == 0
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=event_a,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 0
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=event_b,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 5
|
||||
)
|
||||
assert (
|
||||
Booking.objects.filter(
|
||||
event__primary_event=event_c,
|
||||
cancellation_datetime__isnull=True,
|
||||
).count()
|
||||
== 0
|
||||
)
|
||||
|
||||
# error if slot's agenda is not in querystring
|
||||
resp = app.post_json(fillslots_url % ('update', 'second-agenda'), params=params, status=400)
|
||||
|
@ -2850,7 +3402,7 @@ def test_recurring_events_api_fillslots_multiple_agendas_queries(app, user):
|
|||
params={'slots': events_to_book, 'user_external_id': 'user'},
|
||||
)
|
||||
assert resp.json['booking_count'] == 180
|
||||
assert len(ctx.captured_queries) == 16
|
||||
assert len(ctx.captured_queries) == 17
|
||||
|
||||
|
||||
@pytest.mark.freeze_time('2021-09-06 12:00')
|
||||
|
|
Loading…
Reference in New Issue