mirror of
https://github.com/pretix/pretix.git
synced 2026-08-24 13:02:00 +00:00
Added voucher tag statistics
This commit is contained in:
@@ -10,6 +10,11 @@
|
|||||||
{% trans "All Vouchers" %}
|
{% trans "All Vouchers" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li {% if "event.vouchers.tags" == url_name %}class="active"{% endif %}>
|
||||||
|
<a href="{% url 'control:event.vouchers.tags' organizer=request.event.organizer.slug event=request.event.slug %}">
|
||||||
|
{% trans "Tags" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{% block inside %}
|
{% block inside %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
{% extends "pretixcontrol/vouchers/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block inside %}
|
||||||
|
<p>
|
||||||
|
{% blocktrans trimmed %}
|
||||||
|
If you add a "tag" to a voucher, you can here see statistics on their usage.
|
||||||
|
{% endblocktrans %}
|
||||||
|
</p>
|
||||||
|
{% if tags|length == 0 %}
|
||||||
|
<div class="empty-collection">
|
||||||
|
<p>
|
||||||
|
{% blocktrans trimmed %}
|
||||||
|
You haven't added any tags to vouchers yet.
|
||||||
|
{% endblocktrans %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-hover table-condensed">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{% trans "Tag" %}</th>
|
||||||
|
<th>{% trans "Redeemed vouchers" %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for t in tags %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong><a
|
||||||
|
href="{% url "control:event.vouchers" organizer=request.event.organizer.slug event=request.event.slug %}?tag={{ t.tag|urlencode }}">
|
||||||
|
{{ t.tag }}
|
||||||
|
</a></strong> <small>({{ t.redeemed }} / {{ t.total }})</small>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="progress">
|
||||||
|
<div class="progress-bar progress-bar-{{ t.percentage }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
@@ -59,6 +59,7 @@ urlpatterns = [
|
|||||||
name='event.items.quotas.delete'),
|
name='event.items.quotas.delete'),
|
||||||
url(r'^quotas/add$', item.QuotaCreate.as_view(), name='event.items.quotas.add'),
|
url(r'^quotas/add$', item.QuotaCreate.as_view(), name='event.items.quotas.add'),
|
||||||
url(r'^vouchers/$', vouchers.VoucherList.as_view(), name='event.vouchers'),
|
url(r'^vouchers/$', vouchers.VoucherList.as_view(), name='event.vouchers'),
|
||||||
|
url(r'^vouchers/tags/$', vouchers.VoucherTags.as_view(), name='event.vouchers.tags'),
|
||||||
url(r'^vouchers/(?P<voucher>\d+)/$', vouchers.VoucherUpdate.as_view(), name='event.voucher'),
|
url(r'^vouchers/(?P<voucher>\d+)/$', vouchers.VoucherUpdate.as_view(), name='event.voucher'),
|
||||||
url(r'^vouchers/(?P<voucher>\d+)/delete$', vouchers.VoucherDelete.as_view(),
|
url(r'^vouchers/(?P<voucher>\d+)/delete$', vouchers.VoucherDelete.as_view(),
|
||||||
name='event.voucher.delete'),
|
name='event.voucher.delete'),
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.core.urlresolvers import resolve, reverse
|
from django.core.urlresolvers import resolve, reverse
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.models import Q
|
from django.db.models import Count, Q, Sum
|
||||||
from django.http import Http404, HttpResponseRedirect
|
from django.http import Http404, HttpResponseRedirect
|
||||||
from django.utils.timezone import now
|
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.generic import CreateView, DeleteView, ListView, UpdateView
|
from django.views.generic import (
|
||||||
|
CreateView, DeleteView, ListView, TemplateView, UpdateView,
|
||||||
|
)
|
||||||
|
|
||||||
from pretix.base.models import Voucher
|
from pretix.base.models import Voucher
|
||||||
from pretix.control.forms.vouchers import VoucherBulkForm, VoucherForm
|
from pretix.control.forms.vouchers import VoucherBulkForm, VoucherForm
|
||||||
@@ -39,6 +41,24 @@ class VoucherList(EventPermissionRequiredMixin, ListView):
|
|||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
|
class VoucherTags(EventPermissionRequiredMixin, TemplateView):
|
||||||
|
template_name = 'pretixcontrol/vouchers/tags.html'
|
||||||
|
permission = 'can_change_vouchers'
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
ctx = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
tags = self.request.event.vouchers.order_by().filter(tag__isnull=False).values('tag').annotate(
|
||||||
|
total=Count('id'),
|
||||||
|
redeemed=Sum('redeemed')
|
||||||
|
)
|
||||||
|
for t in tags:
|
||||||
|
t['percentage'] = int((t['redeemed'] / t['total']) * 100)
|
||||||
|
|
||||||
|
ctx['tags'] = tags
|
||||||
|
return ctx
|
||||||
|
|
||||||
|
|
||||||
class VoucherDelete(EventPermissionRequiredMixin, DeleteView):
|
class VoucherDelete(EventPermissionRequiredMixin, DeleteView):
|
||||||
model = Voucher
|
model = Voucher
|
||||||
template_name = 'pretixcontrol/vouchers/delete.html'
|
template_name = 'pretixcontrol/vouchers/delete.html'
|
||||||
|
|||||||
@@ -111,4 +111,12 @@ h1 .btn-sm {
|
|||||||
font-size: 200px;
|
font-size: 200px;
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.table .progress {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@for $i from 0 through 100 {
|
||||||
|
.progress-bar-#{$i} { width: 1% * $i; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user