Refs #654 -- API call to mark order as refunded

This commit is contained in:
Raphael Michel
2018-06-01 10:38:34 +02:00
parent 3030c300f2
commit 42c9e21d04
4 changed files with 85 additions and 5 deletions

View File

@@ -103,7 +103,7 @@ last_modified datetime Last modificati
.. versionchanged:: 1.16
The attributes ``order.last_modified`` as well as the corresponding filters to the resource have been added.
An endpoint for order creation has been added.
An endpoint for order creation as well as ``…/mark_refunded/`` has been added.
.. _order-position-resource:
@@ -720,6 +720,44 @@ Order endpoints
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
:statuscode 404: The requested order does not exist.
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/orders/(code)/mark_refunded/
Marks a paid order as refunded.
.. warning:: In the current implementation, this will **bypass** the payment provider, i.e. the money will **not** be
transferred back to the user automatically, the order will only be *marked* as refunded within pretix.
**Example request**:
.. sourcecode:: http
POST /api/v1/organizers/bigevents/events/sampleconf/orders/ABC12/mark_expired/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"code": "ABC12",
"status": "r",
...
}
:param organizer: The ``slug`` field of the organizer to modify
:param event: The ``slug`` field of the event to modify
:param code: The ``code`` field of the order to modify
:statuscode 200: no error
:statuscode 400: The order cannot be marked as expired since the current order status does not allow it.
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
:statuscode 404: The requested order does not exist.
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/orders/(code)/mark_expired/
Marks a unpaid order as expired.

View File

@@ -30,7 +30,7 @@ from pretix.base.services.invoices import (
from pretix.base.services.mail import SendMailException
from pretix.base.services.orders import (
OrderError, cancel_order, extend_order, mark_order_expired,
mark_order_paid,
mark_order_paid, mark_order_refunded,
)
from pretix.base.services.tickets import (
get_cachedticket_for_order, get_cachedticket_for_position,
@@ -193,7 +193,22 @@ class OrderViewSet(CreateModelMixin, viewsets.ReadOnlyModelViewSet):
)
return self.retrieve(request, [], **kwargs)
# TODO: Find a way to implement mark_refunded
@detail_route(methods=['POST'])
def mark_refunded(self, request, **kwargs):
order = self.get_object()
if order.status != Order.STATUS_PAID:
return Response(
{'detail': 'The order is not paid.'},
status=status.HTTP_400_BAD_REQUEST
)
mark_order_refunded(
order,
user=request.user if request.user.is_authenticated else None,
api_token=(request.auth if isinstance(request.auth, TeamAPIToken) else None),
)
return self.retrieve(request, [], **kwargs)
@detail_route(methods=['POST'])
def extend(self, request, **kwargs):

View File

@@ -214,7 +214,7 @@ def extend_order(order: Order, new_date: datetime, force: bool=False, user: User
@transaction.atomic
def mark_order_refunded(order, user=None):
def mark_order_refunded(order, user=None, api_token=None):
"""
Mark this order as refunded. This sets the payment status and returns the order object.
:param order: The order to change
@@ -228,7 +228,7 @@ def mark_order_refunded(order, user=None):
order.status = Order.STATUS_REFUNDED
order.save()
order.log_action('pretix.event.order.refunded', user=user)
order.log_action('pretix.event.order.refunded', user=user, api_token=api_token)
i = order.invoices.filter(is_cancellation=False).last()
if i:
generate_cancellation(i)

View File

@@ -599,6 +599,33 @@ def test_order_mark_canceled_paid(token_client, organizer, event, order):
assert order.status == Order.STATUS_PAID
@pytest.mark.django_db
def test_order_mark_paid_refunded(token_client, organizer, event, order):
order.status = Order.STATUS_PAID
order.save()
resp = token_client.post(
'/api/v1/organizers/{}/events/{}/orders/{}/mark_refunded/'.format(
organizer.slug, event.slug, order.code
)
)
assert resp.status_code == 200
assert resp.data['status'] == Order.STATUS_REFUNDED
@pytest.mark.django_db
def test_order_mark_canceled_refunded(token_client, organizer, event, order):
order.status = Order.STATUS_CANCELED
order.save()
resp = token_client.post(
'/api/v1/organizers/{}/events/{}/orders/{}/mark_refunded/'.format(
organizer.slug, event.slug, order.code
)
)
assert resp.status_code == 400
order.refresh_from_db()
assert order.status == Order.STATUS_CANCELED
@pytest.mark.django_db
def test_order_mark_paid_unpaid(token_client, organizer, event, order):
order.status = Order.STATUS_PAID