diff --git a/src/pretix/control/logdisplay.py b/src/pretix/control/logdisplay.py index 66818f54e5..3d87cd7bac 100644 --- a/src/pretix/control/logdisplay.py +++ b/src/pretix/control/logdisplay.py @@ -1,8 +1,11 @@ import json from decimal import Decimal +import dateutil.parser +import pytz from django.dispatch import receiver from django.utils import formats +from django.utils.formats import date_format from django.utils.translation import pgettext_lazy, ugettext_lazy as _ from i18nfield.strings import LazyI18nString @@ -200,6 +203,21 @@ def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs): if logentry.action_type.startswith('pretix.event.tickets.provider.'): return _('The settings of a ticket output provider have been changed.') + if logentry.action_type == 'pretix.control.views.checkin': + dt = dateutil.parser.parse(data.get('datetime')) + tz = pytz.timezone(sender.settings.timezone) + dt_formatted = date_format(dt.astimezone(tz), "SHORT_DATETIME_FORMAT") + + if data.get('first'): + return _('Position #{posid} has been checked in manually at {datetime}.').format( + posid=data.get('positionid'), + datetime=dt_formatted + ) + return _('Position #{posid} has been checked in again at {datetime}.').format( + posid=data.get('positionid'), + datetime=dt_formatted + ) + if logentry.action_type == 'pretix.team.member.added': return _('{user} has been added to the team.').format(user=data.get('email')) diff --git a/src/pretix/control/templates/pretixcontrol/checkin/index.html b/src/pretix/control/templates/pretixcontrol/checkin/index.html index 087420bf17..b8f07ca2cd 100644 --- a/src/pretix/control/templates/pretixcontrol/checkin/index.html +++ b/src/pretix/control/templates/pretixcontrol/checkin/index.html @@ -52,6 +52,7 @@ + + @@ -107,6 +113,10 @@
{% trans "Order code" %} {% trans "Item" %} @@ -74,6 +75,11 @@ {% for e in entries %} {% with e.checkins.first as checkin %}
+ + {{ e.order.code }}
+ + {% include "pretixcontrol/pagination.html" %} {% endif %} {% endblock %} diff --git a/src/pretix/control/views/checkin.py b/src/pretix/control/views/checkin.py index 64dfda5701..60fd65befa 100644 --- a/src/pretix/control/views/checkin.py +++ b/src/pretix/control/views/checkin.py @@ -1,8 +1,13 @@ +from django.contrib import messages +from django.core.urlresolvers import reverse from django.db.models import F, Prefetch, Q from django.db.models.functions import Coalesce +from django.shortcuts import redirect +from django.utils.timezone import now +from django.utils.translation import ugettext_lazy as _ from django.views.generic import ListView -from pretix.base.models import Checkin, Item, OrderPosition +from pretix.base.models import Checkin, Item, Order, OrderPosition from pretix.control.permissions import EventPermissionRequiredMixin @@ -69,6 +74,31 @@ class CheckInView(EventPermissionRequiredMixin, ListView): or "subevent" in self.request.GET) return ctx + def post(self, request, *args, **kwargs): + positions = OrderPosition.objects.select_related('item', 'variation', 'order', 'addon_to').filter( + order__event=self.request.event, + pk__in=request.POST.getlist('checkin') + ) + + for op in positions: + created = False + if op.order.status == Order.STATUS_PAID: + ci, created = Checkin.objects.get_or_create(position=op, defaults={ + 'datetime': now(), + }) + op.order.log_action('pretix.control.views.checkin', data={ + 'position': op.id, + 'positionid': op.positionid, + 'first': created, + 'datetime': now() + }, user=request.user) + + messages.success(request, _('The selected tickets have been marked as checked in.')) + return redirect(reverse('control:event.orders.checkins', kwargs={ + 'event': self.request.event.slug, + 'organizer': self.request.event.organizer.slug + }) + '?' + request.GET.urlencode()) + @staticmethod def get_ordering_keys_mappings(): return { diff --git a/src/tests/control/test_checkins.py b/src/tests/control/test_checkins.py index 76119e2fc4..d693ccc34c 100644 --- a/src/tests/control/test_checkins.py +++ b/src/tests/control/test_checkins.py @@ -5,8 +5,8 @@ import pytest from django.utils.timezone import now from pretix.base.models import ( - Checkin, Event, Item, ItemAddOn, ItemCategory, Order, OrderPosition, - Organizer, Team, User, + Checkin, Event, Item, ItemAddOn, ItemCategory, LogEntry, Order, + OrderPosition, Organizer, Team, User, ) from pretix.control.views.dashboards import checkin_widget @@ -269,6 +269,19 @@ def test_checkins_list_mixed(client, checkin_list_env, query, expected): assert item_keys == expected +@pytest.mark.django_db +def test_manual_checkins(client, checkin_list_env): + client.login(email='dummy@dummy.dummy', password='dummy') + assert not checkin_list_env[5][3].checkins.exists() + client.post('/control/event/dummy/dummy/checkins/', { + 'checkin': [checkin_list_env[5][3].pk] + }) + assert checkin_list_env[5][3].checkins.exists() + assert LogEntry.objects.filter( + action_type='pretix.control.views.checkin', object_id=checkin_list_env[5][3].order.pk + ).exists() + + @pytest.fixture def checkin_list_with_addon_env(): # permission