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

@@ -66,7 +66,9 @@ def _default_context(request):
if complain_testmode_orders is None:
complain_testmode_orders = request.event.orders.filter(testmode=True).exists()
request.event.cache.set('complain_testmode_orders', complain_testmode_orders, 30)
ctx['complain_testmode_orders'] = complain_testmode_orders
ctx['complain_testmode_orders'] = complain_testmode_orders and request.user.has_event_permission(
request.organizer, request.event, 'can_view_orders', request=request
)
else:
ctx['complain_testmode_orders'] = False

View File

@@ -105,6 +105,11 @@ class CheckinListForm(forms.ModelForm):
'exit_all_at': NextTimeField,
}
def clean(self):
d = super().clean()
CheckinList.validate_rules(d.get('rules'))
return d
class SimpleCheckinListForm(forms.ModelForm):
def __init__(self, **kwargs):

View File

@@ -1134,6 +1134,13 @@ class TicketSettingsForm(SettingsForm):
class CommentForm(I18nModelForm):
def __init__(self, *args, **kwargs):
self.readonly = kwargs.pop('readonly')
super().__init__(*args, **kwargs)
if self.readonly:
self.fields['comment'].widget.attrs['readonly'] = 'readonly'
class Meta:
model = Event
fields = ['comment']

View File

