docs: add Delhivery B2C API specification and pickup scheduling architecture documentation
All checks were successful
Deploy Beta (NATIVE) / deploy (push) Successful in 48s
All checks were successful
Deploy Beta (NATIVE) / deploy (push) Successful in 48s
This commit is contained in:
parent
2df3902ab5
commit
0fd5cdecb0
2 changed files with 166 additions and 8 deletions
|
|
@ -280,7 +280,7 @@ Authorization: Token 7328f980a6eca01fedf37a63e39e44893481f856
|
|||
|
||||
Schedule a courier pickup at origin seller warehouse.
|
||||
|
||||
- **Endpoint**: `POST /fm/request/create/`
|
||||
- **Endpoint**: `POST /fm/request/new/`
|
||||
- **Headers**:
|
||||
- `Authorization: Token <API_TOKEN>`
|
||||
- `Content-Type: application/json`
|
||||
|
|
@ -289,21 +289,50 @@ Schedule a courier pickup at origin seller warehouse.
|
|||
```json
|
||||
{
|
||||
"pickup_time": "14:00:00",
|
||||
"pickup_date": "2026-10-11",
|
||||
"pickup_location": "StyleHub Retail Store",
|
||||
"expected_package_count": 5
|
||||
"pickup_date": "2026-10-13",
|
||||
"pickup_location": "SAM",
|
||||
"expected_package_count": 1
|
||||
}
|
||||
```
|
||||
|
||||
### Response Example (`200 OK`)
|
||||
### Response Example: Fresh Schedule (`201 Created` / `200 OK`)
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"pickup_id": 987654,
|
||||
"message": "Pickup request scheduled successfully for 2026-10-11 at 14:00:00"
|
||||
"status": true,
|
||||
"success": true,
|
||||
"pickup_id": 328094672,
|
||||
"data": {
|
||||
"pickup_id": 328094672,
|
||||
"message": "Pickup request successfully scheduled"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Response Example: Existing Active Pickup (`Code 669` / `pr_exist = true`)
|
||||
Delhivery enforces a rule that only **one active pickup request** can exist per warehouse per date/slot. If a request is already confirmed, Delhivery returns:
|
||||
```json
|
||||
{
|
||||
"status": true,
|
||||
"success": false,
|
||||
"pr_exist": true,
|
||||
"pickup_id": 328094672,
|
||||
"error": {
|
||||
"code": 669,
|
||||
"message": "A Pickup Request 328094672 for this Pickup Location Already Exist for 13 Oct in slot 14:00 - 18:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
> **Tradhox Handling**: Tradhox recognizes `pr_exist = true` / code `669` as a **confirmed pickup success**, captures `pickup_id = 328094672`, and links all ready orders at that warehouse to this slot.
|
||||
|
||||
### Response Example: Prepaid Balance Rejection (`400 Bad Request`)
|
||||
Delhivery One enforces a **minimum wallet balance floor of ₹500.00** before accepting any First Mile pickup dispatch:
|
||||
```json
|
||||
{
|
||||
"prepaid": "Client wallet balance is 454.32 which is less than 500.0"
|
||||
}
|
||||
```
|
||||
> **Action Required**: The merchant must recharge their Delhivery One wallet to exceed ₹500.00.
|
||||
|
||||
---
|
||||
|
||||
## ❌ 8. Order Edit / Cancellation API
|
||||
|
|
|
|||
129
documentation/pickup_scheduling_architecture.md
Normal file
129
documentation/pickup_scheduling_architecture.md
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
# Tradhox Multi-Carrier Pickup Scheduling Architecture & Logistics Guide
|
||||
|
||||
This document defines the complete architecture, carrier rules, multi-seller scenarios, multi-location logistics, and data audit structures for scheduling courier pickups across **Delhivery**, **Ekart Logistics**, and **Shadowfax**.
|
||||
|
||||
---
|
||||
|
||||
## 1. Carrier Capabilities & Pickup Workflow
|
||||
|
||||
| Carrier | Date Selection | Time Slot Selection | Minimum Wallet Balance | Pickup Mechanism |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| **Delhivery Logistics** | Yes (`YYYY-MM-DD`) | Yes (`10:00:00`, `14:00:00`, `17:00:00`) | **₹500.00 (Strict Floor)** | Live First-Mile API (`POST /fm/request/new/`). Dispatches executive to seller warehouse. |
|
||||
| **Ekart Logistics** | Yes (`YYYY-MM-DD`) | Daily Hub Sweep (Morning & Evening) | Positive freight balance | Sets preferred `dispatchDate` (`POST /data/shipment/dispatch-date`). Hub sweeps run twice daily. |
|
||||
| **Shadowfax Logistics** | SLA Scheduled | Automated Cut-Off Sweep | Positive freight balance | Automated route sweeps based on seller warehouse dispatch cutoff times (e.g. 2:00 PM / 4:00 PM). |
|
||||
|
||||
---
|
||||
|
||||
## 2. Delhivery One Special Rules & Error Handling
|
||||
|
||||
### 2.1. Strict Minimum Wallet Reserve (₹500.00 Floor)
|
||||
- Delhivery One enforces a **minimum wallet balance floor of ₹500.00** before accepting any First Mile pickup dispatch:
|
||||
```json
|
||||
HTTP 400 Bad Request
|
||||
{ "prepaid": "Client wallet balance is 454.32 which is less than 500.0" }
|
||||
```
|
||||
- **Rationale**: Delhivery holds a security reserve against potential weight discrepancies, volumetric adjustments, fuel surcharges, and RTO risk.
|
||||
- **Resolution**: The seller must top up their Delhivery One wallet (via `one.delhivery.com` $\rightarrow$ Finances $\rightarrow$ Wallet) so the balance crosses ₹500.00.
|
||||
|
||||
### 2.2. Single Pickup Request Per Warehouse / Slot (Code 669)
|
||||
- Delhivery allows only **ONE active Pickup Request per warehouse per date & slot**.
|
||||
- When a pickup is already booked for warehouse `SAM` on that date/slot and another request is sent, Delhivery returns:
|
||||
```json
|
||||
{
|
||||
"status": true,
|
||||
"success": false,
|
||||
"pr_exist": true,
|
||||
"pickup_id": 328094672,
|
||||
"error": {
|
||||
"code": 669,
|
||||
"message": "A Pickup Request 328094672 for this Pickup Location Already Exist for 13 Oct in slot 14:00 - 18:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
- **Tradhox Implementation**:
|
||||
- Code `669` is **not an error**; it confirms that Delhivery already has an active pickup assigned to that location.
|
||||
- The backend catches `pr_exist = true`, extracts `pickup_id = 328094672`, records it on the order, and presents a green confirmation banner to the seller.
|
||||
|
||||
---
|
||||
|
||||
## 3. Multi-Seller Scenarios
|
||||
|
||||
### Scenario A: Distinct Store / Workshop Names (Default)
|
||||
- Even if multiple sellers share the same neighborhood or pincode (`641301`):
|
||||
- **Seller 1**: Warehouse name = `SAM`
|
||||
- **Seller 2**: Warehouse name = `KUMAR-CRAFTS`
|
||||
- Delhivery evaluates pickup requests strictly by **Warehouse Name**, not pincode.
|
||||
- Seller 1 receives their own Pickup ID (`PUR-1`), and Seller 2 receives their own Pickup ID (`PUR-2`).
|
||||
- Delhivery dispatches independent field executive visits.
|
||||
|
||||
### Scenario B: Shared Artisan Cluster / Consolidation Hub
|
||||
- If multiple artisans bring their finished crafts to a shared guild center registered under warehouse `SAM`:
|
||||
- **Seller A** books a pickup for 13 Oct (2 PM – 5 PM) $\rightarrow$ creates Delhivery Pickup Request `#328094672`.
|
||||
- **Seller B** at the same hub later reschedules their order for the same date/slot.
|
||||
- Delhivery returns code `669` (`pr_exist = true`).
|
||||
- Tradhox automatically attaches Seller B's order to Pickup Request `#328094672`.
|
||||
- When the Delhivery pickup van arrives at hub `SAM`, the driver scans **all packages waiting at `SAM`** in one consolidated visit.
|
||||
|
||||
---
|
||||
|
||||
## 4. Multi-Order & Multi-Location Logistics
|
||||
|
||||
### Scenario 1: One Seller Warehouse $\rightarrow$ Multiple Delivery Destinations
|
||||
- **Origin**: Warehouse `SAM` (Coimbatore / Mettupalayam).
|
||||
- **Destinations**: Order 1 (Chennai), Order 2 (Bengaluru), Order 3 (Mumbai).
|
||||
- **Logistics Flow**:
|
||||
1. Only **1 Pickup Request** is created for warehouse `SAM`.
|
||||
2. Delhivery dispatches **one pickup executive** to `SAM`.
|
||||
3. The executive scans all packages into their handheld device and loads them into the local van.
|
||||
4. At the central Delhivery sorting hub, Delhivery's sorting automated line splits the packages onto their respective linehaul trucks and airport cargo containers according to destination sort codes (`CHE/GUU`, `BLR/SRA`, `BOM/AND`).
|
||||
|
||||
### Scenario 2: One Seller with Multiple Origin Workshops
|
||||
- **Workshop 1**: `SAM-Coimbatore` (Coimbatore).
|
||||
- **Workshop 2**: `SAM-Salem` (Salem).
|
||||
- **Logistics Flow**:
|
||||
1. Each workshop is registered as an independent pickup warehouse in Delhivery.
|
||||
2. Orders dispatched from Workshop 1 create a Coimbatore pickup assignment.
|
||||
3. Orders dispatched from Workshop 2 create a Salem pickup assignment.
|
||||
4. Both pickups execute concurrently without interference.
|
||||
|
||||
---
|
||||
|
||||
## 5. Database Schema & Audit Logging
|
||||
|
||||
### `seller_central_backend` (`Order` Model)
|
||||
```python
|
||||
class Order(models.Model):
|
||||
...
|
||||
eta = models.CharField(max_length=50, default='N/A')
|
||||
pickup_id = models.CharField(max_length=100, blank=True, null=True, help_text='Carrier Pickup Reference ID')
|
||||
pickup_payload = models.JSONField(default=dict, blank=True, null=True, help_text='Carrier Pickup Scheduling Response & Audit Details')
|
||||
```
|
||||
|
||||
### Stored `pickup_payload` JSON Structure
|
||||
```json
|
||||
{
|
||||
"latest_status": "success",
|
||||
"last_scheduled_at": "2026-10-12T13:39:37Z",
|
||||
"pickup_id": "328094672",
|
||||
"pickup_date": "2026-10-13",
|
||||
"pickup_time": "14:00:00",
|
||||
"carrier": "Delhivery Logistics",
|
||||
"history": [
|
||||
{
|
||||
"scheduled_at": "2026-10-12T13:39:37Z",
|
||||
"status": "success",
|
||||
"pickup_id": "328094672",
|
||||
"pickup_date": "2026-10-13",
|
||||
"pickup_time": "14:00:00",
|
||||
"carrier": "Delhivery Logistics",
|
||||
"message": "Pickup request #328094672 is already confirmed with Delhivery for 2026-10-13",
|
||||
"raw_response": { ... }
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Microservice Audit Tables (`shippingservice`)
|
||||
- **Delhivery**: `DelhiveryActivityLog` (records every HTTP status, endpoint, request headers/payload, and response).
|
||||
- **Ekart**: `EkartActivityLog` (records all token, dispatch-date, and tracking calls).
|
||||
- **Shadowfax**: `ActivityLog` (records forward/reverse order dispatch and tracking calls).
|
||||
Loading…
Reference in a new issue