Explicitly store whether checkins were offline (#2617)

This commit is contained in:
Raphael Michel
2022-05-17 14:32:14 +02:00
committed by GitHub
parent 074252a9c0
commit 08590f9d98
7 changed files with 38 additions and 3 deletions

View File

@@ -157,6 +157,7 @@ class CheckinListViewSet(viewsets.ModelViewSet):
list=self.get_object(), list=self.get_object(),
successful=False, successful=False,
forced=True, forced=True,
force_sent=True,
device=self.request.auth if isinstance(self.request.auth, Device) else None, device=self.request.auth if isinstance(self.request.auth, Device) else None,
gate=self.request.auth.gate if isinstance(self.request.auth, Device) else None, gate=self.request.auth.gate if isinstance(self.request.auth, Device) else None,
**kwargs, **kwargs,

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.2.12 on 2022-04-29 13:56
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pretixbase', '0215_customer_organizer_identifier_unique'),
]
operations = [
migrations.AddField(
model_name='checkin',
name='force_sent',
field=models.BooleanField(default=False, null=True),
),
]

View File

@@ -326,7 +326,13 @@ class Checkin(models.Model):
type = models.CharField(max_length=100, choices=CHECKIN_TYPES, default=TYPE_ENTRY) type = models.CharField(max_length=100, choices=CHECKIN_TYPES, default=TYPE_ENTRY)
nonce = models.CharField(max_length=190, null=True, blank=True) nonce = models.CharField(max_length=190, null=True, blank=True)
# Whether or not the scan was made offline
force_sent = models.BooleanField(default=False, null=True, blank=True)
# Whether the scan was made offline AND would have not been possible online
forced = models.BooleanField(default=False) forced = models.BooleanField(default=False)
device = models.ForeignKey( device = models.ForeignKey(
'pretixbase.Device', related_name='checkins', on_delete=models.PROTECT, null=True, blank=True 'pretixbase.Device', related_name='checkins', on_delete=models.PROTECT, null=True, blank=True
) )

View File

@@ -796,6 +796,7 @@ def perform_checkin(op: OrderPosition, clist: CheckinList, given_answers: dict,
gate=device.gate if device else None, gate=device.gate if device else None,
nonce=nonce, nonce=nonce,
forced=force and (not entry_allowed or from_revoked_secret), forced=force and (not entry_allowed or from_revoked_secret),
force_sent=force,
raw_barcode=raw_barcode, raw_barcode=raw_barcode,
) )
op.order.log_action('pretix.event.checkin', data={ op.order.log_action('pretix.event.checkin', data={

View File

@@ -80,13 +80,17 @@
{% elif c.forced and c.successful %} {% elif c.forced and c.successful %}
<span class="fa fa-fw fa-warning" data-toggle="tooltip" <span class="fa fa-fw fa-warning" data-toggle="tooltip"
title="{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Additional entry scan: {{ date }}{% endblocktrans %}"></span> title="{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Additional entry scan: {{ date }}{% endblocktrans %}"></span>
{% elif c.forced and not c.successful %} {% elif c.force_sent %}
<br> <span class="fa fa-fw fa-cloud-upload" data-toggle="tooltip"
<small class="text-muted">{% trans "Failed in offline mode" %}</small> title="{% blocktrans trimmed with date=c.created|date:'SHORT_DATETIME_FORMAT' %}Offline scan. Upload time: {{ date }}{% endblocktrans %}"></span>
{% elif c.auto_checked_in %} {% elif c.auto_checked_in %}
<span class="fa fa-fw fa-magic" data-toggle="tooltip" <span class="fa fa-fw fa-magic" data-toggle="tooltip"
title="{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Automatically checked in: {{ date }}{% endblocktrans %}"></span> title="{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Automatically checked in: {{ date }}{% endblocktrans %}"></span>
{% endif %} {% endif %}
{% if c.forced and not c.successful %}
<br>
<small class="text-muted">{% trans "Failed in offline mode" %}</small>
{% endif %}
</td> </td>
<td> <td>
{% if c.type == "exit" %}<span class="fa fa-fw fa-sign-out"></span>{% endif %} {% if c.type == "exit" %}<span class="fa fa-fw fa-sign-out"></span>{% endif %}

View File

@@ -618,6 +618,7 @@ class CheckinLogList(ListExporter):
_('Product'), _('Product'),
_('Name'), _('Name'),
_('Device'), _('Device'),
_('Offline'),
_('Offline override'), _('Offline override'),
_('Automatically checked in'), _('Automatically checked in'),
_('Gate'), _('Gate'),
@@ -664,6 +665,7 @@ class CheckinLogList(ListExporter):
str(ci.position.item) if ci.position else (str(ci.raw_item) if ci.raw_item else ''), 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 '', (ci.position.attendee_name or ia.name) if ci.position else '',
str(ci.device) if ci.device else '', str(ci.device) if ci.device else '',
_('Yes') if ci.force_sent is True else (_('No') if ci.force_sent is False else '?'),
_('Yes') if ci.forced else _('No'), _('Yes') if ci.forced else _('No'),
_('Yes') if ci.auto_checked_in else _('No'), _('Yes') if ci.auto_checked_in else _('No'),
str(ci.gate or ''), str(ci.gate or ''),

View File

@@ -814,6 +814,7 @@ def test_forced_flag_set_if_required(token_client, organizer, clist, event, orde
), {'force': True}, format='json') ), {'force': True}, format='json')
with scopes_disabled(): with scopes_disabled():
assert not p.checkins.order_by('pk').last().forced assert not p.checkins.order_by('pk').last().forced
assert p.checkins.order_by('pk').last().force_sent
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
@@ -821,6 +822,7 @@ def test_forced_flag_set_if_required(token_client, organizer, clist, event, orde
), {'force': True}, format='json') ), {'force': True}, format='json')
with scopes_disabled(): with scopes_disabled():
assert p.checkins.order_by('pk').last().forced assert p.checkins.order_by('pk').last().forced
assert p.checkins.order_by('pk').last().force_sent
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
@@ -1184,6 +1186,7 @@ def test_redeem_unknown_revoked_force(token_client, organizer, clist, event, ord
assert resp.data["status"] == "ok" assert resp.data["status"] == "ok"
with scopes_disabled(): with scopes_disabled():
assert Checkin.objects.last().forced assert Checkin.objects.last().forced
assert Checkin.objects.last().force_sent
@pytest.mark.django_db @pytest.mark.django_db