feat: add shipping client api, views, and pickup scheduling architecture docs
All checks were successful
Deploy Beta (NATIVE) / deploy (push) Successful in 39s

This commit is contained in:
vickytechkey 2026-10-13 19:23:22 +05:30
parent c3cb4b3637
commit d2b1a29fa3
3 changed files with 137 additions and 0 deletions

View file

@ -1004,6 +1004,67 @@ class ShippingServiceClient:
'time_slot_label': 'Standard Daily Hub Sweep (Morning & Evening)' if is_ekart else ('Automated Cutoff Sweep' if not is_delhivery else '') 'time_slot_label': 'Standard Daily Hub Sweep (Morning & Evening)' if is_ekart else ('Automated Cutoff Sweep' if not is_delhivery else '')
} }
def get_pickup_schedule(self, awb_number):
"""
Check courier pickup schedule (date, time, slot, pickup_id, location, carrier, status)
for a given tracking / AWB number via shipping microservice.
"""
trk = str(awb_number or '').strip()
if not trk or trk in ('Pending', 'N/A'):
return {'status': 'error', 'message': 'Valid tracking ID / AWB number is required'}
target_urls = [
f"{self.base_url}/api/v1/carrier/pickup-schedule/?tracking_id={trk}",
f"http://127.0.0.1:8086/api/v1/carrier/pickup-schedule/?tracking_id={trk}",
f"http://localhost:8086/api/v1/carrier/pickup-schedule/?tracking_id={trk}",
f"https://beta-shipping.tradhox.com/api/v1/carrier/pickup-schedule/?tracking_id={trk}"
]
for u in target_urls:
try:
res = requests.get(u, headers=self._get_headers(), timeout=5, verify=False)
if res.status_code == 200:
return res.json()
except Exception:
continue
# Direct database / local order fallback
try:
from .models import Order
ord_obj = Order.objects.filter(tracking=trk).first()
if not ord_obj and trk.startswith('TRDX-ORD-'):
ord_obj = Order.objects.filter(order_id=trk).first()
if ord_obj:
p_date = None
p_time = None
if ord_obj.eta and 'Pickup:' in str(ord_obj.eta):
import re
m_d = re.search(r'Pickup:\s*([\d-]+)', str(ord_obj.eta))
m_t = re.search(r'\(([\d:]+)\)', str(ord_obj.eta))
if m_d: p_date = m_d.group(1)
if m_t: p_time = m_t.group(1)
p_slot = ord_obj.eta.replace('Pickup:', '').strip() if ord_obj.eta else 'Afternoon Slot'
return {
'status': 'success',
'tracking_id': trk,
'order_id': ord_obj.order_id,
'carrier': ord_obj.carrier,
'carrier_display': ord_obj.carrier,
'pickup_scheduled': bool(ord_obj.pickup_id),
'pickup_id': ord_obj.pickup_id,
'pickup_date': p_date or time.strftime('%Y-%m-%d'),
'pickup_time': p_time or '14:00:00',
'pickup_slot': p_slot,
'status_display': f"Pickup Scheduled with {ord_obj.carrier} (ID: #{ord_obj.pickup_id})" if ord_obj.pickup_id else f"Ready for Pickup with {ord_obj.carrier}"
}
except Exception as e:
logger.warning(f"Order fallback in get_pickup_schedule: {e}")
return {
'status': 'error',
'message': f"No pickup schedule found for tracking {trk}"
}
def schedule_pickup(self, order, pickup_date=None, pickup_time=None, package_count=1, notes=None, supplier_profile=None): def schedule_pickup(self, order, pickup_date=None, pickup_time=None, package_count=1, notes=None, supplier_profile=None):
""" """
Schedule / reschedule courier pickup for an order with assigned carrier. Schedule / reschedule courier pickup for an order with assigned carrier.

View file

