Store all check-in attempts, not only successful ones (#2074)

This commit is contained in:
Raphael Michel
2021-06-05 13:00:58 +02:00
committed by GitHub
parent 9c3fc69176
commit c7ef79be90
29 changed files with 849 additions and 66 deletions

View File

@@ -596,7 +596,7 @@ class CSVCheckinList(CheckInListMixin, ListExporter):
class CheckinLogList(ListExporter):
name = "checkinlog"
identifier = 'checkinlog'
verbose_name = gettext_lazy('Check-in log (all successful scans)')
verbose_name = gettext_lazy('Check-in log (all scans)')
@property
def additional_form_fields(self):
@@ -616,42 +616,53 @@ class CheckinLogList(ListExporter):
_('Device'),
_('Offline override'),
_('Automatically checked in'),
_('Gate'),
_('Result'),
_('Error message'),
]
qs = Checkin.objects.filter(
position__order__event=self.event,
qs = Checkin.all.filter(
list__event=self.event,
)
if form_data.get('list'):
qs = qs.filter(list_id=form_data.get('list'))
if form_data.get('items'):
qs = qs.filter(position__item_id__in=form_data['items'])
if len(form_data['items']) != self.event.items.count():
qs = qs.filter(Q(position__item_id__in=form_data['items']) | Q(raw_item_id__in=form_data['items']))
if form_data.get('successful_only'):
qs = qs.filter(successful=True)
yield self.ProgressSetTotal(total=qs.count())
qs = qs.select_related(
'position__item', 'position__order', 'position__order__invoice_address', 'position', 'list', 'device'
'position__item', 'position__order', 'position__order__invoice_address', 'position', 'list', 'device',
'raw_item'
).order_by(
'datetime'
)
for ci in qs.iterator():
try:
ia = ci.position.order.invoice_address
except InvoiceAddress.DoesNotExist:
ia = InvoiceAddress()
if ci.position:
try:
ia = ci.position.order.invoice_address
except InvoiceAddress.DoesNotExist:
ia = InvoiceAddress()
yield [
date_format(ci.datetime.astimezone(self.timezone), 'SHORT_DATE_FORMAT'),
date_format(ci.datetime.astimezone(self.timezone), 'TIME_FORMAT'),
str(ci.list),
ci.get_type_display(),
ci.position.order.code,
ci.position.positionid,
ci.position.secret,
str(ci.position.item),
ci.position.attendee_name or ia.name,
str(ci.device),
ci.position.order.code if ci.position else '',
ci.position.positionid if ci.position else '',
ci.raw_barcode or ci.position.secret,
str(ci.position.item) if ci.position else (str(ci.raw_item) if ci.raw_item else ''),
(ci.position.attendee_name or ia.name) if ci.position else '',
str(ci.device) if ci.device else '',
_('Yes') if ci.forced else _('No'),
_('Yes') if ci.auto_checked_in else _('No'),
str(ci.gate or ''),
_('OK') if ci.successful else ci.get_error_reason_display(),
ci.error_explanation or ''
]
def get_filename(self):
@@ -678,6 +689,12 @@ class CheckinLogList(ListExporter):
),
initial=self.event.items.all()
)),
('successful_only',
forms.BooleanField(
label=_('Successful scans only'),
initial=True,
required=False,
)),
]
)

View File

@@ -49,7 +49,7 @@ from django.views.generic import DeleteView, FormView, ListView
from pretix.base.email import get_available_placeholders
from pretix.base.i18n import LazyI18nString, language
from pretix.base.models import LogEntry, Order, OrderPosition
from pretix.base.models import Checkin, LogEntry, Order, OrderPosition
from pretix.base.models.event import SubEvent
from pretix.base.services.mail import TolerantDict
from pretix.base.templatetags.rich_text import markdown_compile_email
@@ -141,12 +141,28 @@ class SenderView(EventPermissionRequiredMixin, FormView):
if form.cleaned_data.get('filter_checkins'):
ql = []
if form.cleaned_data.get('not_checked_in'):
ql.append(Q(checkins__list_id=None))
opq = opq.alias(
any_checkins=Exists(
Checkin.all.filter(
position_id=OuterRef('pk'),
successful=True
)
)
)
ql.append(Q(any_checkins=False))
if form.cleaned_data.get('checkin_lists'):
ql.append(Q(
checkins__list_id__in=[i.pk for i in form.cleaned_data.get('checkin_lists', [])],
))
opq = opq.alias(
matching_checkins=Exists(
Checkin.all.filter(
position_id=OuterRef('pk'),
list_id__in=[i.pk for i in form.cleaned_data.get('checkin_lists', [])],
successful=True
)
)
)
ql.append(Q(matching_checkins=True))
if len(ql) == 2:
opq = opq.filter(ql[0] | ql[1])
elif ql:

View File

@@ -53,7 +53,7 @@ window.vapp = new Vue({
'result.exit': gettext('Exit recorded'),
'result.already_redeemed': gettext('Ticket already used'),
'result.questions': gettext('Information required'),
'result.invalid': gettext('Invalid ticket'),
'result.invalid': gettext('Unknown ticket'),
'result.product': gettext('Invalid product'),
'result.unpaid': gettext('Ticket not paid'),
'result.rules': gettext('Entry not allowed'),