api: update user bookings extra_data on subscription update (#61065)
This commit is contained in:
parent
ad103323ba
commit
b6e141b9c3
|
@ -18,11 +18,13 @@ import collections
|
|||
import copy
|
||||
import datetime
|
||||
import itertools
|
||||
import json
|
||||
import uuid
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import transaction
|
||||
from django.db.models import BooleanField, Count, ExpressionWrapper, F, Prefetch, Q
|
||||
from django.db.models.expressions import RawSQL
|
||||
from django.db.models.functions import TruncDay
|
||||
from django.http import Http404, HttpResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
@ -2076,11 +2078,6 @@ class SubscriptionAPI(APIView):
|
|||
raise APIErrorBadRequest(N_('it is not possible to change user_external_id value'))
|
||||
|
||||
serializer.save()
|
||||
extra_data = {k: v for k, v in request.data.items() if k not in serializer.validated_data}
|
||||
if extra_data:
|
||||
self.subscription.extra_data = self.subscription.extra_data or {}
|
||||
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
|
||||
|
@ -2097,6 +2094,26 @@ class SubscriptionAPI(APIView):
|
|||
self.subscription.date_end + datetime.timedelta(days=1), old_date_end
|
||||
)
|
||||
|
||||
extra_data = {k: v for k, v in request.data.items() if k not in serializer.validated_data}
|
||||
if extra_data:
|
||||
self.subscription.extra_data = self.subscription.extra_data or {}
|
||||
self.subscription.extra_data.update(extra_data)
|
||||
self.subscription.save()
|
||||
# update bookings inside the new period (other bookings were deleted)
|
||||
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 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(),
|
||||
).update(
|
||||
extra_data=RawSQL("COALESCE(extra_data, '{}'::jsonb) || %s::jsonb", (json.dumps(extra_data),))
|
||||
)
|
||||
|
||||
return self.get(request, *args, **kwargs)
|
||||
|
||||
def delete(self, request, *args, **kwargs):
|
||||
|
|
|
@ -1032,3 +1032,83 @@ def test_api_patch_subscription_date_changes_delete_bookings_backwards_with_over
|
|||
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(
|
||||
'date_now, event_date, user_id, in_waiting_list, cancelled, updated',
|
||||
[
|
||||
# event in the future, but no booking for the user
|
||||
('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'yyy', False, False, False),
|
||||
# event in the future
|
||||
('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'xxx', False, False, True),
|
||||
('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'xxx', True, False, True),
|
||||
('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'xxx', False, True, True),
|
||||
# event in the past
|
||||
('2021-09-01 10:00', (2021, 9, 1, 12, 0), 'xxx', False, False, False),
|
||||
# event in the future
|
||||
('2021-08-01 10:00', (2021, 9, 1, 12, 0), 'xxx', False, False, True),
|
||||
('2021-08-01 10:00', (2021, 9, 30, 12, 0), 'xxx', False, False, True),
|
||||
# event in the future, before the period
|
||||
('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),
|
||||
],
|
||||
)
|
||||
def test_api_patch_subscription_update_bookings_extra_data(
|
||||
app, user, freezer, date_now, event_date, user_id, in_waiting_list, cancelled, updated
|
||||
):
|
||||
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(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),
|
||||
)
|
||||
|
||||
# extra_data is None
|
||||
params = {
|
||||
'foo': 'bar',
|
||||
}
|
||||
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
|
||||
assert resp.json['err'] == 0
|
||||
booking.refresh_from_db()
|
||||
if updated:
|
||||
assert booking.extra_data == {'foo': 'bar'}
|
||||
else:
|
||||
assert booking.extra_data is None
|
||||
booking.extra_data = {'some': 'thing'}
|
||||
booking.save()
|
||||
|
||||
# extra_data is not None, update
|
||||
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
|
||||
assert resp.json['err'] == 0
|
||||
booking.refresh_from_db()
|
||||
if updated:
|
||||
assert booking.extra_data == {'foo': 'bar', 'some': 'thing'}
|
||||
else:
|
||||
assert booking.extra_data == {'some': 'thing'}
|
||||
|
||||
# extra_data is not None, merge
|
||||
params = {
|
||||
'foo': 'bar2',
|
||||
}
|
||||
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
|
||||
assert resp.json['err'] == 0
|
||||
booking.refresh_from_db()
|
||||
if updated:
|
||||
assert booking.extra_data == {'foo': 'bar2', 'some': 'thing'}
|
||||
else:
|
||||
assert booking.extra_data == {'some': 'thing'}
|
||||
|
|
Loading…
Reference in New Issue