diff --git a/src/pretix/base/services/seating.py b/src/pretix/base/services/seating.py index 4453e7da42..7e3aaee432 100644 --- a/src/pretix/base/services/seating.py +++ b/src/pretix/base/services/seating.py @@ -41,7 +41,7 @@ class SeatProtected(LazyLocaleException): def validate_plan_change(event, subevent, plan): current_taken_seats = set( event.seats.select_related('product').annotate( - has_op=Exists(OrderPosition.objects.filter( + has_op=Exists(OrderPosition.all.filter( seat=OuterRef('pk'), canceled=False, ).exclude( @@ -65,7 +65,7 @@ def validate_plan_change(event, subevent, plan): def generate_seats(event, subevent, plan, mapping, blocked_guids=None): current_seats = {} for s in event.seats.select_related('product').annotate( - has_op=Exists(OrderPosition.objects.filter( + has_op=Exists(OrderPosition.all.filter( seat=OuterRef('pk'), canceled=False, ).exclude( @@ -133,7 +133,7 @@ def generate_seats(event, subevent, plan, mapping, blocked_guids=None): Seat.objects.bulk_create(create_seats) CartPosition.objects.filter(seat__in=[s.pk for s in current_seats.values()]).delete() - OrderPosition.objects.filter( + OrderPosition.all.filter( Q(canceled=True) | Q(order__status=Order.STATUS_CANCELED), seat__in=[s.pk for s in current_seats.values()], ).update(seat=None) diff --git a/src/tests/api/test_events.py b/src/tests/api/test_events.py index f9bca368c4..9fd9c20951 100644 --- a/src/tests/api/test_events.py +++ b/src/tests/api/test_events.py @@ -1063,6 +1063,41 @@ def test_remove_seating_forbidden(token_client, organizer, event, item, seatingp 'present in the new plan and is already sold."]}' +@pytest.mark.django_db +def test_remove_seating_canceled_seat(token_client, organizer, event, item, seatingplan, order_position): + resp = token_client.patch( + '/api/v1/organizers/{}/events/{}/'.format(organizer.slug, event.slug), + { + "seating_plan": seatingplan.pk, + "seat_category_mapping": { + "Stalls": item.pk + } + }, + format='json' + ) + assert resp.status_code == 200 + event.refresh_from_db() + assert event.seating_plan == seatingplan + with scopes_disabled(): + assert event.seats.count() == 3 + assert event.seat_category_mappings.count() == 1 + + order_position.seat = event.seats.first() + order_position.canceled = True + order_position.save() + + resp = token_client.patch( + '/api/v1/organizers/{}/events/{}/'.format(organizer.slug, event.slug), + { + "seating_plan": None + }, + format='json' + ) + assert resp.status_code == 200 + order_position.refresh_from_db() + assert order_position.seat is None + + @pytest.mark.django_db def test_no_seating_for_series(token_client, organizer, event, item, seatingplan, order_position): event.has_subevents = True