forked from CGM_Public/pretix_original
Improve waiting list filters
This commit is contained in:
@@ -81,9 +81,19 @@
|
|||||||
<option value="a"
|
<option value="a"
|
||||||
{% if request.GET.status == "p" %}selected="selected"{% endif %}>{% trans "All entries" %}</option>
|
{% if request.GET.status == "p" %}selected="selected"{% endif %}>{% trans "All entries" %}</option>
|
||||||
<option value="w"
|
<option value="w"
|
||||||
{% if request.GET.status == "w" or not request.GET.status %}selected="selected"{% endif %}>{% trans "Waiting" %}</option>
|
{% if request.GET.status == "w" or not request.GET.status %}selected="selected"{% endif %}>
|
||||||
|
{% trans "Waiting for a voucher" %}</option>
|
||||||
<option value="s"
|
<option value="s"
|
||||||
{% if request.GET.status == "s" %}selected="selected"{% endif %}>{% trans "Voucher assigned" %}</option>
|
{% if request.GET.status == "s" %}selected="selected"{% endif %}>{% trans "Voucher assigned" %}</option>
|
||||||
|
<option value="v"
|
||||||
|
{% if request.GET.status == "v" %}selected="selected"{% endif %}>
|
||||||
|
{% trans "Waiting for redemption" %}</option>
|
||||||
|
<option value="r"
|
||||||
|
{% if request.GET.status == "r" %}selected="selected"{% endif %}>
|
||||||
|
{% trans "Successfully redeemed" %}</option>
|
||||||
|
<option value="e"
|
||||||
|
{% if request.GET.status == "e" %}selected="selected"{% endif %}>
|
||||||
|
{% trans "Voucher expired" %}</option>
|
||||||
</select>
|
</select>
|
||||||
<select name="item" class="form-control">
|
<select name="item" class="form-control">
|
||||||
<option value="">{% trans "All products" %}</option>
|
<option value="">{% trans "All products" %}</option>
|
||||||
@@ -108,7 +118,7 @@
|
|||||||
<button class="btn btn-primary" type="submit">{% trans "Filter" %}</button>
|
<button class="btn btn-primary" type="submit">{% trans "Filter" %}</button>
|
||||||
</form>
|
</form>
|
||||||
</p>
|
</p>
|
||||||
<form method="post" action="">
|
<form method="post" action="?next={{ request.get_full_path|urlencode }}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-condensed table-hover">
|
<table class="table table-condensed table-hover">
|
||||||
@@ -141,7 +151,13 @@
|
|||||||
<td>{{ e.created|date:"SHORT_DATETIME_FORMAT" }}</td>
|
<td>{{ e.created|date:"SHORT_DATETIME_FORMAT" }}</td>
|
||||||
<td>
|
<td>
|
||||||
{% if e.voucher %}
|
{% if e.voucher %}
|
||||||
<span class="label label-success">{% trans "Voucher assigned" %}</span>
|
{% if e.voucher.redeemed >= e.voucher.max_usages %}
|
||||||
|
<span class="label label-success">{% trans "Voucher redeemed" %}</span>
|
||||||
|
{% elif not e.voucher.is_active %}
|
||||||
|
<span class="label label-danger">{% trans "Voucher expired" %}</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="label label-warning">{% trans "Voucher assigned" %}</span>
|
||||||
|
{% endif %}
|
||||||
{% elif e.availability.0 == 100 %}
|
{% elif e.availability.0 == 100 %}
|
||||||
<span class="label label-warning">
|
<span class="label label-warning">
|
||||||
{% blocktrans with num=e.availability.1 %}
|
{% blocktrans with num=e.availability.1 %}
|
||||||
@@ -165,7 +181,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if not e.voucher %}
|
{% if not e.voucher %}
|
||||||
<a href="{% url "control:event.orders.waitinglist.delete" organizer=request.event.organizer.slug event=request.event.slug entry=e.id %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a>
|
<a href="{% url "control:event.orders.waitinglist.delete" organizer=request.event.organizer.slug event=request.event.slug entry=e.id %}?next={{ request.get_full_path|urlencode }}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="btn btn-danger btn-sm disabled"><i class="fa fa-trash"></i></span>
|
<span class="btn btn-danger btn-sm disabled"><i class="fa fa-trash"></i></span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.models import Sum
|
from django.db.models import F, Q, Sum
|
||||||
from django.db.models.functions import Coalesce
|
from django.db.models.functions import Coalesce
|
||||||
from django.http import Http404, HttpResponseRedirect
|
from django.http import Http404, HttpResponseRedirect
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.utils.http import is_safe_url
|
||||||
|
from django.utils.timezone import now
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.views import View
|
from django.views import View
|
||||||
from django.views.generic import ListView
|
from django.views.generic import ListView
|
||||||
@@ -66,6 +68,8 @@ class WaitingListView(EventPermissionRequiredMixin, PaginationMixin, ListView):
|
|||||||
else:
|
else:
|
||||||
messages.success(request, _('An email containing a voucher code has been sent to the '
|
messages.success(request, _('An email containing a voucher code has been sent to the '
|
||||||
'specified address.'))
|
'specified address.'))
|
||||||
|
if "next" in self.request.GET and is_safe_url(self.request.GET.get("next"), allowed_hosts=None):
|
||||||
|
return redirect(self.request.GET.get("next"))
|
||||||
return redirect(reverse('control:event.orders.waitinglist', kwargs={
|
return redirect(reverse('control:event.orders.waitinglist', kwargs={
|
||||||
'event': request.event.slug,
|
'event': request.event.slug,
|
||||||
'organizer': request.event.organizer.slug
|
'organizer': request.event.organizer.slug
|
||||||
@@ -89,6 +93,23 @@ class WaitingListView(EventPermissionRequiredMixin, PaginationMixin, ListView):
|
|||||||
qs = qs.filter(voucher__isnull=False)
|
qs = qs.filter(voucher__isnull=False)
|
||||||
elif s == 'a':
|
elif s == 'a':
|
||||||
pass
|
pass
|
||||||
|
elif s == 'r':
|
||||||
|
qs = qs.filter(
|
||||||
|
voucher__isnull=False,
|
||||||
|
voucher__redeemed__gte=F('voucher__max_usages'),
|
||||||
|
)
|
||||||
|
elif s == 'v':
|
||||||
|
qs = qs.filter(
|
||||||
|
voucher__isnull=False,
|
||||||
|
voucher__redeemed__lt=F('voucher__max_usages'),
|
||||||
|
).filter(Q(voucher__valid_until__isnull=True) | Q(voucher__valid_until__gt=now()))
|
||||||
|
elif s == 'e':
|
||||||
|
qs = qs.filter(
|
||||||
|
voucher__isnull=False,
|
||||||
|
voucher__redeemed__lt=F('voucher__max_usages'),
|
||||||
|
voucher__valid_until__isnull=False,
|
||||||
|
voucher__valid_until__lte=now()
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
qs = qs.filter(voucher__isnull=True)
|
qs = qs.filter(voucher__isnull=True)
|
||||||
|
|
||||||
@@ -160,6 +181,8 @@ class EntryDelete(EventPermissionRequiredMixin, DeleteView):
|
|||||||
self.object.log_action('pretix.event.orders.waitinglist.deleted', user=self.request.user)
|
self.object.log_action('pretix.event.orders.waitinglist.deleted', user=self.request.user)
|
||||||
self.object.delete()
|
self.object.delete()
|
||||||
messages.success(self.request, _('The selected entry has been deleted.'))
|
messages.success(self.request, _('The selected entry has been deleted.'))
|
||||||
|
if "next" in self.request.GET and is_safe_url(self.request.GET.get("next"), allowed_hosts=None):
|
||||||
|
return redirect(self.request.GET.get("next"))
|
||||||
return HttpResponseRedirect(success_url)
|
return HttpResponseRedirect(success_url)
|
||||||
|
|
||||||
def get_success_url(self) -> str:
|
def get_success_url(self) -> str:
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
|
|
||||||
@@ -29,8 +31,13 @@ def env():
|
|||||||
WaitingListEntry.objects.create(
|
WaitingListEntry.objects.create(
|
||||||
event=event, item=item1, email='success@example.org', voucher=v
|
event=event, item=item1, email='success@example.org', voucher=v
|
||||||
)
|
)
|
||||||
|
v = Voucher.objects.create(item=item1, event=event, block_quota=True, redeemed=0, valid_until=now() - timedelta(days=5))
|
||||||
WaitingListEntry.objects.create(
|
WaitingListEntry.objects.create(
|
||||||
event=event, item=item2, email='item2@example.org'
|
event=event, item=item2, email='expired@example.org', voucher=v
|
||||||
|
)
|
||||||
|
v = Voucher.objects.create(item=item1, event=event, block_quota=True, redeemed=0, valid_until=now() + timedelta(days=5))
|
||||||
|
WaitingListEntry.objects.create(
|
||||||
|
event=event, item=item2, email='valid@example.org', voucher=v
|
||||||
)
|
)
|
||||||
|
|
||||||
t = Team.objects.create(organizer=o, can_view_orders=True, can_change_orders=True)
|
t = Team.objects.create(organizer=o, can_view_orders=True, can_change_orders=True)
|
||||||
@@ -45,17 +52,40 @@ def test_list(client, env):
|
|||||||
|
|
||||||
response = client.get('/control/event/dummy/dummy/waitinglist/')
|
response = client.get('/control/event/dummy/dummy/waitinglist/')
|
||||||
assert 'success@example.org' not in response.rendered_content
|
assert 'success@example.org' not in response.rendered_content
|
||||||
assert 'item2@example.org' in response.rendered_content
|
assert 'expired@example.org' not in response.rendered_content
|
||||||
assert 'foo0@bar.com' in response.rendered_content
|
assert 'foo0@bar.com' in response.rendered_content
|
||||||
assert response.context['estimate'] == 23 * 6
|
assert 'valid@example.org' not in response.rendered_content
|
||||||
|
assert response.context['estimate'] == 23 * 5
|
||||||
|
|
||||||
response = client.get('/control/event/dummy/dummy/waitinglist/?status=a')
|
response = client.get('/control/event/dummy/dummy/waitinglist/?status=a')
|
||||||
assert 'success@example.org' in response.rendered_content
|
assert 'success@example.org' in response.rendered_content
|
||||||
assert 'foo0@bar.com' in response.rendered_content
|
assert 'foo0@bar.com' in response.rendered_content
|
||||||
|
assert 'expired@example.org' in response.rendered_content
|
||||||
|
assert 'valid@example.org' in response.rendered_content
|
||||||
|
|
||||||
response = client.get('/control/event/dummy/dummy/waitinglist/?status=s')
|
response = client.get('/control/event/dummy/dummy/waitinglist/?status=s')
|
||||||
assert 'success@example.org' in response.rendered_content
|
assert 'success@example.org' in response.rendered_content
|
||||||
assert 'foo0@bar.com' not in response.rendered_content
|
assert 'foo0@bar.com' not in response.rendered_content
|
||||||
|
assert 'expired@example.org' in response.rendered_content
|
||||||
|
assert 'valid@example.org' in response.rendered_content
|
||||||
|
|
||||||
|
response = client.get('/control/event/dummy/dummy/waitinglist/?status=v')
|
||||||
|
assert 'success@example.org' not in response.rendered_content
|
||||||
|
assert 'foo0@bar.com' not in response.rendered_content
|
||||||
|
assert 'expired@example.org' not in response.rendered_content
|
||||||
|
assert 'valid@example.org' in response.rendered_content
|
||||||
|
|
||||||
|
response = client.get('/control/event/dummy/dummy/waitinglist/?status=r')
|
||||||
|
assert 'success@example.org' in response.rendered_content
|
||||||
|
assert 'foo0@bar.com' not in response.rendered_content
|
||||||
|
assert 'expired@example.org' not in response.rendered_content
|
||||||
|
assert 'valid@example.org' not in response.rendered_content
|
||||||
|
|
||||||
|
response = client.get('/control/event/dummy/dummy/waitinglist/?status=e')
|
||||||
|
assert 'success@example.org' not in response.rendered_content
|
||||||
|
assert 'expired@example.org' in response.rendered_content
|
||||||
|
assert 'foo0@bar.com' not in response.rendered_content
|
||||||
|
assert 'valid@example.org' not in response.rendered_content
|
||||||
|
|
||||||
response = client.get('/control/event/dummy/dummy/waitinglist/?item=%d' % env[3].pk)
|
response = client.get('/control/event/dummy/dummy/waitinglist/?item=%d' % env[3].pk)
|
||||||
assert 'item2@example.org' not in response.rendered_content
|
assert 'item2@example.org' not in response.rendered_content
|
||||||
@@ -89,5 +119,5 @@ def test_dashboard(client, env):
|
|||||||
quota = Quota.objects.create(name="Test", size=2, event=env[0])
|
quota = Quota.objects.create(name="Test", size=2, event=env[0])
|
||||||
quota.items.add(env[3])
|
quota.items.add(env[3])
|
||||||
w = waitinglist_widgets(env[0])
|
w = waitinglist_widgets(env[0])
|
||||||
assert '3' in w[0]['content']
|
assert '1' in w[0]['content']
|
||||||
assert '6' in w[1]['content']
|
assert '5' in w[1]['content']
|
||||||
|
|||||||
Reference in New Issue
Block a user