add new param current_status to /api/order cancel

This commit is contained in:
jerryfletcher21
2024-06-15 04:07:18 +02:00
parent daf9ce4d3f
commit 6647e164c3
7 changed files with 64 additions and 4 deletions

View File

@ -991,7 +991,17 @@ class Logics:
return False, None
@classmethod
def cancel_order(cls, order, user, state=None):
def cancel_order(cls, order, user, current_status=None):
# If current status is specified, do no cancel the order
# if it is not the correct one.
# This prevents the client from cancelling an order that
# recently changed status.
if current_status is not None:
if order.status != current_status:
return False, {
"bad_request": f"Wrong status, current one is {order.status}"
}
# Do not change order status if an is in order
# any of these status
do_not_cancel = [

View File

@ -245,6 +245,11 @@ class OrderViewSchema:
- `17` - Maker lost dispute
- `18` - Taker lost dispute
The client can specify `current_status` to make sure that the
order is cancelled just if it is in right status.
If the order is not in the specified status, the server will
return an error without cancelling the trade.
Note that there are penalties involved for cancelling a order
mid-trade so use this action carefully:

View File

@ -628,6 +628,13 @@ class UpdateOrderSerializer(serializers.Serializer):
mining_fee_rate = serializers.DecimalField(
max_digits=6, decimal_places=3, allow_null=True, required=False, default=None
)
current_status = serializers.IntegerField(
min_value=Decimal(0),
max_value=18,
allow_null=True,
required=False,
help_text="Current order status for the client",
)
class ClaimRewardSerializer(serializers.Serializer):

View File

@ -511,6 +511,7 @@ class OrderView(viewsets.ViewSet):
mining_fee_rate = serializer.data.get("mining_fee_rate")
statement = serializer.data.get("statement")
rating = serializer.data.get("rating")
current_status_int = serializer.data.get("current_status", None)
# 1) If action is take, it is a taker request!
if action == "take":
@ -586,7 +587,19 @@ class OrderView(viewsets.ViewSet):
# 3) If action is cancel
elif action == "cancel":
valid, context = Logics.cancel_order(order, request.user)
if current_status_int is None:
current_status = None
else:
if current_status_int < 0 or current_status_int >= len(Order.Status):
return Response(
{"bad_request": "current_status is not in the correct range"},
status.HTTP_400_BAD_REQUEST
)
current_status = Order.Status(current_status_int)
valid, context = Logics.cancel_order(
order, request.user, current_status=current_status
)
if not valid:
return Response(context, status.HTTP_400_BAD_REQUEST)

View File

@ -469,6 +469,11 @@ paths:
- `17` - Maker lost dispute
- `18` - Taker lost dispute
The client can specify `current_status` to make sure that the
order is cancelled just if it is in right status.
If the order is not in the specified status, the server will
return an error without cancelling the trade.
Note that there are penalties involved for cancelling a order
mid-trade so use this action carefully:
@ -1950,6 +1955,12 @@ components:
format: decimal
pattern: ^-?\d{0,3}(?:\.\d{0,3})?$
nullable: true
current_status:
type: integer
maximum: 18
minimum: 0
nullable: true
description: Current order status for the client
required:
- action
Version:

View File

@ -659,7 +659,19 @@ class TradeTest(BaseAPITestCase):
"""
trade = Trade(self.client)
trade.publish_order()
trade.cancel_order()
trade.cancel_order(current_status_int=6)
data = trade.response.json()
self.assertEqual(trade.response.status_code, 400)
self.assertResponse(trade.response)
self.assertEqual(
data["bad_request"], "Wrong status, current one is 1"
)
trade.cancel_order(current_status_int=1)
data = trade.response.json()

View File

@ -112,11 +112,13 @@ class Trade:
self.response = self.client.get(path + params, **headers)
@patch("api.tasks.send_notification.delay", send_notification)
def cancel_order(self, robot_index=1):
def cancel_order(self, robot_index=1, current_status_int=None):
path = reverse("order")
params = f"?order_id={self.order_id}"
headers = self.get_robot_auth(robot_index)
body = {"action": "cancel"}
if current_status_int is not None:
body.update({"current_status": current_status_int})
self.response = self.client.post(path + params, body, **headers)
def pause_order(self, robot_index=1):