Use "cancel" method instead of "refund" for free orders (#743)

* Use "cancel" method instead of "refund" for free orders

* Adjust API
This commit is contained in:
Raphael Michel
2018-01-15 21:46:16 +01:00
committed by GitHub
parent db24bd4d78
commit f8cc332ed7
8 changed files with 30 additions and 9 deletions

View File

@@ -109,9 +109,9 @@ class OrderViewSet(viewsets.ReadOnlyModelViewSet):
send_mail = request.data.get('send_email', True)
order = self.get_object()
if order.status != Order.STATUS_PENDING:
if not order.cancel_allowed():
return Response(
{'detail': 'The order is not pending.'},
{'detail': 'The order is not allowed to be canceled.'},
status=status.HTTP_400_BAD_REQUEST
)

View File

@@ -213,6 +213,12 @@ class Order(LoggedModel):
def net_total(self):
return self.total - self.tax_total
def cancel_allowed(self):
return (
self.status == Order.STATUS_PENDING
or (self.status == Order.STATUS_PAID and self.total == Decimal('0.00'))
)
@staticmethod
def normalize_code(code):
tr = str.maketrans({
@@ -272,7 +278,7 @@ class Order(LoggedModel):
"""
positions = self.positions.all().select_related('item')
cancelable = all([op.item.allow_cancel for op in positions])
return self.event.settings.cancel_allow_user and cancelable
return self.cancel_allowed() and self.event.settings.cancel_allow_user and cancelable
@property
def is_expired_by_time(self):

View File

@@ -245,7 +245,7 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None):
if isinstance(api_token, int):
api_token = TeamAPIToken.objects.get(pk=api_token)
with order.event.lock():
if order.status != Order.STATUS_PENDING:
if not order.cancel_allowed():
raise OrderError(_('You cannot cancel this order.'))
order.status = Order.STATUS_CANCELED
order.save()

View File

@@ -29,7 +29,7 @@
{% trans "Extend payment term" %}
</a>
{% endif %}
{% if order.status == 'n' %}
{% if order.cancel_allowed %}
<a href="{% url "control:event.order.transition" event=request.event.slug organizer=request.event.organizer.slug code=order.code %}?status=c" class="btn btn-default">
{% trans "Cancel order" %}
</a>

View File

@@ -219,7 +219,7 @@ class OrderTransition(OrderView):
messages.warning(self.request, _('The order has been marked as paid, but we were unable to send a confirmation mail.'))
else:
messages.success(self.request, _('The order has been marked as paid.'))
elif self.order.status == Order.STATUS_PENDING and to == 'c':
elif self.order.cancel_allowed() and to == 'c':
cancel_order(self.order, user=self.request.user, send_mail=self.request.POST.get("send_email") == "on")
messages.success(self.request, _('The order has been canceled.'))
elif self.order.status == Order.STATUS_PAID and to == 'n':
@@ -241,7 +241,7 @@ class OrderTransition(OrderView):
def get(self, *args, **kwargs):
to = self.request.GET.get('status', '')
if self.order.status == Order.STATUS_PENDING and to == 'c':
if self.order.cancel_allowed() and to == 'c':
return render(self.request, 'pretixcontrol/order/cancel.html', {
'order': self.order,
})

View File

@@ -202,7 +202,7 @@
{% endif %}
<div class="clearfix"></div>
</div>
{% if order.status == "n" and order.can_user_cancel %}
{% if order.can_user_cancel %}
<div class="row">
<div class="col-md-12 text-right">
<p>

View File

@@ -498,7 +498,7 @@ class OrderCancel(EventViewMixin, OrderDetailMixin, TemplateView):
self.kwargs = kwargs
if not self.order:
raise Http404(_('Unknown order code or not authorized to access this order.'))
if self.order.status != Order.STATUS_PENDING or not self.order.can_user_cancel:
if not self.order.can_user_cancel:
messages.error(request, _('You cannot cancel this order.'))
return redirect(self.get_order_url())
return super().dispatch(request, *args, **kwargs)

View File

@@ -222,6 +222,21 @@ def test_order_transition(client, env, process):
assert o.status == process[0]
@pytest.mark.django_db
def test_order_cancel_free(client, env):
o = Order.objects.get(id=env[2].id)
o.status = Order.STATUS_PAID
o.total = Decimal('0.00')
o.save()
client.login(email='dummy@dummy.dummy', password='dummy')
client.get('/control/event/dummy/dummy/orders/FOO/transition?status=c')
client.post('/control/event/dummy/dummy/orders/FOO/transition', {
'status': 'c'
})
o = Order.objects.get(id=env[2].id)
assert o.status == Order.STATUS_CANCELED
@pytest.mark.django_db
def test_order_invoice_create_forbidden(client, env):
client.login(email='dummy@dummy.dummy', password='dummy')