api: cancel booking in agendas events fillslots - instead of delete (#61066)

This commit is contained in:
Lauréline Guérin 2022-02-07 13:53:04 +01:00
parent b61a867667
commit 290e4a9e66
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
2 changed files with 174 additions and 43 deletions

View File

@ -1928,7 +1928,11 @@ class MultipleAgendasEventsFillslots(EventsFillslots):
return events
def get_already_booked_events(self, user_external_id):
return Event.objects.filter(agenda__in=self.agendas, booking__user_external_id=user_external_id)
return Event.objects.filter(
agenda__in=self.agendas,
booking__user_external_id=user_external_id,
booking__cancellation_datetime__isnull=True,
)
def get_agendas_by_ids(self):
return {a.pk: a for a in self.agendas}

View File

@ -3685,7 +3685,7 @@ def test_api_events_fillslots_preserve_past_bookings(app, user, freezer):
assert resp.json['booking_count'] == 0
assert resp.json['cancelled_booking_count'] == 1
assert event.booking_set.count() == 1
assert second_event.booking_set.count() == 0
assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
@pytest.mark.freeze_time('2021-09-06 12:00')
@ -3713,16 +3713,16 @@ def test_api_events_fillslots_preserve_out_of_delays_bookings(app, user, freezer
resp = app.post_json(fillslots_url, params=params)
assert resp.json['booking_count'] == 0
assert resp.json['cancelled_booking_count'] == 0
assert event.booking_set.count() == 1
assert second_event.booking_set.count() == 1
assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
booking = event.booking_set.get()
# except if we want to bypass delays
params = {'user_external_id': 'user_id', 'slots': 'event-2', 'bypass_delays': True}
resp = app.post_json(fillslots_url, params=params)
assert resp.json['booking_count'] == 0
assert resp.json['cancelled_booking_count'] == 1
assert event.booking_set.count() == 0
assert second_event.booking_set.count() == 1
assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
booking.save() # reset
# cancel all bookings in delays
@ -3731,14 +3731,14 @@ def test_api_events_fillslots_preserve_out_of_delays_bookings(app, user, freezer
assert resp.json['booking_count'] == 0
assert resp.json['cancelled_booking_count'] == 1
assert event.booking_set.count() == 1
assert second_event.booking_set.count() == 0
assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
# bypass delays
params = {'user_external_id': 'user_id', 'slots': '', 'bypass_delays': True}
resp = app.post_json(fillslots_url, params=params)
assert resp.json['booking_count'] == 0
assert resp.json['cancelled_booking_count'] == 1
assert event.booking_set.count() == 0
assert second_event.booking_set.count() == 0
assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
booking.save() # reset
# book only second event while first event is out of delay with multiple agendas API
@ -3753,8 +3753,8 @@ def test_api_events_fillslots_preserve_out_of_delays_bookings(app, user, freezer
resp = app.post_json('/api/agendas/events/fillslots/?agendas=foo-bar', params=params)
assert resp.json['booking_count'] == 0
assert resp.json['cancelled_booking_count'] == 1
assert event.booking_set.count() == 0
assert second_event.booking_set.count() == 1
assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
booking.save() # reset
# book only first event while second event is out of delay
@ -3763,38 +3763,38 @@ def test_api_events_fillslots_preserve_out_of_delays_bookings(app, user, freezer
resp = app.post_json(fillslots_url, params=params)
assert resp.json['booking_count'] == 0
assert resp.json['cancelled_booking_count'] == 0
assert event.booking_set.count() == 1
assert second_event.booking_set.count() == 1
assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
# bypass_delays has no effect on maximal_booking_delay
params = {'user_external_id': 'user_id', 'slots': 'event', 'bypass_delays': True}
resp = app.post_json(fillslots_url, params=params)
assert resp.json['booking_count'] == 0
assert resp.json['cancelled_booking_count'] == 0
assert event.booking_set.count() == 1
assert second_event.booking_set.count() == 1
assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
# cancel all bookings in delays
params = {'user_external_id': 'user_id', 'slots': ''}
resp = app.post_json(fillslots_url, params=params)
assert resp.json['booking_count'] == 0
assert resp.json['cancelled_booking_count'] == 1
assert event.booking_set.count() == 0
assert second_event.booking_set.count() == 1
assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
# book only first event while second event is out of delay with multiple agendas API
params = {'user_external_id': 'user_id', 'slots': 'foo-bar@event'}
resp = app.post_json('/api/agendas/events/fillslots/?agendas=foo-bar', params=params)
assert resp.json['booking_count'] == 1
assert resp.json['cancelled_booking_count'] == 0
assert event.booking_set.count() == 1
assert second_event.booking_set.count() == 1
assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
# bypass_delays has no effect on maximal_booking_delay
params = {'user_external_id': 'user_id', 'slots': 'foo-bar@event', 'bypass_delays': True}
resp = app.post_json('/api/agendas/events/fillslots/?agendas=foo-bar', params=params)
assert resp.json['booking_count'] == 0
assert resp.json['cancelled_booking_count'] == 0
assert event.booking_set.count() == 1
assert second_event.booking_set.count() == 1
assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
@pytest.mark.freeze_time('2021-09-06 12:00')
@ -3828,8 +3828,8 @@ def test_api_events_fillslots_multiple_agendas(app, user):
assert len(resp.json['booked_events']) == 2
assert resp.json['booked_events'][0]['id'] == 'first-agenda@event'
assert resp.json['booked_events'][1]['id'] == 'second-agenda@event'
assert first_event.booking_set.count() == 1
assert second_event.booking_set.count() == 1
assert first_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
# booking modification
params = {'user_external_id': 'user_id', 'slots': 'first-agenda@event'}
@ -3837,8 +3837,8 @@ def test_api_events_fillslots_multiple_agendas(app, user):
assert resp.json['booking_count'] == 0
assert len(resp.json['booked_events']) == 0
assert resp.json['cancelled_booking_count'] == 1
assert first_event.booking_set.count() == 1
assert second_event.booking_set.count() == 0
assert first_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
params = {'user_external_id': 'user_id_2', 'slots': event_slugs}
resp = app.post_json('/api/agendas/events/fillslots/?agendas=%s' % agenda_slugs, params=params)
@ -3846,8 +3846,8 @@ def test_api_events_fillslots_multiple_agendas(app, user):
assert len(resp.json['booked_events']) == 2
assert resp.json['booked_events'][0]['id'] == 'first-agenda@event'
assert resp.json['booked_events'][1]['id'] == 'second-agenda@event'
assert first_event.booking_set.count() == 2
assert second_event.booking_set.count() == 1
assert first_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 2
assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
params = {'user_external_id': 'user_id_3', 'slots': event_slugs}
resp = app.post_json('/api/agendas/events/fillslots/?agendas=%s' % agenda_slugs, params=params)
@ -3896,6 +3896,78 @@ def test_api_events_fillslots_multiple_agendas(app, user):
assert resp.json['errors']['slots'] == ['Missing agenda slug in slot @event']
@pytest.mark.freeze_time('2021-09-06 12:00')
def test_api_events_fillslots_multiple_agendas_with_cancelled(app, user):
agenda_1 = Agenda.objects.create(label='Agenda 1', kind='events')
Desk.objects.create(agenda=agenda_1, slug='_exceptions_holder')
event_1 = Event.objects.create(
label='Event 1',
start_datetime=now() + datetime.timedelta(days=1),
places=2,
agenda=agenda_1,
)
agenda_2 = Agenda.objects.create(label='Agenda 2', kind='events')
Desk.objects.create(agenda=agenda_2, slug='_exceptions_holder')
event_2 = Event.objects.create(
label='Event 2',
start_datetime=now() + datetime.timedelta(days=2),
places=2,
agenda=agenda_2,
)
Event.objects.create(
label='Event 3',
start_datetime=now() + datetime.timedelta(days=3),
places=2,
agenda=agenda_2,
)
# create cancelled booking for the user
booking_1 = Booking.objects.create(event=event_1, user_external_id='user_id')
booking_1.cancel()
assert booking_1.cancellation_datetime is not None
# and non cancelled booking for the user
booking_2 = Booking.objects.create(event=event_2, user_external_id='user_id')
assert booking_2.cancellation_datetime is None
# secondary booking for this one
booking_2_secondary = Booking.objects.create(event=event_2, primary_booking=booking_2)
# and bookings for another user
Booking.objects.create(event=event_1, user_external_id='user_id_foobar')
other_booking = Booking.objects.create(event=event_2, user_external_id='user_id_foobar')
other_booking.cancel()
app.authorization = ('Basic', ('john.doe', 'password'))
fillslots_url = '/api/agendas/events/fillslots/?agendas=%s,%s' % (agenda_1.slug, agenda_2.slug)
params = {'user_external_id': 'user_id', 'slots': 'agenda-1@event-1,agenda-2@event-2,agenda-2@event-3'}
resp = app.post_json(fillslots_url, params=params)
assert resp.json['booking_count'] == 2
assert len(resp.json['booked_events']) == 2
assert resp.json['cancelled_booking_count'] == 0
assert resp.json['booked_events'][0]['id'] == 'agenda-1@event-1'
assert resp.json['booked_events'][1]['id'] == 'agenda-2@event-3'
assert Booking.objects.filter(user_external_id='user_id').count() == 3
assert Booking.objects.filter(user_external_id='user_id', cancellation_datetime__isnull=True).count() == 3
assert Booking.objects.filter(pk=booking_1.pk).exists() is False # cancelled booking deleted
booking_2.refresh_from_db()
booking_2_secondary.refresh_from_db()
assert booking_2.cancellation_datetime is None
assert booking_2_secondary.cancellation_datetime is None
params = {'user_external_id': 'user_id', 'slots': 'agenda-2@event-3'}
resp = app.post_json(fillslots_url, params=params)
assert resp.json['booking_count'] == 0
assert resp.json['cancelled_booking_count'] == 2
assert Booking.objects.filter(user_external_id='user_id').count() == 3
assert Booking.objects.filter(user_external_id='user_id', cancellation_datetime__isnull=True).count() == 1
assert Booking.objects.filter(pk=booking_1.pk).exists() is False # cancelled booking deleted
booking_2.refresh_from_db()
booking_2_secondary.refresh_from_db()
assert booking_2.cancellation_datetime is not None
assert booking_2_secondary.cancellation_datetime is not None
def test_api_events_fillslots_multiple_agendas_check_delays(app, user):
agenda = Agenda.objects.create(
label='Foo bar', kind='events', minimal_booking_delay=0, maximal_booking_delay=7
@ -3983,18 +4055,38 @@ def test_api_events_fillslots_multiple_agendas_subscribed(app, user):
params = {'user_external_id': 'xxx', 'slots': 'first-agenda@event,second-agenda@event'}
resp = app.post_json('/api/agendas/events/fillslots/?subscribed=category-a', params=params)
assert resp.json['booking_count'] == 2
assert Event.objects.get(agenda=first_agenda, slug='event').booking_set.count() == 1
assert Event.objects.get(agenda=second_agenda, slug='event').booking_set.count() == 1
assert Booking.objects.count() == 2
assert (
Event.objects.get(agenda=first_agenda, slug='event')
.booking_set.filter(cancellation_datetime__isnull=True)
.count()
== 1
)
assert (
Event.objects.get(agenda=second_agenda, slug='event')
.booking_set.filter(cancellation_datetime__isnull=True)
.count()
== 1
)
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 2
# update bookings for category-a
params = {'user_external_id': 'xxx', 'slots': 'second-agenda@event'}
resp = app.post_json('/api/agendas/events/fillslots/?subscribed=category-a', params=params)
assert resp.json['booking_count'] == 0
assert resp.json['cancelled_booking_count'] == 1
assert Event.objects.get(agenda=first_agenda, slug='event').booking_set.count() == 0
assert Event.objects.get(agenda=second_agenda, slug='event').booking_set.count() == 1
assert Booking.objects.count() == 1
assert (
Event.objects.get(agenda=first_agenda, slug='event')
.booking_set.filter(cancellation_datetime__isnull=True)
.count()
== 0
)
assert (
Event.objects.get(agenda=second_agenda, slug='event')
.booking_set.filter(cancellation_datetime__isnull=True)
.count()
== 1
)
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 1
# try to book event from agenda with no subscription TODO messages
params = {'user_external_id': 'xxx', 'slots': 'third-agenda@event'}
@ -4015,10 +4107,25 @@ def test_api_events_fillslots_multiple_agendas_subscribed(app, user):
params = {'user_external_id': 'xxx', 'slots': 'third-agenda@event'}
resp = app.post_json('/api/agendas/events/fillslots/?subscribed=category-b', params=params)
assert resp.json['booking_count'] == 1
assert Event.objects.get(agenda=first_agenda, slug='event').booking_set.count() == 0
assert Event.objects.get(agenda=second_agenda, slug='event').booking_set.count() == 1
assert Event.objects.get(agenda=third_agenda, slug='event').booking_set.count() == 1
assert Booking.objects.count() == 2
assert (
Event.objects.get(agenda=first_agenda, slug='event')
.booking_set.filter(cancellation_datetime__isnull=True)
.count()
== 0
)
assert (
Event.objects.get(agenda=second_agenda, slug='event')
.booking_set.filter(cancellation_datetime__isnull=True)
.count()
== 1
)
assert (
Event.objects.get(agenda=third_agenda, slug='event')
.booking_set.filter(cancellation_datetime__isnull=True)
.count()
== 1
)
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 2
# add subscription to first agenda (disjoint) spanning event-2
for agenda in (first_agenda, second_agenda):
@ -4033,9 +4140,19 @@ def test_api_events_fillslots_multiple_agendas_subscribed(app, user):
resp = app.post_json('/api/agendas/events/fillslots/?subscribed=all', params=params)
assert resp.json['booking_count'] == 2
assert resp.json['cancelled_booking_count'] == 2
assert Event.objects.get(agenda=first_agenda, slug='event').booking_set.count() == 1
assert Event.objects.get(agenda=second_agenda, slug='event-2').booking_set.count() == 1
assert Booking.objects.count() == 2
assert (
Event.objects.get(agenda=first_agenda, slug='event')
.booking_set.filter(cancellation_datetime__isnull=True)
.count()
== 1
)
assert (
Event.objects.get(agenda=second_agenda, slug='event-2')
.booking_set.filter(cancellation_datetime__isnull=True)
.count()
== 1
)
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 2
# other user
for agenda in (first_agenda, second_agenda):
@ -4049,9 +4166,19 @@ def test_api_events_fillslots_multiple_agendas_subscribed(app, user):
resp = app.post_json('/api/agendas/events/fillslots/?subscribed=all', params=params)
assert resp.json['booking_count'] == 2
assert resp.json['cancelled_booking_count'] == 0
assert Event.objects.get(agenda=first_agenda, slug='event').booking_set.count() == 2
assert Event.objects.get(agenda=second_agenda, slug='event-2').booking_set.count() == 2
assert Booking.objects.count() == 4
assert (
Event.objects.get(agenda=first_agenda, slug='event')
.booking_set.filter(cancellation_datetime__isnull=True)
.count()
== 2
)
assert (
Event.objects.get(agenda=second_agenda, slug='event-2')
.booking_set.filter(cancellation_datetime__isnull=True)
.count()
== 2
)
assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 4
# try to book event outside subscription date range
params = {'user_external_id': 'xxx', 'slots': 'third-agenda@event-2'}