@@ -149,7 +149,7 @@ class TeamForm(forms.ModelForm):
'can_change_teams', 'can_change_organizer_settings',
'can_manage_gift_cards',
'can_change_event_settings', 'can_change_items',
'can_view_orders', 'can_change_orders',
'can_view_orders', 'can_change_orders', 'can_checkin_orders',
'can_view_vouchers', 'can_change_vouchers']
widgets = {
'limit_events': forms.CheckboxSelectMultiple(attrs={

View File

@@ -514,5 +514,5 @@ def merge_in(nav, newnav):
if 'children' not in parents[0]:
parents[0]['children'] = []
parents[0]['children'].append(item)
else:
nav.append(item)
continue
nav.append(item)

View File

@@ -283,6 +283,7 @@
{% for nav in nav_items %}
<li>
<a href="{{ nav.url }}" {% if nav.active %}class="active"{% endif %}
{% if nav.external %}target="_blank"{% endif %}
{% if nav.children %}class="has-children"{% endif %}>
{% if nav.icon %}
{% if "<svg" in nav.icon %}
@@ -301,6 +302,7 @@
{% for item in nav.children %}
<li>
<a href="{{ item.url }}"
{% if item.external %}target="_blank"{% endif %}
{% if item.active %}class="active"{% endif %}>
{{ item.label }}
</a>

View File

@@ -150,12 +150,14 @@
<div class="row">
{% bootstrap_field comment_form.comment layout="horizontal" show_help=True show_label=False horizontal_field_class="col-md-12" %}
</div>
<p class="text-right flip">
<br>
<button class="btn btn-default">
{% trans "Update comment" %}
</button>
</p>
{% if not comment_form.readonly %}
<p class="text-right flip">
<br>
<button class="btn btn-default">
{% trans "Update comment" %}
</button>
</p>
{% endif %}
</form>
</div>
</div>

View File

@@ -35,6 +35,7 @@
{% bootstrap_field form.can_change_items layout="control" %}
{% bootstrap_field form.can_view_orders layout="control" %}
{% bootstrap_field form.can_change_orders layout="control" %}
{% bootstrap_field form.can_checkin_orders layout="control" %}
{% bootstrap_field form.can_view_vouchers layout="control" %}
{% bootstrap_field form.can_change_vouchers layout="control" %}
</fieldset>

View File

@@ -22,8 +22,8 @@ from django.utils.translation import gettext_lazy as _, pgettext, ungettext
from pretix.base.decimal import round_decimal
from pretix.base.models import (
Item, ItemVariation, Order, OrderPosition, OrderRefund, RequiredAction,
SubEvent, Voucher, WaitingListEntry,
Item, ItemCategory, ItemVariation, Order, OrderPosition, OrderRefund,
Question, Quota, RequiredAction, SubEvent, Voucher, WaitingListEntry,
)
from pretix.base.services.quotas import QuotaAvailability
from pretix.base.timeline import timeline_for_event
@@ -313,19 +313,40 @@ def event_index(request, organizer, event):
except SubEvent.DoesNotExist:
pass
widgets = []
for r, result in event_dashboard_widgets.send(sender=request.event, subevent=subevent, lazy=True):
widgets.extend(result)
can_view_orders = request.user.has_event_permission(request.organizer, request.event, 'can_view_orders',
request=request)
can_change_orders = request.user.has_event_permission(request.organizer, request.event, 'can_change_orders',
request=request)
can_change_event_settings = request.user.has_event_permission(request.organizer, request.event,
'can_change_event_settings', request=request)
can_view_vouchers = request.user.has_event_permission(request.organizer, request.event, 'can_view_vouchers',
request=request)
widgets = []
if can_view_orders:
for r, result in event_dashboard_widgets.send(sender=request.event, subevent=subevent, lazy=True):
widgets.extend(result)
qs = request.event.logentry_set.all().select_related('user', 'content_type', 'api_token', 'oauth_application',
'device').order_by('-datetime')
qs = qs.exclude(action_type__in=OVERVIEW_BANLIST)
if not request.user.has_event_permission(request.organizer, request.event, 'can_view_orders', request=request):
if not can_view_orders:
qs = qs.exclude(content_type=ContentType.objects.get_for_model(Order))
if not request.user.has_event_permission(request.organizer, request.event, 'can_view_vouchers', request=request):
if not can_view_vouchers:
qs = qs.exclude(content_type=ContentType.objects.get_for_model(Voucher))
if not can_change_event_settings:
allowed_types = [
ContentType.objects.get_for_model(Voucher),
ContentType.objects.get_for_model(Order)
]
if request.user.has_event_permission(request.organizer, request.event, 'can_change_items', request=request):
allowed_types += [
ContentType.objects.get_for_model(Item),
ContentType.objects.get_for_model(ItemCategory),
ContentType.objects.get_for_model(Quota),
ContentType.objects.get_for_model(Question),
]
qs = qs.filter(content_type__in=allowed_types)
a_qs = request.event.requiredaction_set.filter(done=False)
@@ -334,25 +355,25 @@ def event_index(request, organizer, event):
'logs': qs[:5],
'subevent': subevent,
'actions': a_qs[:5] if can_change_orders else [],
'comment_form': CommentForm(initial={'comment': request.event.comment})
'comment_form': CommentForm(initial={'comment': request.event.comment}, readonly=not can_change_event_settings),
}
ctx['has_overpaid_orders'] = Order.annotate_overpayments(request.event.orders).filter(
ctx['has_overpaid_orders'] = can_view_orders and Order.annotate_overpayments(request.event.orders).filter(
Q(~Q(status=Order.STATUS_CANCELED) & Q(pending_sum_t__lt=0))
| Q(Q(status=Order.STATUS_CANCELED) & Q(pending_sum_rc__lt=0))
).exists()
ctx['has_pending_orders_with_full_payment'] = Order.annotate_overpayments(request.event.orders).filter(
ctx['has_pending_orders_with_full_payment'] = can_view_orders and Order.annotate_overpayments(request.event.orders).filter(
Q(status__in=(Order.STATUS_EXPIRED, Order.STATUS_PENDING)) & Q(pending_sum_t__lte=0) & Q(require_approval=False)
).exists()
ctx['has_pending_refunds'] = OrderRefund.objects.filter(
ctx['has_pending_refunds'] = can_view_orders and OrderRefund.objects.filter(
order__event=request.event,
state__in=(OrderRefund.REFUND_STATE_CREATED, OrderRefund.REFUND_STATE_EXTERNAL)
).exists()
ctx['has_pending_approvals'] = request.event.orders.filter(
ctx['has_pending_approvals'] = can_view_orders and request.event.orders.filter(
status=Order.STATUS_PENDING,
require_approval=True
).exists()
ctx['has_cancellation_requests'] = CancellationRequest.objects.filter(
ctx['has_cancellation_requests'] = can_view_orders and CancellationRequest.objects.filter(
order__event=request.event
).exists()

View File

@@ -55,7 +55,9 @@ from pretix.plugins.stripe.payment import StripeSettingsHolder
from pretix.presale.style import regenerate_css
from ...base.i18n import language
from ...base.models.items import ItemMetaProperty
from ...base.models.items import (
Item, ItemCategory, ItemMetaProperty, Question, Quota,
)
from ...base.settings import SETTINGS_AFFECTING_CSS, LazyI18nStringList
from ..logdisplay import OVERVIEW_BANLIST
from . import CreateView, PaginationMixin, UpdateView
@@ -971,6 +973,21 @@ class EventLog(EventPermissionRequiredMixin, PaginationMixin, ListView):
if not self.request.user.has_event_permission(self.request.organizer, self.request.event, 'can_view_vouchers',
request=self.request):
qs = qs.exclude(content_type=ContentType.objects.get_for_model(Voucher))
if not self.request.user.has_event_permission(self.request.organizer, self.request.event,
'can_change_event_settings', request=self.request):
allowed_types = [
ContentType.objects.get_for_model(Voucher),
ContentType.objects.get_for_model(Order)
]
if self.request.user.has_event_permission(self.request.organizer, self.request.event,
'can_change_items', request=self.request):
allowed_types += [
ContentType.objects.get_for_model(Item),
ContentType.objects.get_for_model(ItemCategory),
ContentType.objects.get_for_model(Quota),
ContentType.objects.get_for_model(Question),
]
qs = qs.filter(content_type__in=allowed_types)
if self.request.GET.get('user') == 'yes':
qs = qs.filter(user__isnull=False)