forked from CGM_Public/pretix_original
Check-in: New flags for check-in lists (#3577)
This commit is contained in:
@@ -38,7 +38,7 @@ class CheckinListSerializer(I18nAwareModelSerializer):
|
||||
model = CheckinList
|
||||
fields = ('id', 'name', 'all_products', 'limit_products', 'subevent', 'checkin_count', 'position_count',
|
||||
'include_pending', 'auto_checkin_sales_channels', 'allow_multiple_entries', 'allow_entry_after_exit',
|
||||
'rules', 'exit_all_at', 'addon_match')
|
||||
'rules', 'exit_all_at', 'addon_match', 'ignore_in_statistics', 'consider_tickets_used')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
22
src/pretix/base/migrations/0247_checkinlist.py
Normal file
22
src/pretix/base/migrations/0247_checkinlist.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# Generated by Django 4.2.4 on 2023-09-06 11:58
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("pretixbase", "0246_bigint"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="checkinlist",
|
||||
name="consider_tickets_used",
|
||||
field=models.BooleanField(default=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="checkinlist",
|
||||
name="ignore_in_statistics",
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
||||
@@ -62,6 +62,16 @@ class CheckinList(LoggedModel):
|
||||
'and valid for check-in regardless of which date they are purchased for. '
|
||||
'You can limit their validity through the advanced check-in rules, '
|
||||
'though.'))
|
||||
ignore_in_statistics = models.BooleanField(
|
||||
verbose_name=pgettext_lazy('checkin', 'Ignore check-ins on this list in statistics'),
|
||||
default=False
|
||||
)
|
||||
consider_tickets_used = models.BooleanField(
|
||||
verbose_name=pgettext_lazy('checkin', 'Tickets with a check-in on this list should be considered "used"'),
|
||||
help_text=_('This is relevant in various situations, e.g. for deciding if a ticket can still be canceled by '
|
||||
'the customer.'),
|
||||
default=True
|
||||
)
|
||||
include_pending = models.BooleanField(verbose_name=pgettext_lazy('checkin', 'Include pending orders'),
|
||||
default=False,
|
||||
help_text=_('With this option, people will be able to check in even if the '
|
||||
|
||||
@@ -633,7 +633,7 @@ class Order(LockModel, LoggedModel):
|
||||
positions = list(
|
||||
self.positions.all().annotate(
|
||||
has_variations=Exists(ItemVariation.objects.filter(item_id=OuterRef('item_id'))),
|
||||
has_checkin=Exists(Checkin.objects.filter(position_id=OuterRef('pk')))
|
||||
has_checkin=Exists(Checkin.objects.filter(position_id=OuterRef('pk'), list__consider_tickets_used=True))
|
||||
).select_related('item').prefetch_related('issued_gift_cards')
|
||||
)
|
||||
if self.event.settings.change_allow_user_if_checked_in:
|
||||
@@ -665,7 +665,7 @@ class Order(LockModel, LoggedModel):
|
||||
return False
|
||||
positions = list(
|
||||
self.positions.all().annotate(
|
||||
has_checkin=Exists(Checkin.objects.filter(position_id=OuterRef('pk')))
|
||||
has_checkin=Exists(Checkin.objects.filter(position_id=OuterRef('pk'), list__consider_tickets_used=True))
|
||||
).select_related('item').prefetch_related('issued_gift_cards')
|
||||
)
|
||||
cancelable = all([op.item.allow_cancel and not op.has_checkin and not op.blocked for op in positions])
|
||||
@@ -820,7 +820,7 @@ class Order(LockModel, LoggedModel):
|
||||
|
||||
positions = list(
|
||||
self.positions.all().annotate(
|
||||
has_checkin=Exists(Checkin.objects.filter(position_id=OuterRef('pk')))
|
||||
has_checkin=Exists(Checkin.objects.filter(position_id=OuterRef('pk'), list__consider_tickets_used=True))
|
||||
).select_related('item').prefetch_related('item__questions')
|
||||
)
|
||||
if not self.event.settings.allow_modifications_after_checkin:
|
||||
|
||||
@@ -1996,7 +1996,7 @@ class OrderChangeManager:
|
||||
for a in current_addons[cp][k][:current_num - input_num]:
|
||||
if a.canceled:
|
||||
continue
|
||||
if a.checkins.exists():
|
||||
if a.checkins.filter(list__consider_tickets_used=True).exists():
|
||||
raise OrderError(
|
||||
error_messages['addon_already_checked_in'] % {
|
||||
'addon': str(a.item.name),
|
||||
|
||||
@@ -2072,7 +2072,8 @@ class VoucherFilterForm(FilterForm):
|
||||
qs = qs.filter(Q(valid_until__isnull=False) & Q(valid_until__lt=now())).filter(redeemed=0)
|
||||
elif s == 'c':
|
||||
checkins = Checkin.objects.filter(
|
||||
position__voucher=OuterRef('pk')
|
||||
position__voucher=OuterRef('pk'),
|
||||
list__consider_tickets_used=True,
|
||||
)
|
||||
qs = qs.annotate(has_checkin=Exists(checkins)).filter(
|
||||
redeemed__gt=0, has_checkin=True
|
||||
|
||||
@@ -390,7 +390,7 @@
|
||||
{% elif c.auto_checked_in %}
|
||||
<span class="fa fa-fw fa-magic text-success" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Automatically checked in: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
|
||||
{% else %}
|
||||
<span class="fa fa-fw fa-check text-success" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Entry scan: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
|
||||
<span class="fa fa-fw fa-check {% if c.list.consider_tickets_used %}text-success{% else %}text-muted{% endif %}" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Entry scan: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
@@ -133,10 +133,10 @@ class ScheduledMail(models.Model):
|
||||
|
||||
if self.rule.checked_in_status == "no_checkin":
|
||||
filter_orders_by_op = True
|
||||
op_qs = op_qs.filter(~Exists(Checkin.objects.filter(position_id=OuterRef('pk'))))
|
||||
op_qs = op_qs.filter(~Exists(Checkin.objects.filter(position_id=OuterRef('pk'), list__consider_tickets_used=True)))
|
||||
elif self.rule.checked_in_status == "checked_in":
|
||||
filter_orders_by_op = True
|
||||
op_qs = op_qs.filter(Exists(Checkin.objects.filter(position_id=OuterRef('pk'))))
|
||||
op_qs = op_qs.filter(Exists(Checkin.objects.filter(position_id=OuterRef('pk'), list__consider_tickets_used=True)))
|
||||
|
||||
status_q = Q(status__in=self.rule.restrict_to_status)
|
||||
if 'n__pending_approval' in self.rule.restrict_to_status:
|
||||
|
||||
@@ -67,6 +67,7 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict,
|
||||
any_checkins=Exists(
|
||||
Checkin.objects.filter(
|
||||
Q(position_id=OuterRef('pk')) | Q(position__addon_to_id=OuterRef('pk')),
|
||||
list__consider_tickets_used=True,
|
||||
)
|
||||
),
|
||||
matching_checkins=Exists(
|
||||
|
||||
@@ -373,7 +373,8 @@ class OrderSendView(BaseSenderView):
|
||||
any_checkins=Exists(
|
||||
Checkin.all.filter(
|
||||
Q(position_id=OuterRef('pk')) | Q(position__addon_to_id=OuterRef('pk')),
|
||||
successful=True
|
||||
successful=True,
|
||||
list__consider_tickets_used=True,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -246,7 +246,10 @@ class OrderDetails(EventViewMixin, OrderDetailMixin, CartMixin, TicketPageMixin,
|
||||
qs = qs.annotate(
|
||||
checkin_count=Subquery(
|
||||
Checkin.objects.filter(
|
||||
successful=True, type=Checkin.TYPE_ENTRY, position_id=OuterRef('pk')
|
||||
successful=True,
|
||||
type=Checkin.TYPE_ENTRY,
|
||||
position_id=OuterRef('pk'),
|
||||
list__consider_tickets_used=True,
|
||||
).order_by().values('position').annotate(c=Count('*')).values('c')
|
||||
)
|
||||
)
|
||||
@@ -358,7 +361,10 @@ class OrderPositionDetails(EventViewMixin, OrderPositionDetailMixin, CartMixin,
|
||||
qs = qs.annotate(
|
||||
checkin_count=Subquery(
|
||||
Checkin.objects.filter(
|
||||
successful=True, type=Checkin.TYPE_ENTRY, position_id=OuterRef('pk')
|
||||
successful=True,
|
||||
type=Checkin.TYPE_ENTRY,
|
||||
position_id=OuterRef('pk'),
|
||||
list__consider_tickets_used=True,
|
||||
).order_by().values('position').annotate(c=Count('*')).values('c')
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user