Web-based check-in interface (#1985)

This commit is contained in:
Raphael Michel
2021-03-30 09:34:11 +02:00
committed by GitHub
parent b06cded172
commit 92a50cb2d1
56 changed files with 3578 additions and 58 deletions

View File

@@ -1,4 +1,5 @@
from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import models
from django.db.models import Exists, F, Max, OuterRef, Q, Subquery
from django.utils.timezone import now
@@ -142,6 +143,54 @@ class CheckinList(LoggedModel):
def __str__(self):
return self.name
@classmethod
def validate_rules(cls, rules, seen_nonbool=False, depth=0):
# While we implement a full jsonlogic machine on Python-level, we also use the logic rules to generate
# SQL queries, which is not a full implementation of JSON logic right now, but makes some assumptions,
# e.g. it does not support something like (a AND b) == (c OR D)
# Every change to our supported JSON logic must be done
# * in pretix.base.services.checkin
# * in pretix.base.models.checkin
# * in checkinrules.js
# * in libpretixsync
top_level_operators = {
'<', '<=', '>', '>=', '==', '!=', 'inList', 'isBefore', 'isAfter', 'or', 'and'
}
allowed_operators = top_level_operators | {
'buildTime', 'objectList', 'lookup', 'var',
}
allowed_vars = {
'product', 'variation', 'now', 'entries_number', 'entries_today', 'entries_days'
}
if not rules or not isinstance(rules, dict):
return
if len(rules) > 1:
raise ValidationError(f'Rules should not include dictionaries with more than one key, found: "{rules}".')
operator = list(rules.keys())[0]
if operator not in allowed_operators:
raise ValidationError(f'Logic operator "{operator}" is currently not allowed.')
if depth == 0 and operator not in top_level_operators:
raise ValidationError(f'Logic operator "{operator}" is currently not allowed on the first level.')
values = rules[operator]
if not isinstance(values, list) and not isinstance(values, tuple):
values = [values]
if operator == 'var':
if values[0] not in allowed_vars:
raise ValidationError(f'Logic variable "{values[0]}" is currently not allowed.')
return
if operator in ('or', 'and') and seen_nonbool:
raise ValidationError(f'You cannot use OR/AND logic on a level below a comparison operator.')
for v in values:
cls.validate_rules(v, seen_nonbool=seen_nonbool or operator not in ('or', 'and'), depth=depth + 1)
class Checkin(models.Model):
"""

View File

@@ -1088,17 +1088,23 @@ class Question(LoggedModel):
)
dependency_values = MultiStringField(default=[])
valid_number_min = models.DecimalField(decimal_places=6, max_digits=16, null=True, blank=True,
verbose_name=_('Minimum value'), help_text=_('Currently not supported in our apps'))
verbose_name=_('Minimum value'),
help_text=_('Currently not supported in our apps and during check-in'))
valid_number_max = models.DecimalField(decimal_places=6, max_digits=16, null=True, blank=True,
verbose_name=_('Maximum value'), help_text=_('Currently not supported in our apps'))
verbose_name=_('Maximum value'),
help_text=_('Currently not supported in our apps and during check-in'))
valid_date_min = models.DateField(null=True, blank=True,
verbose_name=_('Minimum value'), help_text=_('Currently not supported in our apps'))
verbose_name=_('Minimum value'),
help_text=_('Currently not supported in our apps and during check-in'))
valid_date_max = models.DateField(null=True, blank=True,
verbose_name=_('Maximum value'), help_text=_('Currently not supported in our apps'))
verbose_name=_('Maximum value'),
help_text=_('Currently not supported in our apps and during check-in'))
valid_datetime_min = models.DateTimeField(null=True, blank=True,
verbose_name=_('Minimum value'), help_text=_('Currently not supported in our apps'))
verbose_name=_('Minimum value'),
help_text=_('Currently not supported in our apps and during check-in'))
valid_datetime_max = models.DateTimeField(null=True, blank=True,
verbose_name=_('Maximum value'), help_text=_('Currently not supported in our apps'))
verbose_name=_('Maximum value'),
help_text=_('Currently not supported in our apps and during check-in'))
objects = ScopedManager(organizer='event__organizer')

View File

@@ -174,6 +174,8 @@ class Team(LoggedModel):
:type can_view_orders: bool
:param can_change_orders: If ``True``, the members can change details of orders of the associated events.
:type can_change_orders: bool
:param can_checkin_orders: If ``True``, the members can perform check-in related actions.
:type can_checkin_orders: bool
:param can_view_vouchers: If ``True``, the members can inspect details of all vouchers of the associated events.
:type can_view_vouchers: bool
:param can_change_vouchers: If ``True``, the members can change and create vouchers for the associated events.
@@ -220,6 +222,12 @@ class Team(LoggedModel):
default=False,
verbose_name=_("Can change orders")
)
can_checkin_orders = models.BooleanField(
default=False,
verbose_name=_("Can perform check-ins"),
help_text=_('This includes searching for attendees, which can be used to obtain personal information about '
'attendees. Users with "can change orders" can also perform check-ins.')
)
can_view_vouchers = models.BooleanField(
default=False,
verbose_name=_("Can view vouchers")