mirror of
https://github.com/pretix/pretix.git
synced 2026-05-08 15:44:02 +00:00
Allow users to see the number of checkins (#2561)
Co-authored-by: Richard Schreiber <schreiber@rami.io>
This commit is contained in:
@@ -1195,7 +1195,20 @@ DEFAULTS = {
|
||||
help_text=_("If you ask for a phone number, explain why you do so and what you will use the phone number for.")
|
||||
)
|
||||
},
|
||||
|
||||
'show_checkin_number_user': {
|
||||
'default': 'False',
|
||||
'type': bool,
|
||||
'serializer_class': serializers.BooleanField,
|
||||
'form_class': forms.BooleanField,
|
||||
'form_kwargs': dict(
|
||||
label=_("Show number of check-ins to customer"),
|
||||
help_text=_('With this option enabled, your customers will be able how many times they entered '
|
||||
'the event. This is usually not necessary, but might be useful in combination with tickets '
|
||||
'that are usable a specific number of times, so customers can see how many times they have '
|
||||
'already been used. Exits or failed scans will not be counted, and the user will not see '
|
||||
'the different check-in lists.'),
|
||||
)
|
||||
},
|
||||
'ticket_download': {
|
||||
'default': 'False',
|
||||
'type': bool,
|
||||
|
||||
@@ -523,6 +523,7 @@ class EventSettingsForm(SettingsForm):
|
||||
'last_order_modification_date',
|
||||
'allow_modifications_after_checkin',
|
||||
'checkout_show_copy_answers_button',
|
||||
'show_checkin_number_user',
|
||||
'primary_color',
|
||||
'theme_color_success',
|
||||
'theme_color_danger',
|
||||
|
||||
@@ -221,6 +221,7 @@
|
||||
{% bootstrap_field sform.show_items_outside_presale_period layout="control" %}
|
||||
{% bootstrap_field sform.last_order_modification_date layout="control" %}
|
||||
{% bootstrap_field sform.allow_modifications_after_checkin layout="control" %}
|
||||
{% bootstrap_field sform.show_checkin_number_user layout="control" %}
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{% trans "Display" %}</legend>
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
</p>
|
||||
{% if line.seat or line.voucher or line.subevent or line.used_membership%}
|
||||
<dl class="dl-inline">
|
||||
{% elif event.settings.show_checkin_number_user and line.checkin_count %}
|
||||
<dl class="dl-inline">
|
||||
{% endif %}
|
||||
{% if line.seat %}
|
||||
<div class="cart-icon-details">
|
||||
@@ -94,8 +96,25 @@
|
||||
</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if event.settings.show_checkin_number_user and line.checkin_count %}
|
||||
<div class="cart-icon-details">
|
||||
<dt class="sr-only">{% trans "Usage:" context "ticket_checkins" %}</dt>
|
||||
<dd class="text-success">
|
||||
<span class="fa fa-check-circle fa-fw text-success" aria-hidden="true"></span>
|
||||
<strong>
|
||||
{% blocktrans trimmed count count=line.checkin_count %}
|
||||
This ticket has been used once.
|
||||
{% plural %}
|
||||
This ticket has been used {{ count }} times.
|
||||
{% endblocktrans %}
|
||||
</strong>
|
||||
</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if line.seat or line.voucher or line.subevent or line.used_membership%}
|
||||
</dl>
|
||||
{% elif event.settings.show_checkin_number_user and line.checkin_count %}
|
||||
</dl>
|
||||
{% endif %}
|
||||
|
||||
{% if line.issued_gift_cards.exists %}
|
||||
|
||||
@@ -47,7 +47,7 @@ from django.contrib import messages
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.files import File
|
||||
from django.db import transaction
|
||||
from django.db.models import Exists, OuterRef, Q, Sum
|
||||
from django.db.models import Count, Exists, OuterRef, Q, Subquery, Sum
|
||||
from django.http import (
|
||||
FileResponse, Http404, HttpResponseRedirect, JsonResponse,
|
||||
)
|
||||
@@ -60,7 +60,8 @@ from django.views.decorators.clickjacking import xframe_options_exempt
|
||||
from django.views.generic import TemplateView, View
|
||||
|
||||
from pretix.base.models import (
|
||||
CachedTicket, GiftCard, Invoice, Order, OrderPosition, Quota, TaxRule,
|
||||
CachedTicket, Checkin, GiftCard, Invoice, Order, OrderPosition, Quota,
|
||||
TaxRule,
|
||||
)
|
||||
from pretix.base.models.orders import (
|
||||
CachedCombinedTicket, InvoiceAddress, OrderFee, OrderPayment, OrderRefund,
|
||||
@@ -124,12 +125,13 @@ class OrderDetailMixin(NoSearchIndexViewMixin):
|
||||
class OrderPositionDetailMixin(NoSearchIndexViewMixin):
|
||||
@cached_property
|
||||
def position(self):
|
||||
p = OrderPosition.objects.filter(
|
||||
qs = OrderPosition.objects.filter(
|
||||
order__event=self.request.event,
|
||||
addon_to__isnull=True,
|
||||
order__code=self.kwargs['order'],
|
||||
positionid=self.kwargs['position']
|
||||
).select_related('order', 'order__event').first()
|
||||
).select_related('order', 'order__event')
|
||||
p = qs.first()
|
||||
if p:
|
||||
if p.web_secret.lower() == self.kwargs['secret'].lower():
|
||||
return p
|
||||
@@ -229,9 +231,21 @@ class OrderDetails(EventViewMixin, OrderDetailMixin, CartMixin, TicketPageMixin,
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
|
||||
qs = self.order.positions.prefetch_related('issued_gift_cards').select_related('tax_rule')
|
||||
if self.request.event.settings.show_checkin_number_user:
|
||||
qs = qs.annotate(
|
||||
checkin_count=Subquery(
|
||||
Checkin.objects.filter(
|
||||
successful=True, type=Checkin.TYPE_ENTRY, position_id=OuterRef('pk')
|
||||
).order_by().values('position').annotate(c=Count('*')).values('c')
|
||||
)
|
||||
)
|
||||
|
||||
ctx['cart'] = self.get_cart(
|
||||
answers=True, downloads=ctx['can_download'],
|
||||
queryset=self.order.positions.prefetch_related('issued_gift_cards').select_related('tax_rule'),
|
||||
answers=True,
|
||||
downloads=ctx['can_download'],
|
||||
queryset=qs,
|
||||
order=self.order
|
||||
)
|
||||
ctx['tickets_with_download'] = [p for p in ctx['cart']['positions'] if p.generate_ticket]
|
||||
@@ -328,14 +342,23 @@ class OrderPositionDetails(EventViewMixin, OrderPositionDetailMixin, CartMixin,
|
||||
return buttons
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
qs = self.order.positions.select_related('tax_rule').filter(
|
||||
Q(pk=self.position.pk) | Q(addon_to__id=self.position.pk)
|
||||
)
|
||||
if self.request.event.settings.show_checkin_number_user:
|
||||
qs = qs.annotate(
|
||||
checkin_count=Subquery(
|
||||
Checkin.objects.filter(
|
||||
successful=True, type=Checkin.TYPE_ENTRY, position_id=OuterRef('pk')
|
||||
).order_by().values('position').annotate(c=Count('*')).values('c')
|
||||
)
|
||||
)
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
ctx['can_download_multi'] = False
|
||||
ctx['position'] = self.position
|
||||
ctx['cart'] = self.get_cart(
|
||||
answers=True, downloads=ctx['can_download'],
|
||||
queryset=self.order.positions.select_related('tax_rule').filter(
|
||||
Q(pk=self.position.pk) | Q(addon_to__id=self.position.pk)
|
||||
),
|
||||
queryset=qs,
|
||||
order=self.order
|
||||
)
|
||||
ctx['tickets_with_download'] = [p for p in ctx['cart']['positions'] if p.generate_ticket]
|
||||
|
||||
Reference in New Issue
Block a user