# API Documentation - Quản lý lý do thất bại (OrderFailReason)

## Mục lục
1. [Tìm kiếm danh sách lý do thất bại](#1-tìm-kiếm-danh-sách-lý-do-thất-bại)
2. [Lấy chi tiết lý do thất bại](#2-lấy-chi-tiết-lý-do-thất-bại)
3. [Thêm mới hoặc cập nhật lý do thất bại](#3-thêm-mới-hoặc-cập-nhật-lý-do-thất-bại)
4. [Xóa lý do thất bại](#4-xóa-lý-do-thất-bại)

---

## 1. Tìm kiếm danh sách lý do thất bại

### 1.1. Tìm kiếm và phân trang (Admin)

**Endpoint**: `POST /api/OrderFailReason/Search`  
**Authorization**: `OrderFailReason.Search`

Mô tả: API dùng để tìm kiếm, lọc và phân trang cấu hình lý do lấy/giao hàng thất bại.

**Request Body:**
```json
{
  "Pagination": {
    "PageIndex": 1,
    "PageSize": 15
  },
  "Search": {
    "PredicateObject": {
      "Keyword": "không nghe máy",
      "Type": 1,
      "IsActive": true
    }
  },
  "Sort": {
    "Predicate": "SortOrder",
    "Reverse": false
  }
}
```

**Request Parameters:**
- `Keyword` (string): Tìm kiếm theo tên hoặc mô tả lý do.
- `Type` (int): 1 = Lấy hàng (Pickup), 2 = Giao hàng (Delivery), 3 = Cả hai (Both).
- `IsActive` (bool): Lọc theo trạng thái hoạt động.

**Response:**
```json
{
  "Result": 1,
  "Message": "Thành công",
  "Data": {
    "TotalRecord": 1,
    "DataCollection": [
      {
        "Id": 1,
        "Name": "Khách không nghe máy",
        "Description": "Gọi 3 cuộc nhưng không nghe",
        "Type": 1,
        "IsMediaRequired": true,
        "MediaTitle": "Lịch sử cuộc gọi",
        "SortOrder": 1,
        "IsActive": true,
        "TypeName": "Lấy hàng",
        "CreatedTimeDisplay": "11/03/2026 10:00",
        "CreatedByUserName": "admin",
        "UpdatedTimeDisplay": "11/03/2026 12:00",
        "UpdatedByUserName": "admin"
      }
    ]
  }
}
```

---

## 2. Lấy chi tiết lý do thất bại

### 2.1. Lấy thông tin theo ID

**Endpoint**: `GET /api/OrderFailReason/{id}`  
**Authorization**: `OrderFailReason.GetById`

Mô tả: Lấy thông tin chi tiết của một lý do để hiển thị trên form cập nhật.

**Response:**
```json
{
  "Result": 1,
  "Message": "Thành công",
  "Data": {
    "Id": 1,
    "Name": "Khách không nghe máy",
    "Description": "Gọi 3 cuộc nhưng không nghe",
    "Type": 1,
    "IsMediaRequired": true,
    "MediaTitle": "Lịch sử cuộc gọi",
    "SortOrder": 1,
    "IsActive": true
  }
}
```

---

## 3. Thêm mới hoặc cập nhật lý do thất bại

### 3.1. Thêm mới hoặc cập nhật

**Endpoint**: `POST /api/OrderFailReason/CreateOrUpdate`  
**Authorization**: `OrderFailReason.CreateOrUpdate`

Mô tả: API dùng để tạo mới (khi truyền Id = 0) hoặc cập nhật (khi truyền Id > 0) một lý do lấy/giao hàng thất bại.

**Request Body:**
```json
{
  "Id": 0,
  "Name": "Sai địa chỉ giao hàng",
  "Description": "Khách hàng nhập sai địa chỉ trên ứng dụng",
  "Type": 2,
  "IsMediaRequired": false,
  "MediaTitle": "",
  "SortOrder": 2,
  "IsActive": true
}
```

> [!IMPORTANT]
> **Quy tắc Media**
> Nếu `IsMediaRequired` được set là `true`, trường `MediaTitle` nên có nội dung hướng dẫn để hiển thị cho tài xế trên Driver App biết cần phải chụp ảnh gì. Ví dụ: `MediaTitle = "Ảnh chụp nhà/biển số xe"`.

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

---

## 4. Xóa lý do thất bại

### 4.1. Xóa lý do (Soft Delete)

**Endpoint**: `POST /api/OrderFailReason/Delete`  
**Authorization**: `OrderFailReason.Delete`

Mô tả: Xóa một lý do thất bại khỏi hệ thống (Cập nhật trường IsDeleted = true).

**Request Body:**
```json
{
  "Id": 1
}
```

**Response:**
```json
{
  "Result": 1,
  "Message": "Xóa thành công",
  "Data": true
}
```
