# API Documentation - Driver Order Management

## Mục lục
1. [Tìm kiếm lịch sử đơn hàng](#1-tìm-kiếm-lịch-sử-đơn-hàng)
2. [Tìm kiếm đơn hàng đang hoạt động](#2-tìm-kiếm-đơn-hàng-đang-hoạt-động)
3. [Sắp xếp thứ tự hiển thị đơn hàng](#3-sắp-xếp-thứ-tự-hiển-thị-đơn-hàng)

---

## 1. Tìm kiếm lịch sử đơn hàng
Tìm kiếm danh sách các đơn hàng mà lái xe đã **lấy hàng** (`PickedupById`) hoặc đã **giao hàng** (`DeliveredById`).

### Thông tin cơ bản
- **Endpoint**: `POST /api/DriverOrder/SearchOrders`
- **Authorization**: `Bearer [Token]` (Quyền: `DriverApp.SearchOrders`)

### Request Body (JSON)
Sử dụng cấu trúc `SmartTableParam` để tìm kiếm, phân trang và sắp xếp.

```json
{
  "Pagination": {
    "PageIndex": 1,
    "PageSize": 15
  },
  "Search": {
    "PredicateObject": {
      "Keyword": "LADA123456",
      "DateFrom": "2026-03-01T00:00:00+07:00",
      "DateTo": "2026-03-08T23:59:59+07:00",
      "DateFilterType": "pickup"
    }
  }
}
```

**Request Parameters Detail:**
- `Pagination`: Thông tin phân trang.
- `Search.PredicateObject.Keyword`: (Optional) Tìm kiếm theo mã vận đơn, số điện thoại người gửi hoặc người nhận.
- `Search.PredicateObject.DateFrom`: (Optional) Thời gian bắt đầu lọc (DateTimeOffset).
- `Search.PredicateObject.DateTo`: (Optional) Thời gian kết thúc lọc (DateTimeOffset).
- `Search.PredicateObject.DateFilterType`: (Optional) Loại thời gian lọc. Giá trị: `"pickup"` (thời gian lấy hàng, mặc định) hoặc `"delivery"` (thời gian giao hàng).
- `Sort`: Tuỳ thuộc vào bộ lọc thời gian:
  - Nếu `DateFilterType` = `"pickup"`: Sắp xếp theo thời gian lấy hàng (`PickupTime`) giảm dần (mới nhất trước).
  - Nếu `DateFilterType` = `"delivery"`: Sắp xếp theo thời gian giao hàng (`DeliveryDate`) giảm dần (mới nhất trước).
  - Nếu không lọc theo khoảng thời gian: Mặc định sắp xếp theo thời gian tạo đơn (`CreatedTime`) giảm dần.

### Response
Trả về `SmartTableResult` chứa danh sách `DriverOrderHistoryItem`.

```json
{
  "Items": [
    {
      "Id": 1001,
      "Code": "LADA240501.0001",
      "PickedupByUserName": "driver01",
      "PickedupByFullName": "Nguyễn Tài Xế",
      "DeliveredByUserName": "driver02",
      "DeliveredByFullName": "Trần Giao Hàng",
      "SenderName": "Nguyễn Văn A",
      "SenderPhone": "0912345678",
      "SenderAddress": "Số 1 Đại Cồ Việt, Hà Nội",
      "ReceiverName": "Trần Thị B",
      "ReceiverPhone": "0987654321",
      "ReceiverAddress": "123 Lê Lợi, Q1, TP.HCM",
      "PackageContent": "Quần áo, linh kiện",
      "TotalPackages": 2,
      "TotalWeight": 5.5,
      "PickupTime": "2024-05-01T10:30:00+07:00",
      "DeliveryDate": "2024-05-02T15:00:00+07:00",
      "TotalFee": 50000,
      "CollectAmount": 200000,
      "PayFeeType": 1,
      "PayFeeTypeStr": "Người gửi trả",
      "OrderStatusStr": "Mới",
      "OrderPhysicalStatusStr": "Đang lấy hàng",
      "MediaUrls": [
        "https://cdn.ladaer.vn/media/orders/2026/03/IMG_123.jpg"
      ]
    }
  ],
  "TotalRecord": 1,
  "NumberOfPages": 1
}
```

> [!NOTE]
> **Logic lọc đơn hàng**
> - API SearchOrders trả về các đơn hàng mà lái xe đã thực sự lấy hàng (`PickedupById`) hoặc giao hàng (`DeliveredById`), không bao gồm đơn chỉ được phân công.
> - Khi `DateFilterType = "pickup"`: chỉ trả về đơn do tài xế này lấy hàng (`PickedupById == userId`).
> - Khi `DateFilterType = "delivery"`: chỉ trả về đơn do tài xế này giao hàng (`DeliveredById == userId`).

---

## 2. Tìm kiếm đơn hàng đang hoạt động
Tìm kiếm danh sách các đơn hàng có trạng thái đang hoạt động (đang lấy, lấy thất bại, đang giao, giao thất bại) và được phân công cho lái xe hiện tại.

### Thông tin cơ bản
- **Endpoint**: `POST /api/DriverOrder/SearchActiveOrders`
- **Authorization**: `Bearer [Token]` (Quyền: `DriverApp.SearchActiveOrders`)

### Request Body (JSON)
Sử dụng cấu trúc `SmartTableParam` để tìm kiếm, phân trang và sắp xếp.

```json
{
  "Pagination": {
    "PageIndex": 1,
    "PageSize": 15
  },
  "Search": {
    "PredicateObject": {
      "Keyword": "LADA123456"
    }
  },
  "Sort": {
    "Predicate": "DisplayOrder",
    "Reverse": false
  }
}
```

**Request Parameters Detail:**
- `Pagination`: Thông tin phân trang.
- `Search.PredicateObject.Keyword`: (Optional) Tìm kiếm theo mã vận đơn.
- `Sort`: Thông tin sắp xếp. Mặc định hệ thống sẽ sắp xếp theo `DisplayOrder` tăng dần và `CreatedTime` giảm dần nếu không truyền.

### Response
Trả về `SmartTableResult` chứa danh sách `OpsOrderItem`.

```json
{
  "Items": [
    {
      "Code": "LADA240501.0001",
      "Note": "Giao hàng giờ hành chính",
      "SaleId": 12,
      "SaleUserName": "admin",
      "RouteName": "Hà Nội - Hải Phòng",
      "OrderOps": {
        "Status": 1,
        "StatusStr": "Mới",
        "PhysicalStatus": 2,
        "PhysicalStatusStr": "Đang lấy hàng",
        "PicId": 105,
        "PicUserName": "driver01",
        "DisplayOrder": 1
      },
      "OrderFin": {
        "TotalFee": 50000,
        "CollectAmount": 200000,
        "PayFeeType": 1
      },
      "Addresses": [
        {
          "FullName": "Nguyễn Văn A",
          "PhoneNumber": "0912345678",
          "FullAddress": "Số 1 Đại Cồ Việt, Bách Khoa, Hai Bà Trưng, Hà Nội",
          "AddressType": 1
        }
      ],
      "Packages": [
        {
          "Weight": 5.5,
          "Length": 20,
          "Width": 15,
          "Height": 10
        }
      ],
      "Id": 1001,
      "CreatedTime": "2024-05-01T08:00:00Z",
      "PickupTime": "2024-05-01T10:30:00Z",
      "DeliveryDate": null
    }
  ],
  "TotalRecord": 1,
  "NumberOfPages": 1
}
```

---

## 3. Sắp xếp thứ tự hiển thị đơn hàng
Cho phép lái xe tự sắp xếp thứ tự ưu tiên xử lý các đơn hàng trên ứng dụng.

### Thông tin cơ bản
- **Endpoint**: `POST /api/DriverOrder/ReorderOrders`
- **Authorization**: `Bearer [Token]` (Quyền: `DriverApp.ReorderOrders`)

### Request Body (JSON)
Gửi danh sách các đơn hàng (`OrderId`) kèm theo thứ tự hiển thị mong muốn (`DisplayOrder`).

```json
{
  "Items": [
    {
      "OrderId": 1001,
      "DisplayOrder": 1
    },
    {
      "OrderId": 1002,
      "DisplayOrder": 2
    }
  ]
}
```

**Request Parameters Detail:**
- `Items`: Danh sách các item cần sắp xếp.
- `OrderId`: ID của bản ghi `OrderOps` tương ứng.
- `DisplayOrder`: Giá trị thứ tự (Số nguyên). Số nhỏ hơn sẽ hiển thị trước.

### Response
Trả về kết quả thực hiện.

```json
{
  "Result": 1,
  "Message": "Thành công"
}
```

> [!NOTE]
> **Logic Lọc Đơn Hoạt Động**
> API SearchActiveOrders tự động lọc các đơn hàng thuộc 9 tổ hợp trạng thái bao gồm:
> - Đang lấy hàng (New + AssignedPickup/OnPicking)
> - Lấy thất bại (New + PickFailed, PickupFail + OnPicking/PickFailed)
> - Đang giao hàng (Received + OutboundForDelivery/OnDelivery)
> - Giao thất bại (DeliveryFail + OutboundForDelivery/OnDelivery)

> [!IMPORTANT]
> **Thứ tự hiển thị**
> Nếu người dùng không chỉ định sắp xếp qua API Search, hệ thống ưu tiên hiển thị theo `DisplayOrder` (thứ tự đã lưu qua API ReorderOrders) trước, sau đó mới đến `CreatedTime` giảm dần.

