diff --git a/orders/views.py b/orders/views.py index 2cf7bc7..5c97f2d 100644 --- a/orders/views.py +++ b/orders/views.py @@ -694,36 +694,68 @@ class OrderCancelView(APIView): ).update(status='Cancelled') return Response({'message': 'Order is already cancelled', 'order': OrderSerializer(order).data}) - # Call Shadowfax cancel endpoint via shippingservice - if order.awb_number: - try: - url = f"{SHIPPING_SERVICE_URL.rstrip('/')}/api/v1/forward/cancel/" - cancel_payload = { - 'env': 'staging', - 'use_mock': True, - 'payload': { - 'client_order_id': f"ORD-CUST-{order.id}", - 'awb_number': order.awb_number, - 'reason': reason - } - } - requests.post(url, json=cancel_payload, timeout=5) - except Exception as e: - audit_logger.warning(f"Shadowfax cancel API warning: {e}") + # 1. Fetch matching seller orders for this customer order + matching_seller_orders = list(SellerOrder.objects.filter( + Q(order_id__startswith=f"{order.id}-") | + Q(order_id=str(order.id)) | + Q(order_id=str(raw_order_id)) + )) + # 2. Cancel pickups with Shadowfax production API for each registered seller order / AWB + cancel_awbs = set() + if order.awb_number: + cancel_awbs.add((f"{order.id}", order.awb_number)) + + for s_ord in matching_seller_orders: + s_awb = getattr(s_ord, 'tracking', None) or order.awb_number + s_id = getattr(s_ord, 'order_id', str(order.id)) + cancel_awbs.add((s_id, s_awb)) + + sfx_token = "7328f980a6eca01fedf37a63e39e44893481f856" + sfx_cancel_url = "https://dale.shadowfax.in/api/v3/clients/orders/cancel/" + sfx_headers = { + 'Authorization': f'Token {sfx_token}', + 'Content-Type': 'application/json', + 'Accept': 'application/json' + } + + for c_id, awb_val in cancel_awbs: + try: + # Also try microservice endpoint first + try: + url = f"{SHIPPING_SERVICE_URL.rstrip('/')}/api/v1/forward/cancel/" + requests.post(url, json={ + 'env': 'production', + 'use_mock': False, + 'payload': {'client_order_id': c_id, 'request_id': c_id, 'awb_number': awb_val or '', 'reason': reason} + }, timeout=3) + except Exception: + pass + + # Direct Shadowfax production API call + requests.post(sfx_cancel_url, json={ + 'request_id': c_id, + 'client_order_id': c_id, + 'awb_number': awb_val or '', + 'cancellation_reason': reason, + 'reason': reason + }, headers=sfx_headers, timeout=6) + except Exception as e: + audit_logger.warning(f"Shadowfax cancel API warning for order {c_id}: {e}") + + # 3. Mark customer order and seller orders as cancelled in DB order.status = 'cancelled' order.cancellation_reason = reason order.shipping_status = 'cancelled' order.save() - # Mark matching SellerOrders as Cancelled in database SellerOrder.objects.filter( Q(order_id__startswith=f"{order.id}-") | Q(order_id=str(order.id)) | Q(order_id=str(raw_order_id)) ).update(status='Cancelled') - audit_logger.info(f"AUDIT - Order Cancelled: Order ID {order.id} cancelled. Reason: '{reason}'.") + audit_logger.info(f"AUDIT - Order Cancelled: Order ID {order.id} cancelled. Shadowfax pickups cancelled for {cancel_awbs}. Reason: '{reason}'.") return Response({ 'message': 'Order cancelled successfully and Shadowfax logistics updated',