# Customer Reconciliation Slip - API Quick Reference

## Endpoints Overview

| Endpoint | Method | Description | Authorization |
|----------|--------|-------------|---------------|
| `/api/CustomerReconciliationSlip/Approve/{id}` | PUT | Duyệt phiếu đối soát | Approve, Founder, Accountant |
| `/api/CustomerReconciliationSlip/Reject` | POST | Từ chối phiếu đối soát | Creator, Reject, Founder, Accountant |
| `/api/CustomerReconciliationSlip/Complete` | POST | Hoàn thành phiếu đối soát | Complete, Founder, Accountant |
| `/api/CustomerReconciliationSlip/ExportExcel` | POST | Xuất Excel danh sách phiếu | ExportExcel, Founder |
| `/api/CustomerReconciliationSlip/ExportExcelDetail/{slipId}` | POST | Xuất Excel chi tiết phiếu | ExportExcel, Founder |

---

## Quick Examples

### 1. Approve Slip
```bash
curl -X PUT "https://api.example.com/api/CustomerReconciliationSlip/Approve/123" \
  -H "Authorization: Bearer {token}"
```

**Response:**
```json
{
  "Message": "Duyệt phiếu thành công"
}
```

---

### 2. Reject Slip
```bash
curl -X POST "https://api.example.com/api/CustomerReconciliationSlip/Reject" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer {token}" \
  -d '{
    "Id": 123,
    "Reason": "Số tiền COD không khớp với thực tế"
  }'
```

**Response:**
```json
{
  "Message": "Từ chối phiếu thành công"
}
```

---

### 3. Complete Slip
```bash
curl -X POST "https://api.example.com/api/CustomerReconciliationSlip/Complete" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer {token}" \
  -d '{
    "Id": 123,
    "PaymentMethod": "Chuyển khoản Vietcombank",
    "TransactionCode": "FT24120912345678",
    "Note": "Đã chuyển khoản cho khách hàng"
  }'
```

**Response:**
```json
{
  "Message": "Xác nhận thanh toán thành công"
}
```

---

### 4. Export Excel List
```bash
curl -X POST "https://api.example.com/api/CustomerReconciliationSlip/ExportExcel" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer {token}" \
  -d '{
    "FileName": "DanhSachPhieuDoiSoat_Thang12",
    "FromDate": "2024-12-01T00:00:00Z",
    "ToDate": "2024-12-31T23:59:59Z",
    "Status": 4,
    "IncludeOrderDetails": true
  }'
```

**Response:**
```json
{
  "Result": 1,
  "Message": "Xuất Excel thành công",
  "FileName": "DanhSachPhieuDoiSoat_Thang12.xlsx",
  "DownloadUrl": "https://api.example.com/downloads/...",
  "TotalRecords": 15,
  "FileSize": 245760
}
```

---

### 5. Export Excel Detail
```bash
curl -X POST "https://api.example.com/api/CustomerReconciliationSlip/ExportExcelDetail/123" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer {token}" \
  -d '{
    "FileName": "ChiTietPhieu_CR-241209-A1B2",
    "IncludeOrderDetails": true,
    "IncludeApprovalInfo": true,
    "IncludeNotes": true
  }'
```

**Response:**
```json
{
  "Result": 1,
  "Message": "Xuất Excel chi tiết thành công",
  "FileName": "ChiTietPhieu_CR-241209-A1B2.xlsx",
  "DownloadUrl": "https://api.example.com/downloads/...",
  "TotalRecords": 1,
  "FileSize": 102400
}
```

---

## Workflow Diagrams

### Phiếu Chi Tiền (Receivable - Công ty trả khách)
```
┌─────────┐
│  Draft  │
└────┬────┘
     │ Create
     ▼
┌──────────────────┐
│ PendingApproval  │
└────┬─────────────┘
     │
     ├─────────► Approve ──────┐
     │                         │
     │                         ▼
     │                    ┌──────────┐
     │                    │ Approved │
     │                    └────┬─────┘
     │                         │
     │                         │ Complete
     │                         ▼
     │                    ┌───────────┐
     │                    │ Completed │
     │                    └───────────┘
     │
     └─────────► Reject ──────┐
                               ▼
                          ┌──────────┐
                          │ Rejected │
                          └──────────┘
```

