diff --git a/src/pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html b/src/pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html new file mode 100644 index 0000000000..475fbc2201 --- /dev/null +++ b/src/pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html @@ -0,0 +1,31 @@ +{% extends "pretixcontrol/items/base.html" %} +{% load i18n %} +{% load bootstrap3 %} +{% block title %}{% trans "Delete check-ins" %}{% endblock %} +{% block inside %} +

{% trans "Delete check-ins" %}

+
+ {% csrf_token %} + {% for k, l in request.POST.lists %} + {% for v in l %} + + {% endfor %} + {% endfor %} +

+ {% blocktrans trimmed count count=cnt %} + Are you sure you want to permanently delete the check-ins of one ticket. + {% plural %} + Are you sure you want to permanently delete the check-ins of {{ count }} tickets? + {% endblocktrans %} +

+
+ + {% trans "Cancel" %} + + +
+
+{% endblock %} diff --git a/src/pretix/control/templates/pretixcontrol/checkin/index.html b/src/pretix/control/templates/pretixcontrol/checkin/index.html index 28fc1d6500..ef812a93a2 100644 --- a/src/pretix/control/templates/pretixcontrol/checkin/index.html +++ b/src/pretix/control/templates/pretixcontrol/checkin/index.html @@ -205,22 +205,27 @@ - {% if "can_change_orders" in request.eventpermset or "can_checkin_orders" in request.eventpermset %} - - - {% endif %} - {% if "can_change_orders" in request.eventpermset %} - - {% endif %} +
+ {% if "can_change_orders" in request.eventpermset or "can_checkin_orders" in request.eventpermset %} + + + {% endif %} + {% if "can_change_orders" in request.eventpermset %} + + {% endif %} +
{% include "pretixcontrol/pagination.html" %} {% endif %} diff --git a/src/pretix/control/urls.py b/src/pretix/control/urls.py index b0dbfc9137..bef3a19c7e 100644 --- a/src/pretix/control/urls.py +++ b/src/pretix/control/urls.py @@ -438,6 +438,7 @@ urlpatterns = [ re_path(r'^checkinlists/select2$', typeahead.checkinlist_select2, name='event.orders.checkinlists.select2'), re_path(r'^checkinlists/(?P\d+)/$', checkin.CheckInListShow.as_view(), name='event.orders.checkinlists.show'), re_path(r'^checkinlists/(?P\d+)/simulator$', checkin.CheckInListSimulator.as_view(), name='event.orders.checkinlists.simulator'), + re_path(r'^checkinlists/(?P\d+)/bulk_revert$', checkin.CheckInListBulkRevertConfirmView.as_view(), name='event.orders.checkinlists.bulk_revert'), re_path(r'^checkinlists/(?P\d+)/bulk_action$', checkin.CheckInListBulkActionView.as_view(), name='event.orders.checkinlists.bulk_action'), re_path(r'^checkinlists/(?P\d+)/change$', checkin.CheckinListUpdate.as_view(), name='event.orders.checkinlists.edit'), diff --git a/src/pretix/control/views/checkin.py b/src/pretix/control/views/checkin.py index 22b30512b5..b2dd89e6cf 100644 --- a/src/pretix/control/views/checkin.py +++ b/src/pretix/control/views/checkin.py @@ -45,7 +45,7 @@ from django.urls import reverse from django.utils.functional import cached_property from django.utils.timezone import is_aware, make_aware, now from django.utils.translation import gettext_lazy as _ -from django.views.generic import FormView, ListView +from django.views.generic import FormView, ListView, TemplateView from i18nfield.strings import LazyI18nString from pretix.api.views.checkin import _redeem_process @@ -191,9 +191,23 @@ class CheckInListShow(EventPermissionRequiredMixin, PaginationMixin, CheckInList return ctx +class CheckInListBulkRevertConfirmView(CheckInListQueryMixin, EventPermissionRequiredMixin, TemplateView): + template_name = "pretixcontrol/checkin/bulk_revert_confirm.html" + + def post(self, request, *args, **kwargs): + self.list = get_object_or_404(self.request.event.checkin_lists.all(), pk=kwargs.get("list")) + return super().get(request, *args, **kwargs) + + def get_context_data(self, **kwargs): + return super().get_context_data( + **kwargs, + cnt=self.get_queryset().count(), + checkinlist=self.list, + ) + + class CheckInListBulkActionView(CheckInListQueryMixin, EventPermissionRequiredMixin, AsyncPostView): permission = ('can_change_orders', 'can_checkin_orders') - context_object_name = 'device' def dispatch(self, request, *args, **kwargs): self.list = get_object_or_404(self.request.event.checkin_lists.all(), pk=kwargs.get("list")) @@ -216,14 +230,15 @@ class CheckInListBulkActionView(CheckInListQueryMixin, EventPermissionRequiredMi if op.order.status == Order.STATUS_PAID or ( (self.list.include_pending or op.order.valid_if_pending) and op.order.status == Order.STATUS_PENDING ): - Checkin.objects.filter(position=op, list=self.list).delete() - op.order.log_action('pretix.event.checkin.reverted', data={ - 'position': op.id, - 'positionid': op.positionid, - 'list': self.list.pk, - 'web': True - }, user=request.user) - op.order.touch() + _, deleted = Checkin.objects.filter(position=op, list=self.list).delete() + if deleted: + op.order.log_action('pretix.event.checkin.reverted', data={ + 'position': op.id, + 'positionid': op.positionid, + 'list': self.list.pk, + 'web': True + }, user=request.user) + op.order.touch() return 'reverted', request.POST.get('returnquery') else: