forked from CGM_Public/pretix_original
Allow to bulk-delete vouchers
This commit is contained in:
@@ -0,0 +1,40 @@
|
|||||||
|
{% extends "pretixcontrol/event/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
{% block title %}{% trans "Delete vouchers" %}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<h1>{% trans "Delete vouchers" %}</h1>
|
||||||
|
<form action="" method="post" class="form-horizontal">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% if allowed %}
|
||||||
|
<p>{% blocktrans %}Are you sure you want to delete the following vouchers?{% endblocktrans %}</p>
|
||||||
|
<ul>
|
||||||
|
{% for s in allowed %}
|
||||||
|
<li>
|
||||||
|
{{ s }}
|
||||||
|
<input type="hidden" name="voucher" value="{{ s.pk }}">
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
{% if forbidden %}
|
||||||
|
<p>{% blocktrans trimmed %}The following vouchers can't be deleted as they already have been redeemed, but they will be set to fully redeemed instead.{% endblocktrans %}</p>
|
||||||
|
<ul>
|
||||||
|
{% for s in forbidden %}
|
||||||
|
<li>
|
||||||
|
{{ s }}
|
||||||
|
<input type="hidden" name="voucher" value="{{ s.pk }}">
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
<div class="form-group submit-group">
|
||||||
|
<a href="{% url "control:event.vouchers" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default btn-cancel">
|
||||||
|
{% trans "Cancel" %}
|
||||||
|
</a>
|
||||||
|
<button type="submit" class="btn btn-danger btn-save" value="delete_confirm" name="action">
|
||||||
|
{% trans "Delete" %}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
@@ -83,56 +83,73 @@
|
|||||||
class="btn btn-default"><i class="fa fa-download"></i>
|
class="btn btn-default"><i class="fa fa-download"></i>
|
||||||
{% trans "Download list" %}</a>
|
{% trans "Download list" %}</a>
|
||||||
</p>
|
</p>
|
||||||
<div class="table-responsive">
|
<form action="{% url "control:event.vouchers.bulkaction" organizer=request.event.organizer.slug event=request.event.slug %}" method="post">
|
||||||
<table class="table table-hover table-quotas">
|
{% csrf_token %}
|
||||||
<thead>
|
<div class="table-responsive">
|
||||||
<tr>
|
<table class="table table-hover table-quotas">
|
||||||
<th>{% trans "Voucher code" %}</th>
|
<thead>
|
||||||
<th>{% trans "Redemptions" %}</th>
|
|
||||||
<th>{% trans "Expiry" %}</th>
|
|
||||||
<th>{% trans "Tag" %}</th>
|
|
||||||
<th>{% trans "Product" %}</th>
|
|
||||||
{% if request.event.has_subevents %}
|
|
||||||
<th>{% trans "Date" context "subevent" %}</th>
|
|
||||||
{% endif %}
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for v in vouchers %}
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<th>
|
||||||
<strong><a href="
|
{% if "can_change_vouchers" in request.eventpermset %}
|
||||||
{% url "control:event.voucher" organizer=request.event.organizer.slug event=request.event.slug voucher=v.id %}">{{ v.code }}</a></strong>
|
<input type="checkbox" data-toggle-table />
|
||||||
</td>
|
|
||||||
<td>{{ v.redeemed }} / {{ v.max_usages }}</td>
|
|
||||||
<td>{{ v.valid_until|date }}</td>
|
|
||||||
<td>
|
|
||||||
{{ v.tag }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{% if v.item %}
|
|
||||||
{{ v.item }}
|
|
||||||
{% if v.variation %}
|
|
||||||
– {{ v.variation }}
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
|
||||||
{% blocktrans trimmed with quota=v.quota.name %}
|
|
||||||
Any product in quota "{{ quota }}"
|
|
||||||
{% endblocktrans %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</th>
|
||||||
|
<th>{% trans "Voucher code" %}</th>
|
||||||
|
<th>{% trans "Redemptions" %}</th>
|
||||||
|
<th>{% trans "Expiry" %}</th>
|
||||||
|
<th>{% trans "Tag" %}</th>
|
||||||
|
<th>{% trans "Product" %}</th>
|
||||||
{% if request.event.has_subevents %}
|
{% if request.event.has_subevents %}
|
||||||
<td>{{ v.subevent.name }} – {{ v.subevent.get_date_range_display }}</td>
|
<th>{% trans "Date" context "subevent" %}</th>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<td class="text-right">
|
<th></th>
|
||||||
<a href="{% url "control:event.voucher.delete" organizer=request.event.organizer.slug event=request.event.slug voucher=v.id %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
</thead>
|
||||||
</tbody>
|
<tbody>
|
||||||
</table>
|
{% for v in vouchers %}
|
||||||
</div>
|
<tr>
|
||||||
|
<td>
|
||||||
|
{% if "can_change_vouchers" in request.eventpermset %}
|
||||||
|
<input type="checkbox" name="voucher" class="" value="{{ v.pk }}"/>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<strong><a href="{% url "control:event.voucher" organizer=request.event.organizer.slug event=request.event.slug voucher=v.id %}">{{ v.code }}</a></strong>
|
||||||
|
</td>
|
||||||
|
<td>{{ v.redeemed }} / {{ v.max_usages }}</td>
|
||||||
|
<td>{{ v.valid_until|date }}</td>
|
||||||
|
<td>
|
||||||
|
{{ v.tag }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if v.item %}
|
||||||
|
{{ v.item }}
|
||||||
|
{% if v.variation %}
|
||||||
|
– {{ v.variation }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% blocktrans trimmed with quota=v.quota.name %}
|
||||||
|
Any product in quota "{{ quota }}"
|
||||||
|
{% endblocktrans %}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% if request.event.has_subevents %}
|
||||||
|
<td>{{ v.subevent.name }} – {{ v.subevent.get_date_range_display }}</td>
|
||||||
|
{% endif %}
|
||||||
|
<td class="text-right">
|
||||||
|
<a href="{% url "control:event.voucher.delete" organizer=request.event.organizer.slug event=request.event.slug voucher=v.id %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% if "can_change_vouchers" in request.eventpermset %}
|
||||||
|
<button type="submit" class="btn btn-default btn-save" name="action" value="delete">
|
||||||
|
{% trans "Delete selected" %}
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
</form>
|
||||||
{% include "pretixcontrol/pagination.html" %}
|
{% include "pretixcontrol/pagination.html" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ urlpatterns = [
|
|||||||
url(r'^vouchers/add$', vouchers.VoucherCreate.as_view(), name='event.vouchers.add'),
|
url(r'^vouchers/add$', vouchers.VoucherCreate.as_view(), name='event.vouchers.add'),
|
||||||
url(r'^vouchers/go$', vouchers.VoucherGo.as_view(), name='event.vouchers.go'),
|
url(r'^vouchers/go$', vouchers.VoucherGo.as_view(), name='event.vouchers.go'),
|
||||||
url(r'^vouchers/bulk_add$', vouchers.VoucherBulkCreate.as_view(), name='event.vouchers.bulk'),
|
url(r'^vouchers/bulk_add$', vouchers.VoucherBulkCreate.as_view(), name='event.vouchers.bulk'),
|
||||||
|
url(r'^vouchers/bulk_action$', vouchers.VoucherBulkAction.as_view(), name='event.vouchers.bulkaction'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/transition$', orders.OrderTransition.as_view(),
|
url(r'^orders/(?P<code>[0-9A-Z]+)/transition$', orders.OrderTransition.as_view(),
|
||||||
name='event.order.transition'),
|
name='event.order.transition'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/resend$', orders.OrderResendLink.as_view(),
|
url(r'^orders/(?P<code>[0-9A-Z]+)/resend$', orders.OrderResendLink.as_view(),
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from django.http import (
|
|||||||
Http404, HttpResponse, HttpResponseBadRequest, HttpResponseRedirect,
|
Http404, HttpResponse, HttpResponseBadRequest, HttpResponseRedirect,
|
||||||
JsonResponse,
|
JsonResponse,
|
||||||
)
|
)
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect, render
|
||||||
from django.urls import resolve, reverse
|
from django.urls import resolve, reverse
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
@@ -322,3 +322,41 @@ class VoucherRNG(EventPermissionRequiredMixin, View):
|
|||||||
'organizer': self.request.event.organizer.slug,
|
'organizer': self.request.event.organizer.slug,
|
||||||
'event': self.request.event.slug,
|
'event': self.request.event.slug,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
class VoucherBulkAction(EventPermissionRequiredMixin, View):
|
||||||
|
permission = 'can_change_vouchers'
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def objects(self):
|
||||||
|
return self.request.event.vouchers.filter(
|
||||||
|
id__in=self.request.POST.getlist('voucher')
|
||||||
|
)
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
if request.POST.get('action') == 'delete':
|
||||||
|
return render(request, 'pretixcontrol/vouchers/delete_bulk.html', {
|
||||||
|
'allowed': self.objects.filter(redeemed=0),
|
||||||
|
'forbidden': self.objects.exclude(redeemed=0),
|
||||||
|
})
|
||||||
|
elif request.POST.get('action') == 'delete_confirm':
|
||||||
|
for obj in self.objects:
|
||||||
|
if obj.allow_delete():
|
||||||
|
obj.log_action('pretix.voucher.deleted', user=self.request.user)
|
||||||
|
obj.delete()
|
||||||
|
else:
|
||||||
|
obj.log_action('pretix.voucher.changed', user=self.request.user, data={
|
||||||
|
'max_usages': min(obj.redeemed, obj.max_usages),
|
||||||
|
'bulk': True
|
||||||
|
})
|
||||||
|
obj.max_usages = min(obj.redeemed, obj.max_usages)
|
||||||
|
obj.save(update_fields=['max_usages'])
|
||||||
|
messages.success(request, _('The selected vouchers have been deleted or disabled.'))
|
||||||
|
return redirect(self.get_success_url())
|
||||||
|
|
||||||
|
def get_success_url(self) -> str:
|
||||||
|
return reverse('control:event.vouchers', kwargs={
|
||||||
|
'organizer': self.request.event.organizer.slug,
|
||||||
|
'event': self.request.event.slug,
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user