### Phiếu Thu Tiền (Payable - Khách trả công ty)
```
┌─────────┐
│  Draft  │
└────┬────┘
     │ Create (with proof image)
     ▼
┌──────────────────┐
│ PendingApproval  │
└────┬─────────────┘
     │
     ├─────────► Complete ─────┐
     │                         │
     │                         ▼
     │                    ┌───────────┐
     │                    │ Completed │
     │                    └───────────┘
     │
     └─────────► Reject ──────┐
                               ▼
                          ┌──────────┐
                          │ Rejected │
                          └──────────┘
```

---

## Status Codes Reference

| Status | Value | Description | Next Actions |
|--------|-------|-------------|--------------|
| Draft | 1 | Nháp | Submit → PendingApproval |
| PendingApproval | 2 | Chờ duyệt | Approve (Receivable) / Complete (Payable) / Reject |
| Approved | 3 | Đã duyệt | Complete / Reject |
| Completed | 4 | Hoàn thành | None (Final state) |
| Rejected | 8 | Từ chối | None (Final state) |

---

## Type Reference

| Type | Value | Description | Workflow |
|------|-------|-------------|----------|
| Receivable | 1 | Phiếu chi tiền (công ty trả khách) | Requires approval before completion |
| Payable | 2 | Phiếu thu tiền (khách trả công ty) | Direct completion, no approval needed |

---

## Permission Matrix

| Action | Required Roles |
|--------|----------------|
| Approve | `CustomerReconciliationSlip.Approve` OR `Founder` OR `Accountant` |
| Reject | Creator OR `CustomerReconciliationSlip.Reject` OR `Founder` OR `Accountant` |
| Complete | `CustomerReconciliationSlip.Complete` OR `Founder` OR `Accountant` |
| Export Excel | `CustomerReconciliationSlip.ExportExcel` OR `Founder` |

---

## Common Error Responses

### 400 Bad Request
```json
{
  "Message": "Trạng thái phiếu không hợp lệ"
}
```

### 401 Unauthorized
```json
{
  "Message": "Unauthorized"
}
```

### 403 Forbidden
```json
{
  "Message": "Forbidden"
}
```

### 404 Not Found
```json
{
  "Message": "Phiếu không tồn tại"
}
```

### 500 Internal Server Error
```json
{
  "Result": 3,
  "Message": "Lỗi hệ thống: {error details}"
}
```

---

## Request Models

### RejectCustomerReconciliationSlipModel
```typescript
interface RejectModel {
  Id: number;              // Required
  Reason: string;          // Required, min 10 chars
}
```

### CompleteCustomerReconciliationSlipModel
```typescript
interface CompleteModel {
  Id: number;                    // Required
  PaymentMethod: string;         // Required
  TransactionCode?: string;      // Optional
  ProofImageUrl?: string;        // Optional
  Note?: string;                 // Optional
}
```

### CustomerReconciliationSlipExcelExportModel
```typescript
interface ExportModel {
  FileName?: string;
  CustomerReconciliationSlipIds?: number[];
  FromDate?: Date;
  ToDate?: Date;
  CustomerId?: number;
  Status?: number;               // 1|2|3|4|8
  Type?: number;                 // 1|2
  IncludeOrderDetails?: boolean; // default: true
  IncludeApprovalInfo?: boolean; // default: true
  IncludeNotes?: boolean;        // default: true
  FolderPath?: string;
}
```

---

## Validation Rules

### Approve
- ✓ Phiếu phải tồn tại
- ✓ Phiếu phải ở trạng thái `PendingApproval`
- ✓ Chỉ áp dụng cho phiếu loại `Receivable`

### Reject
- ✓ Phiếu phải tồn tại
- ✓ Phiếu không được ở trạng thái `Completed` hoặc `Rejected`
- ✓ Lý do từ chối không được để trống
- ✓ Lý do từ chối tối thiểu 10 ký tự

