From 69879bdae06bdfbba1f3d2452d07b281a0e2c39d Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Thu, 6 Aug 2020 09:28:35 +0200 Subject: [PATCH] Fix API bug: Do not delete SubEventItems on PATCH request --- src/pretix/api/serializers/event.py | 26 +++++++++++++----------- src/tests/api/test_subevents.py | 31 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/pretix/api/serializers/event.py b/src/pretix/api/serializers/event.py index adee315bc..66950875c 100644 --- a/src/pretix/api/serializers/event.py +++ b/src/pretix/api/serializers/event.py @@ -459,27 +459,29 @@ class SubEventSerializer(I18nAwareModelSerializer): @transaction.atomic def update(self, instance, validated_data): - item_price_overrides_data = validated_data.pop('subeventitem_set') if 'subeventitem_set' in validated_data else {} - variation_price_overrides_data = validated_data.pop('subeventitemvariation_set') if 'subeventitemvariation_set' in validated_data else {} + item_price_overrides_data = validated_data.pop('subeventitem_set') + variation_price_overrides_data = validated_data.pop('subeventitemvariation_set') meta_data = validated_data.pop('meta_data', None) seat_category_mapping = validated_data.pop('seat_category_mapping', None) subevent = super().update(instance, validated_data) - existing_item_overrides = {item.item: item.id for item in SubEventItem.objects.filter(subevent=subevent)} + if item_price_overrides_data is not None: + existing_item_overrides = {item.item: item.id for item in SubEventItem.objects.filter(subevent=subevent)} - for item_price_override_data in item_price_overrides_data: - id = existing_item_overrides.pop(item_price_override_data['item'], None) - SubEventItem(id=id, subevent=subevent, **item_price_override_data).save() + for item_price_override_data in item_price_overrides_data: + id = existing_item_overrides.pop(item_price_override_data['item'], None) + SubEventItem(id=id, subevent=subevent, **item_price_override_data).save() - SubEventItem.objects.filter(id__in=existing_item_overrides.values()).delete() + SubEventItem.objects.filter(id__in=existing_item_overrides.values()).delete() - existing_variation_overrides = {item.variation: item.id for item in SubEventItemVariation.objects.filter(subevent=subevent)} + if variation_price_overrides_data is not None: + existing_variation_overrides = {item.variation: item.id for item in SubEventItemVariation.objects.filter(subevent=subevent)} - for variation_price_override_data in variation_price_overrides_data: - id = existing_variation_overrides.pop(variation_price_override_data['variation'], None) - SubEventItemVariation(id=id, subevent=subevent, **variation_price_override_data).save() + for variation_price_override_data in variation_price_overrides_data: + id = existing_variation_overrides.pop(variation_price_override_data['variation'], None) + SubEventItemVariation(id=id, subevent=subevent, **variation_price_override_data).save() - SubEventItemVariation.objects.filter(id__in=existing_variation_overrides.values()).delete() + SubEventItemVariation.objects.filter(id__in=existing_variation_overrides.values()).delete() # Meta data if meta_data is not None: diff --git a/src/tests/api/test_subevents.py b/src/tests/api/test_subevents.py index 31659aafb..5c9c16602 100644 --- a/src/tests/api/test_subevents.py +++ b/src/tests/api/test_subevents.py @@ -562,6 +562,37 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2, assert resp.content.decode() == '{"non_field_errors":["One or more variations do not belong to this event."]}' +@pytest.mark.django_db +def test_subevent_update_keep_subeventitems(token_client, organizer, event, subevent, item, item2): + resp = token_client.patch( + '/api/v1/organizers/{}/events/{}/subevents/{}/'.format(organizer.slug, event.slug, subevent.pk), + { + "item_price_overrides": [ + { + "item": item.pk, + "price": "88.88", + "disabled": True + } + ], + }, + format='json' + ) + assert resp.status_code == 200 + with scopes_disabled(): + assert event.subevents.get(id=subevent.id).item_overrides[item.pk].disabled + + resp = token_client.patch( + '/api/v1/organizers/{}/events/{}/subevents/{}/'.format(organizer.slug, event.slug, subevent.pk), + { + "date_from": "2017-12-27T10:00:00Z", + }, + format='json' + ) + assert resp.status_code == 200 + with scopes_disabled(): + assert event.subevents.get(id=subevent.id).item_overrides[item.pk].disabled + + @pytest.mark.django_db def test_subevent_detail(token_client, organizer, event, subevent): res = dict(TEST_SUBEVENT_RES)