api: remove user bookings on subscription date changes (#61065)
This commit is contained in:
parent
b6f7d25808
commit
ad103323ba
|
@ -2029,6 +2029,20 @@ class SubscriptionAPI(APIView):
|
|||
response.update({'err': 0})
|
||||
return Response(response)
|
||||
|
||||
def delete_out_of_period_bookings(self, date_start, date_end):
|
||||
booking_qs = Booking.objects.filter(
|
||||
# remove user bookings for this agenda
|
||||
event__agenda=self.subscription.agenda,
|
||||
user_external_id=self.subscription.user_external_id,
|
||||
# in the requested period
|
||||
event__start_datetime__gt=date_start,
|
||||
event__start_datetime__lt=date_end + datetime.timedelta(days=1),
|
||||
).filter(
|
||||
# but only in the future
|
||||
event__start_datetime__gt=now(),
|
||||
)
|
||||
booking_qs.delete()
|
||||
|
||||
def patch(self, request, *args, **kwargs):
|
||||
serializer = self.serializer_class(self.subscription, data=request.data, partial=True)
|
||||
old_date_start = self.subscription.date_start
|
||||
|
@ -2068,21 +2082,25 @@ class SubscriptionAPI(APIView):
|
|||
self.subscription.extra_data.update(extra_data)
|
||||
self.subscription.save()
|
||||
|
||||
if old_date_start > self.subscription.date_end or old_date_end < self.subscription.date_start:
|
||||
# new period does not overlaps the old one, delete all bookings in the old period
|
||||
self.delete_out_of_period_bookings(old_date_start, old_date_end)
|
||||
else:
|
||||
if old_date_start < self.subscription.date_start:
|
||||
# date start has been postponed, remove all bookings from old start to new start
|
||||
self.delete_out_of_period_bookings(
|
||||
old_date_start, self.subscription.date_start - datetime.timedelta(days=1)
|
||||
)
|
||||
if old_date_end > self.subscription.date_end:
|
||||
# date end has been brought forward, remove all bookings from new end to old end
|
||||
self.delete_out_of_period_bookings(
|
||||
self.subscription.date_end + datetime.timedelta(days=1), old_date_end
|
||||
)
|
||||
|
||||
return self.get(request, *args, **kwargs)
|
||||
|
||||
def delete(self, request, *args, **kwargs):
|
||||
booking_qs = Booking.objects.filter(
|
||||
# remove user bookings for this agenda
|
||||
event__agenda=self.subscription.agenda,
|
||||
user_external_id=self.subscription.user_external_id,
|
||||
# in the period of the deleted subscription
|
||||
event__start_datetime__gt=self.subscription.date_start,
|
||||
event__start_datetime__lt=self.subscription.date_end + datetime.timedelta(days=1),
|
||||
).filter(
|
||||
# but only in the future
|
||||
event__start_datetime__gt=now(),
|
||||
)
|
||||
booking_qs.delete()
|
||||
self.delete_out_of_period_bookings(self.subscription.date_start, self.subscription.date_end)
|
||||
self.subscription.delete()
|
||||
response = {'err': 0}
|
||||
return Response(response)
|
||||
|
|
|
@ -729,3 +729,306 @@ def test_api_patch_subscription_check_dates(app, user):
|
|||
'/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params, status=400
|
||||
)
|
||||
assert resp.json['err_desc'] == 'another subscription overlapping this period already exists'
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'date_now, event_date, user_id, in_waiting_list, cancelled, deleted',
|
||||
[
|
||||
# event in the future, but no booking for the user
|
||||
('2021-09-04 09:59', (2021, 9, 4, 12, 0), 'yyy', False, False, False),
|
||||
# event in the future
|
||||
('2021-09-04 09:59', (2021, 9, 4, 12, 0), 'xxx', False, False, True),
|
||||
('2021-09-04 09:59', (2021, 9, 4, 12, 0), 'xxx', True, False, True),
|
||||
('2021-09-04 09:59', (2021, 9, 4, 12, 0), 'xxx', False, True, True),
|
||||
# event in the past
|
||||
('2021-09-04 10:00', (2021, 9, 4, 12, 0), 'xxx', False, False, False),
|
||||
# event in the future, before the period
|
||||
('2021-08-01 10:00', (2021, 8, 14, 12, 0), 'xxx', False, False, False),
|
||||
('2021-08-01 10:00', (2021, 8, 31, 12, 0), 'xxx', False, False, False),
|
||||
# event in the future, after the period
|
||||
('2021-08-01 10:00', (2021, 10, 1, 12, 0), 'xxx', False, False, False),
|
||||
('2021-08-01 10:00', (2021, 10, 16, 12, 0), 'xxx', False, False, False),
|
||||
],
|
||||
)
|
||||
def test_api_patch_subscription_date_changes_delete_bookings(
|
||||
app, user, freezer, date_now, event_date, user_id, in_waiting_list, cancelled, deleted
|
||||
):
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
||||
subscription = Subscription.objects.create(
|
||||
agenda=agenda,
|
||||
user_external_id='xxx',
|
||||
date_start=datetime.date(year=2021, month=9, day=1),
|
||||
date_end=datetime.date(year=2021, month=9, day=30),
|
||||
)
|
||||
Subscription.objects.create(
|
||||
agenda=agenda,
|
||||
user_external_id='zzz', # another user
|
||||
date_start=datetime.date(year=2021, month=9, day=1),
|
||||
date_end=datetime.date(year=2021, month=9, day=30),
|
||||
)
|
||||
|
||||
other_agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
||||
Subscription.objects.create(
|
||||
agenda=other_agenda,
|
||||
user_external_id='xxx',
|
||||
date_start=datetime.date(year=2021, month=9, day=1),
|
||||
date_end=datetime.date(year=2021, month=10, day=1),
|
||||
)
|
||||
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
|
||||
freezer.move_to(date_now)
|
||||
event = Event.objects.create(
|
||||
agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
|
||||
)
|
||||
booking = Booking.objects.create(
|
||||
event=event,
|
||||
user_external_id=user_id,
|
||||
in_waiting_list=in_waiting_list,
|
||||
cancellation_datetime=(now() if cancelled else None),
|
||||
)
|
||||
|
||||
# date_start is postponed, date_end is brought forward
|
||||
params = {
|
||||
'date_start': '2021-09-05',
|
||||
'date_end': '2021-09-25',
|
||||
}
|
||||
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
|
||||
assert resp.json['err'] == 0
|
||||
assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'event_date, deleted',
|
||||
[
|
||||
# just before old first day
|
||||
((2021, 8, 31, 12, 00), False),
|
||||
# old first day
|
||||
((2021, 9, 1, 12, 00), True),
|
||||
# old last day
|
||||
((2021, 9, 30, 12, 00), True),
|
||||
# just after old last day
|
||||
((2021, 10, 1, 12, 00), False),
|
||||
],
|
||||
)
|
||||
def test_api_patch_subscription_date_changes_delete_bookings_forwards_no_overlaps(
|
||||
app, user, freezer, event_date, deleted
|
||||
):
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
||||
subscription = Subscription.objects.create(
|
||||
agenda=agenda,
|
||||
user_external_id='xxx',
|
||||
date_start=datetime.date(year=2021, month=9, day=1),
|
||||
date_end=datetime.date(year=2021, month=9, day=30),
|
||||
)
|
||||
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
|
||||
freezer.move_to('2021-08-01 10:00')
|
||||
event = Event.objects.create(
|
||||
agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
|
||||
)
|
||||
booking = Booking.objects.create(
|
||||
event=event,
|
||||
user_external_id='xxx',
|
||||
)
|
||||
# subscription moved forwards, no overlaps
|
||||
params = {
|
||||
'date_start': '2021-11-01',
|
||||
'date_end': '2021-11-30',
|
||||
}
|
||||
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
|
||||
assert resp.json['err'] == 0
|
||||
assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'event_date, deleted',
|
||||
[
|
||||
# just before old first day
|
||||
((2021, 8, 31, 12, 00), False),
|
||||
# old first day
|
||||
((2021, 9, 1, 12, 00), True),
|
||||
# old last day
|
||||
((2021, 9, 30, 12, 00), True),
|
||||
# just after old last day
|
||||
((2021, 10, 1, 12, 00), False),
|
||||
],
|
||||
)
|
||||
def test_api_patch_subscription_date_changes_delete_bookings_backwards_no_overlaps(
|
||||
app, user, freezer, event_date, deleted
|
||||
):
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
||||
subscription = Subscription.objects.create(
|
||||
agenda=agenda,
|
||||
user_external_id='xxx',
|
||||
date_start=datetime.date(year=2021, month=9, day=1),
|
||||
date_end=datetime.date(year=2021, month=9, day=30),
|
||||
)
|
||||
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
|
||||
freezer.move_to('2021-06-01 10:00')
|
||||
event = Event.objects.create(
|
||||
agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
|
||||
)
|
||||
booking = Booking.objects.create(
|
||||
event=event,
|
||||
user_external_id='xxx',
|
||||
)
|
||||
# subscription moved backwards, no overlaps
|
||||
params = {
|
||||
'date_start': '2021-07-01',
|
||||
'date_end': '2021-07-31',
|
||||
}
|
||||
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
|
||||
assert resp.json['err'] == 0
|
||||
assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'event_date, deleted',
|
||||
[
|
||||
# just before old first day
|
||||
((2021, 8, 31, 12, 00), False),
|
||||
# old first day
|
||||
((2021, 9, 1, 12, 00), True),
|
||||
# just before new first day
|
||||
((2021, 9, 4, 12, 00), True),
|
||||
# new first day
|
||||
((2021, 9, 5, 12, 00), False),
|
||||
# new last day
|
||||
((2021, 9, 25, 12, 00), False),
|
||||
# just after new last day
|
||||
((2021, 9, 26, 12, 00), True),
|
||||
# old last day
|
||||
((2021, 9, 30, 12, 00), True),
|
||||
# just after old last day
|
||||
((2021, 10, 1, 12, 00), False),
|
||||
],
|
||||
)
|
||||
def test_api_patch_subscription_date_changes_delete_bookings_shorter_period(
|
||||
app, user, freezer, event_date, deleted
|
||||
):
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
||||
subscription = Subscription.objects.create(
|
||||
agenda=agenda,
|
||||
user_external_id='xxx',
|
||||
date_start=datetime.date(year=2021, month=9, day=1),
|
||||
date_end=datetime.date(year=2021, month=9, day=30),
|
||||
)
|
||||
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
|
||||
freezer.move_to('2021-08-01 10:00')
|
||||
event = Event.objects.create(
|
||||
agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
|
||||
)
|
||||
booking = Booking.objects.create(
|
||||
event=event,
|
||||
user_external_id='xxx',
|
||||
)
|
||||
# date_start is postponed, date_end is brought forward
|
||||
params = {
|
||||
'date_start': '2021-09-05',
|
||||
'date_end': '2021-09-25',
|
||||
}
|
||||
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
|
||||
assert resp.json['err'] == 0
|
||||
assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'event_date, deleted',
|
||||
[
|
||||
# just before old first day
|
||||
((2021, 8, 31, 12, 00), False),
|
||||
# old first day
|
||||
((2021, 9, 1, 12, 00), True),
|
||||
# just before new first day
|
||||
((2021, 9, 14, 12, 00), True),
|
||||
# new first day
|
||||
((2021, 9, 15, 12, 00), False),
|
||||
# old last day
|
||||
((2021, 9, 30, 12, 00), False),
|
||||
# just after old last day
|
||||
((2021, 10, 1, 12, 00), False),
|
||||
],
|
||||
)
|
||||
def test_api_patch_subscription_date_changes_delete_bookings_forwards_with_overlaps(
|
||||
app, user, freezer, event_date, deleted
|
||||
):
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
||||
subscription = Subscription.objects.create(
|
||||
agenda=agenda,
|
||||
user_external_id='xxx',
|
||||
date_start=datetime.date(year=2021, month=9, day=1),
|
||||
date_end=datetime.date(year=2021, month=9, day=30),
|
||||
)
|
||||
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
|
||||
freezer.move_to('2021-08-01 10:00')
|
||||
event = Event.objects.create(
|
||||
agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
|
||||
)
|
||||
booking = Booking.objects.create(
|
||||
event=event,
|
||||
user_external_id='xxx',
|
||||
)
|
||||
# subscription moved forwards, with overlaps
|
||||
params = {
|
||||
'date_start': '2021-09-15',
|
||||
'date_end': '2021-10-15',
|
||||
}
|
||||
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
|
||||
assert resp.json['err'] == 0
|
||||
assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'event_date, deleted',
|
||||
[
|
||||
# just before old first day
|
||||
((2021, 8, 31, 12, 00), False),
|
||||
# old first day
|
||||
((2021, 9, 1, 12, 00), False),
|
||||
# new last day
|
||||
((2021, 9, 15, 12, 00), False),
|
||||
# just after new last day
|
||||
((2021, 9, 16, 12, 00), True),
|
||||
# old last day
|
||||
((2021, 9, 30, 12, 00), True),
|
||||
# just after old last day
|
||||
((2021, 10, 1, 12, 00), False),
|
||||
],
|
||||
)
|
||||
def test_api_patch_subscription_date_changes_delete_bookings_backwards_with_overlaps(
|
||||
app, user, freezer, event_date, deleted
|
||||
):
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
||||
subscription = Subscription.objects.create(
|
||||
agenda=agenda,
|
||||
user_external_id='xxx',
|
||||
date_start=datetime.date(year=2021, month=9, day=1),
|
||||
date_end=datetime.date(year=2021, month=9, day=30),
|
||||
)
|
||||
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
|
||||
freezer.move_to('2021-08-01 10:00')
|
||||
event = Event.objects.create(
|
||||
agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
|
||||
)
|
||||
booking = Booking.objects.create(
|
||||
event=event,
|
||||
user_external_id='xxx',
|
||||
)
|
||||
# subscription moved backwards, with overlaps
|
||||
params = {
|
||||
'date_start': '2021-08-15',
|
||||
'date_end': '2021-09-15',
|
||||
}
|
||||
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
|
||||
assert resp.json['err'] == 0
|
||||
assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
|
||||
|
|
Loading…
Reference in New Issue