@ -1750,6 +1750,12 @@ class OrderViewSet(viewsets.ModelViewSet):
'order': OrderSerializer(order).data 'order': OrderSerializer(order).data
}) })
@drf_action(detail=True, methods=['get'])
def pickup_schedule(self, request, pk=None):
order = self.get_object()
awb = request.query_params.get('awb') or request.query_params.get('tracking_id') or order.tracking
res = shipping_client.get_pickup_schedule(awb)
return Response(res)
@drf_action(detail=True, methods=['get']) @drf_action(detail=True, methods=['get'])
def print_label(self, request, pk=None): def print_label(self, request, pk=None):

View file

@ -153,3 +153,73 @@ class Order(models.Model):
- **Tradhox User Experience**: - **Tradhox User Experience**:
- In Tradhox Supplier Central, once an order is manifested and scheduled, Tradhox surfaces the active **Pickup Request ID (`PR #328095871`)** and **`PICKUP SCHEDULED`** badge. - In Tradhox Supplier Central, once an order is manifested and scheduled, Tradhox surfaces the active **Pickup Request ID (`PR #328095871`)** and **`PICKUP SCHEDULED`** badge.
- Merchants do not need to manually click "Add to Pickup" inside the Delhivery One portal; the courier executive will collect all ready packages for warehouse `SAM`. - Merchants do not need to manually click "Add to Pickup" inside the Delhivery One portal; the courier executive will collect all ready packages for warehouse `SAM`.
---
## 7. Check Pickup Schedule by Tracking ID (AWB) Specification
### 7.1. REST Endpoints
Clients can query the pickup schedule using either endpoint:
- **Primary Route**:
`GET /api/v1/carrier/pickup-schedule/?tracking_id=<AWB>`
- **Unified Alias**:
`GET /api/v1/carrier/schedule-pickup/?tracking_id=<AWB>`
- **POST Route**:
`POST /api/v1/carrier/pickup-schedule/` with JSON `{"tracking_id": "<AWB>"}`
#### Supported Query Parameters
- `tracking_id` / `awb` / `tracking` / `waybill`: The carrier waybill or client order ID (e.g. `69873010000232`).
### 7.2. Response Schema
```json
{
"status": "success",
"tracking_id": "69873010000232",
"order_id": "32-18",
"carrier": "DELHIVERY",
"carrier_display": "Delhivery Logistics",
"pickup_scheduled": true,
"pickup_id": "328095871",
"pickup_date": "2026-10-14",
"pickup_time": "10:00:00",
"pickup_slot": "Morning Slot (10:00 AM – 1:00 PM)",
"pickup_location": "SAM",
"shipment_status": "Manifested",
"pickup_status": "CONFIRMED",
"status_display": "Pickup Confirmed with Delhivery Logistics (PR #328095871) for 2026-10-14 (Morning Slot (10:00 AM – 1:00 PM))",
"destination": {
"city": "Kanchipuram",
"pincode": 600059
},
"consignee": {
"name": "Vignesh Krishnasamy",
"city": "Kanchipuram",
"state": "Tamil Nadu",
"pincode": 600059
},
"scans": [
{
"scan": "Manifested",
"instructions": "Manifest uploaded",
"location": "Mettupalayam_IshwaryNgr_D (Tamil Nadu)",
"timestamp": "2026-10-12T19:04:35.275"
}
],
"details": {
"expected_package_count": 1,
"manifest_date": "2026-10-12T19:04:35.245",
"picked_up_date": null
}
}
```
### 7.3. Resolution Hierarchy
1. **`shipping_pickupschedule` Table**: Checks if a local record exists.
2. **Live Carrier Tracking API**:
- For **Delhivery**, calls `/api/v1/packages/json/?waybill={trk}`, extracting origin warehouse, consignee address, and shipment status.
- Cross-checks with active warehouse pickup requests.
3. **Cross-Database Order Lookup**:
- Queries `api_order` in `customerprofile_beta` to correlate `pickup_id` and ETA slot.
4. **Auto-Caching**: Updates the `PickupSchedule` model so subsequent lookups are instant.