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 return False, None
@classmethod @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 # Do not change order status if an is in order
# any of these status # any of these status
do_not_cancel = [ do_not_cancel = [

View File

@ -245,6 +245,11 @@ class OrderViewSchema:
- `17` - Maker lost dispute - `17` - Maker lost dispute
- `18` - Taker 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 Note that there are penalties involved for cancelling a order
mid-trade so use this action carefully: mid-trade so use this action carefully:

View File

@ -628,6 +628,13 @@ class UpdateOrderSerializer(serializers.Serializer):
mining_fee_rate = serializers.DecimalField( mining_fee_rate = serializers.DecimalField(
max_digits=6, decimal_places=3, allow_null=True, required=False, default=None 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): class ClaimRewardSerializer(serializers.Serializer):

View File

@ -511,6 +511,7 @@ class OrderView(viewsets.ViewSet):
mining_fee_rate = serializer.data.get("mining_fee_rate") mining_fee_rate = serializer.data.get("mining_fee_rate")
statement = serializer.data.get("statement") statement = serializer.data.get("statement")
rating = serializer.data.get("rating") rating = serializer.data.get("rating")
current_status_int = serializer.data.get("current_status", None)
# 1) If action is take, it is a taker request! # 1) If action is take, it is a taker request!
if action == "take": if action == "take":
@ -586,7 +587,19 @@ class OrderView(viewsets.ViewSet):
# 3) If action is cancel # 3) If action is cancel
elif action == "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: if not valid:
return Response(context, status.HTTP_400_BAD_REQUEST) return Response(context, status.HTTP_400_BAD_REQUEST)

View File

@ -469,6 +469,11 @@ paths:
- `17` - Maker lost dispute - `17` - Maker lost dispute
- `18` - Taker 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 Note that there are penalties involved for cancelling a order
mid-trade so use this action carefully: mid-trade so use this action carefully:
@ -1950,6 +1955,12 @@ components:
format: decimal format: decimal
pattern: ^-?\d{0,3}(?:\.\d{0,3})?$ pattern: ^-?\d{0,3}(?:\.\d{0,3})?$
nullable: true nullable: true
current_status:
type: integer
maximum: 18
minimum: 0
nullable: true
description: Current order status for the client
required: required:
- action - action
Version: Version:

View File

@ -659,7 +659,19 @@ class TradeTest(BaseAPITestCase):
""" """
trade = Trade(self.client) trade = Trade(self.client)
trade.publish_order() 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() data = trade.response.json()

View File

@ -112,11 +112,13 @@ class Trade:
self.response = self.client.get(path + params, **headers) self.response = self.client.get(path + params, **headers)
@patch("api.tasks.send_notification.delay", send_notification) @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") path = reverse("order")
params = f"?order_id={self.order_id}" params = f"?order_id={self.order_id}"
headers = self.get_robot_auth(robot_index) headers = self.get_robot_auth(robot_index)
body = {"action": "cancel"} 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) self.response = self.client.post(path + params, body, **headers)
def pause_order(self, robot_index=1): def pause_order(self, robot_index=1):