mirror of
https://github.com/pretix/pretix.git
synced 2026-08-20 12:26:27 +00:00
Add typeahead suggestions for voucher tag field (#6058)
Suggest existing tags as the user types in the voucher tag field. Waiting list voucher tags are excluded from suggestions.
This commit is contained in:
@@ -106,6 +106,11 @@ class VoucherForm(I18nModelForm):
|
|||||||
pass
|
pass
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
self.fields['tag'].widget.attrs['data-typeahead-url'] = reverse('control:event.vouchers.tags.typeahead', kwargs={
|
||||||
|
'event': instance.event.slug,
|
||||||
|
'organizer': instance.event.organizer.slug,
|
||||||
|
})
|
||||||
|
|
||||||
if instance.event.has_subevents:
|
if instance.event.has_subevents:
|
||||||
self.fields['subevent'].queryset = instance.event.subevents.all()
|
self.fields['subevent'].queryset = instance.event.subevents.all()
|
||||||
self.fields['subevent'].widget = Select2(
|
self.fields['subevent'].widget = Select2(
|
||||||
|
|||||||
@@ -370,6 +370,7 @@ urlpatterns = [
|
|||||||
re_path(r'^discounts/add$', discounts.DiscountCreate.as_view(), name='event.items.discounts.add'),
|
re_path(r'^discounts/add$', discounts.DiscountCreate.as_view(), name='event.items.discounts.add'),
|
||||||
re_path(r'^vouchers/$', vouchers.VoucherList.as_view(), name='event.vouchers'),
|
re_path(r'^vouchers/$', vouchers.VoucherList.as_view(), name='event.vouchers'),
|
||||||
re_path(r'^vouchers/tags/$', vouchers.VoucherTags.as_view(), name='event.vouchers.tags'),
|
re_path(r'^vouchers/tags/$', vouchers.VoucherTags.as_view(), name='event.vouchers.tags'),
|
||||||
|
re_path(r'^vouchers/tags/typeahead$', typeahead.voucher_tag_typeahead, name='event.vouchers.tags.typeahead'),
|
||||||
re_path(r'^vouchers/rng$', vouchers.VoucherRNG.as_view(), name='event.vouchers.rng'),
|
re_path(r'^vouchers/rng$', vouchers.VoucherRNG.as_view(), name='event.vouchers.rng'),
|
||||||
re_path(r'^vouchers/item_select$', typeahead.itemvarquota_select2, name='event.vouchers.itemselect2'),
|
re_path(r'^vouchers/item_select$', typeahead.itemvarquota_select2, name='event.vouchers.itemselect2'),
|
||||||
re_path(r'^vouchers/(?P<voucher>\d+)/$', vouchers.VoucherUpdate.as_view(), name='event.voucher'),
|
re_path(r'^vouchers/(?P<voucher>\d+)/$', vouchers.VoucherUpdate.as_view(), name='event.voucher'),
|
||||||
|
|||||||
@@ -975,6 +975,21 @@ def subevent_meta_values(request, organizer, event):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@event_permission_required('event.vouchers:read')
|
||||||
|
def voucher_tag_typeahead(request, **kwargs):
|
||||||
|
q = request.GET.get('q', '')
|
||||||
|
tags = request.event.vouchers.filter(
|
||||||
|
tag__isnull=False,
|
||||||
|
waitinglistentries__isnull=True,
|
||||||
|
).filter(
|
||||||
|
tag__icontains=q,
|
||||||
|
).values_list('tag', flat=True).distinct().order_by('tag')[:10]
|
||||||
|
|
||||||
|
return JsonResponse({
|
||||||
|
'results': [{'name': t} for t in tags]
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def item_meta_values(request, organizer, event):
|
def item_meta_values(request, organizer, event):
|
||||||
q = request.GET.get('q')
|
q = request.GET.get('q')
|
||||||
propname = request.GET.get('property')
|
propname = request.GET.get('property')
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ from tests.base import SoupTestMixin, extract_form_fields
|
|||||||
|
|
||||||
from pretix.base.models import (
|
from pretix.base.models import (
|
||||||
Event, Item, ItemVariation, Order, OrderPosition, Organizer, Quota, Team,
|
Event, Item, ItemVariation, Order, OrderPosition, Organizer, Quota, Team,
|
||||||
User, Voucher,
|
User, Voucher, WaitingListEntry,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -771,3 +771,38 @@ class VoucherFormTest(SoupTestMixin, TransactionTestCase):
|
|||||||
|
|
||||||
assert len(doc.select('.alert-warning ul li')) == 1 # Check that there's exactly 1 item in the warning list
|
assert len(doc.select('.alert-warning ul li')) == 1 # Check that there's exactly 1 item in the warning list
|
||||||
assert doc.text.count('Order DEDUP') == 1 # Check that the order is listed exactly once
|
assert doc.text.count('Order DEDUP') == 1 # Check that the order is listed exactly once
|
||||||
|
|
||||||
|
def test_tag_typeahead(self):
|
||||||
|
with scopes_disabled():
|
||||||
|
self.event.vouchers.create(item=self.ticket, code='AAAAAAA', tag='early-bird')
|
||||||
|
self.event.vouchers.create(item=self.ticket, code='BBBBBBB', tag='early-vip')
|
||||||
|
self.event.vouchers.create(item=self.ticket, code='CCCCCCC', tag='sponsor')
|
||||||
|
|
||||||
|
url = '/control/event/%s/%s/vouchers/tags/typeahead' % (self.orga.slug, self.event.slug)
|
||||||
|
resp = self.client.get(url + '?q=early')
|
||||||
|
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = json.loads(resp.content.decode())
|
||||||
|
names = [r['name'] for r in data['results']]
|
||||||
|
|
||||||
|
assert 'early-bird' in names
|
||||||
|
assert 'early-vip' in names
|
||||||
|
assert 'sponsor' not in names
|
||||||
|
|
||||||
|
def test_tag_typeahead_excludes_waiting_list(self):
|
||||||
|
with scopes_disabled():
|
||||||
|
v = self.event.vouchers.create(item=self.ticket, code='AAAAAAA', tag='waiting-list')
|
||||||
|
WaitingListEntry.objects.create(
|
||||||
|
event=self.event, item=self.ticket, email='foo@example.com', voucher=v
|
||||||
|
)
|
||||||
|
self.event.vouchers.create(item=self.ticket, code='BBBBBBB', tag='walk-ins')
|
||||||
|
|
||||||
|
url = '/control/event/%s/%s/vouchers/tags/typeahead' % (self.orga.slug, self.event.slug)
|
||||||
|
resp = self.client.get(url + '?q=wa')
|
||||||
|
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = json.loads(resp.content.decode())
|
||||||
|
names = [r['name'] for r in data['results']]
|
||||||
|
|
||||||
|
assert 'walk-ins' in names
|
||||||
|
assert 'waiting-list' not in names
|
||||||
|
|||||||
Reference in New Issue
Block a user