### Complete
- ✓ Phiếu phải tồn tại
- ✓ **Receivable:** Phải ở trạng thái `Approved`
- ✓ **Payable:** Phải ở trạng thái `PendingApproval`
- ✓ PaymentMethod không được để trống

### Export Excel
- ✓ FromDate ≤ ToDate
- ✓ Tất cả IDs > 0
- ✓ Tên file không chứa ký tự đặc biệt

---

## Testing Checklist

### Approve
- [ ] Approve phiếu Receivable ở trạng thái PendingApproval
- [ ] Không thể approve phiếu Payable
- [ ] Không thể approve phiếu ở trạng thái khác
- [ ] Kiểm tra quyền: chỉ Founder/Accountant/Approve permission
- [ ] Kiểm tra log được tạo

### Reject
- [ ] Reject phiếu với lý do hợp lệ
- [ ] Không thể reject phiếu Completed
- [ ] Không thể reject phiếu Rejected
- [ ] Kiểm tra quyền: Creator/Founder/Accountant/Reject permission
- [ ] Kiểm tra lý do được lưu vào InternalNote
- [ ] Kiểm tra log được tạo

### Complete
- [ ] Complete phiếu Receivable sau khi Approved
- [ ] Complete phiếu Payable trực tiếp từ PendingApproval
- [ ] Không thể complete phiếu Receivable chưa Approved
- [ ] Kiểm tra thông tin thanh toán được lưu
- [ ] Kiểm tra quyền: Founder/Accountant/Complete permission
- [ ] Kiểm tra log được tạo

### Export Excel
- [ ] Export với filter theo ngày
- [ ] Export với filter theo khách hàng
- [ ] Export với filter theo trạng thái
- [ ] Export với filter theo loại phiếu
- [ ] Export danh sách IDs cụ thể
- [ ] Export chi tiết một phiếu
- [ ] Kiểm tra file Excel được tạo đúng format
- [ ] Kiểm tra download URL hoạt động
- [ ] Kiểm tra quyền: ExportExcel permission/Founder

---

## Integration Examples

### JavaScript/TypeScript
```typescript
// Approve slip
async function approveSlip(slipId: number): Promise<void> {
  const response = await fetch(
    `${API_BASE_URL}/api/CustomerReconciliationSlip/Approve/${slipId}`,
    {
      method: 'PUT',
      headers: {
        'Authorization': `Bearer ${token}`,
      },
    }
  );
  
  if (!response.ok) {
    throw new Error('Failed to approve slip');
  }
  
  const result = await response.json();
  console.log(result.Message);
}

// Reject slip
async function rejectSlip(slipId: number, reason: string): Promise<void> {
  const response = await fetch(
    `${API_BASE_URL}/api/CustomerReconciliationSlip/Reject`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`,
      },
      body: JSON.stringify({
        Id: slipId,
        Reason: reason,
      }),
    }
  );
  
  if (!response.ok) {
    throw new Error('Failed to reject slip');
  }
  
  const result = await response.json();
  console.log(result.Message);
}

// Complete slip
async function completeSlip(data: CompleteModel): Promise<void> {
  const response = await fetch(
    `${API_BASE_URL}/api/CustomerReconciliationSlip/Complete`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`,
      },
      body: JSON.stringify(data),
    }
  );
  
  if (!response.ok) {
    throw new Error('Failed to complete slip');
  }
  
  const result = await response.json();
  console.log(result.Message);
}

// Export Excel
async function exportExcel(filter: ExportModel): Promise<string> {
  const response = await fetch(
    `${API_BASE_URL}/api/CustomerReconciliationSlip/ExportExcel`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`,
      },
      body: JSON.stringify(filter),
    }
  );
  
  if (!response.ok) {
    throw new Error('Failed to export Excel');
  }
  
  const result = await response.json();
  return result.DownloadUrl;
}
```

---

## Related Documentation

- [Full API Documentation](./API_CustomerReconciliationSlip_Actions.md)
- [Permission Updates](./CustomerReconciliationSlip_Permission_Updates.md)
- [Excel Export Details](./API_CustomerReconciliationSlipExcelExport.md)
- [Create & Search APIs](./API_CustomerReconciliationSlip_CreateSearch.md)
