diff --git a/src/pretix/api/views/checkin.py b/src/pretix/api/views/checkin.py index e26297e3c5..60eb79ee0c 100644 --- a/src/pretix/api/views/checkin.py +++ b/src/pretix/api/views/checkin.py @@ -163,13 +163,29 @@ class CheckinListViewSet(viewsets.ModelViewSet): serializer.is_valid(raise_exception=True) kwargs = {} - if not serializer.validated_data.get('position'): - kwargs['position'] = OrderPosition.all.filter( + clist = self.get_object() + + if not serializer.validated_data.get('position') and 'events_and_checkin_lists' in self.request.data: + # an offline checkin failed, let's see whether a ticket with the given secret actually exists and just + # was not synced in time, so we can enrich the log message + candidate_position = OrderPosition.all.filter( organizer=self.request.organizer, secret=serializer.validated_data['raw_barcode'] ).first() + if candidate_position.event.pk != clist.event.pk: + try: + list_id = next(list_id for event_slug, list_id in self.request.data['events_and_checkin_lists'] + if event_slug == candidate_position.event.slug) + except StopIteration: # ignore if candidate position's event was not active on device + pass + else: + try: + clist = candidate_position.event.checkin_lists.get(pk=list_id) + except CheckinList.DoesNotExist: # ignore if list deleted in between + pass + if candidate_position.event.pk == clist.event.pk: + kwargs['position'] = candidate_position - clist = self.get_object() if serializer.validated_data.get('nonce'): if kwargs.get('position'): prev = kwargs['position'].all_checkins.filter(nonce=serializer.validated_data['nonce']).first()