forked from CGM_Public/pretix_original
Explicitly store whether checkins were offline (#2617)
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
18
src/pretix/base/migrations/0216_checkin_forced_sent.py
Normal file
18
src/pretix/base/migrations/0216_checkin_forced_sent.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -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
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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={
|
||||||
|
|||||||
@@ -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 %}
|
||||||
|
|||||||
@@ -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 ''),
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user