forked from CGM_Public/pretix_original
Refs #118 -- Asynchronous order cancelling
This commit is contained in:
@@ -94,39 +94,51 @@ def mark_order_paid(order: Order, provider: str=None, info: str=None, date: date
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def mark_order_refunded(order: Order, user: User=None):
|
||||
def mark_order_refunded(order, user=None):
|
||||
"""
|
||||
Mark this order as refunded. This sets the payment status and returns the order object.
|
||||
:param order: The order to change
|
||||
:param user: The user that performed the change
|
||||
"""
|
||||
order.status = Order.STATUS_REFUNDED
|
||||
order.save()
|
||||
order.log_action('pretix.event.order.refunded', user=user)
|
||||
if isinstance(order, int):
|
||||
order = Order.objects.get(pk=order)
|
||||
if isinstance(user, int):
|
||||
user = User.objects.get(pk=user)
|
||||
with order.event.lock():
|
||||
order.status = Order.STATUS_REFUNDED
|
||||
order.save()
|
||||
order.log_action('pretix.event.order.refunded', user=user)
|
||||
|
||||
i = order.invoices.filter(is_cancellation=False).last()
|
||||
if i:
|
||||
generate_cancellation(i)
|
||||
i = order.invoices.filter(is_cancellation=False).last()
|
||||
if i:
|
||||
generate_cancellation(i)
|
||||
|
||||
return order
|
||||
return order
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def cancel_order(order: Order, user: User=None):
|
||||
def cancel_order(order, user=None):
|
||||
"""
|
||||
Mark this order as canceled
|
||||
:param order: The order to change
|
||||
:param user: The user that performed the change
|
||||
"""
|
||||
order.status = Order.STATUS_CANCELLED
|
||||
order.save()
|
||||
order.log_action('pretix.event.order.cancelled', user=user)
|
||||
if isinstance(order, int):
|
||||
order = Order.objects.get(pk=order)
|
||||
if isinstance(user, int):
|
||||
user = User.objects.get(pk=user)
|
||||
with order.event.lock():
|
||||
if order.status not in (Order.STATUS_PENDING, Order.STATUS_EXPIRED):
|
||||
raise OrderError(_('You cannot cancel this order'))
|
||||
order.status = Order.STATUS_CANCELLED
|
||||
order.save()
|
||||
order.log_action('pretix.event.order.cancelled', user=user)
|
||||
|
||||
i = order.invoices.filter(is_cancellation=False).last()
|
||||
if i:
|
||||
generate_cancellation(i)
|
||||
i = order.invoices.filter(is_cancellation=False).last()
|
||||
if i:
|
||||
generate_cancellation(i)
|
||||
|
||||
return order
|
||||
return order
|
||||
|
||||
|
||||
class OrderError(Exception):
|
||||
@@ -310,4 +322,12 @@ if settings.HAS_CELERY:
|
||||
except EventLock.LockTimeoutException:
|
||||
self.retry(exc=OrderError(error_messages['busy']))
|
||||
|
||||
@app.task(bind=True, max_retries=5, default_retry_delay=2)
|
||||
def cancel_order_task(self, order: int, user: int=None):
|
||||
try:
|
||||
return cancel_order(order, user)
|
||||
except EventLock.LockTimeoutException:
|
||||
self.retry(exc=OrderError(error_messages['busy']))
|
||||
|
||||
perform_order.task = perform_order_task
|
||||
cancel_order.task = cancel_order_task
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
Do you really want to cancel this order? You cannot revert this action.
|
||||
{% endblocktrans %}</p>
|
||||
|
||||
<form method="post" href="">
|
||||
<form method="post" action="{% eventurl request.event "presale:event.order.cancel.do" secret=order.secret order=order.code %}" data-asynctask>
|
||||
{% csrf_token %}
|
||||
<div class="row checkout-button-row">
|
||||
<div class="col-md-4">
|
||||
|
||||
@@ -21,6 +21,9 @@ event_patterns = [
|
||||
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/cancel$',
|
||||
pretix.presale.views.order.OrderCancel.as_view(),
|
||||
name='event.order.cancel'),
|
||||
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/cancel/do$',
|
||||
pretix.presale.views.order.OrderCancelDo.as_view(),
|
||||
name='event.order.cancel.do'),
|
||||
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/modify$',
|
||||
pretix.presale.views.order.OrderModify.as_view(),
|
||||
name='event.order.modify'),
|
||||
|
||||
@@ -6,7 +6,7 @@ from django.http import Http404
|
||||
from django.shortcuts import redirect
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ugettext_lazy as _, gettext
|
||||
from django.views.generic import TemplateView, View
|
||||
|
||||
from pretix.base.models import (
|
||||
@@ -14,7 +14,7 @@ from pretix.base.models import (
|
||||
)
|
||||
from pretix.base.models.orders import InvoiceAddress
|
||||
from pretix.base.services.invoices import invoice_pdf
|
||||
from pretix.base.services.orders import cancel_order
|
||||
from pretix.base.services.orders import cancel_order, OrderError
|
||||
from pretix.base.services.tickets import generate
|
||||
from pretix.base.signals import (
|
||||
register_payment_providers, register_ticket_outputs,
|
||||
@@ -22,6 +22,7 @@ from pretix.base.signals import (
|
||||
from pretix.multidomain.urlreverse import eventreverse
|
||||
from pretix.presale.forms.checkout import InvoiceAddressForm
|
||||
from pretix.presale.views import CartMixin, EventViewMixin
|
||||
from pretix.presale.views.async import AsyncAction
|
||||
from pretix.presale.views.questions import QuestionsViewMixin
|
||||
|
||||
|
||||
@@ -270,10 +271,6 @@ class OrderCancel(EventViewMixin, OrderDetailMixin, TemplateView):
|
||||
return redirect(self.get_order_url())
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
cancel_order(self.order)
|
||||
return redirect(self.get_order_url())
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
@@ -283,6 +280,36 @@ class OrderCancel(EventViewMixin, OrderDetailMixin, TemplateView):
|
||||
return ctx
|
||||
|
||||
|
||||
class OrderCancelDo(EventViewMixin, OrderDetailMixin, AsyncAction, View):
|
||||
task = cancel_order
|
||||
|
||||
def get_success_url(self, value):
|
||||
return self.get_order_url()
|
||||
|
||||
def get_error_url(self):
|
||||
return self.get_order_url()
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
if not self.order:
|
||||
raise Http404(_('Unknown order code or not authorized to access this order.'))
|
||||
return self.do(self.order)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
ctx['order'] = self.order
|
||||
return ctx
|
||||
|
||||
def get_success_message(self, value):
|
||||
return _('The order has been cancelled.')
|
||||
|
||||
def get_error_message(self, exception):
|
||||
if isinstance(exception, dict) and exception['exc_type'] == 'OrderError':
|
||||
return gettext(exception['exc_message'])
|
||||
elif isinstance(exception, OrderError):
|
||||
return str(exception)
|
||||
return super().get_error_message(exception)
|
||||
|
||||
|
||||
class OrderDownload(EventViewMixin, OrderDetailMixin, View):
|
||||
@cached_property
|
||||
def output(self):
|
||||
|
||||
Reference in New Issue
Block a user