# Hệ thống Quản lý Doanh thu (Income Management System)

## Tổng quan

Hệ thống quản lý doanh thu được xây dựng tương tự như hệ thống quản lý chi phí (Expense), bao gồm các thành phần chính:

1. **Income** - Doanh thu
2. **IncomeCategory** - Danh mục doanh thu
3. **IncomeHistory** - Lịch sử thay đổi doanh thu
4. **IncomeStatus** - Enum trạng thái doanh thu

## Cấu trúc dữ liệu

### IncomeStatus Enum

```csharp
public enum IncomeStatus
{
    Pending,    // Đang chờ xử lý
    Approved,   // Đã phê duyệt
    Rejected,   // Đã từ chối
    Received    // Đã nhận tiền (tương ứng với Paid trong Expense)
}
```

### Income Entity

Entity `Income` kế thừa từ `BaseEntityWithKey<Guid>` và có các thuộc tính:

- **Thông tin cơ bản**: Description, Note, Amount
- **Danh mục**: IncomeCategoryId (required), IncomeCategory
- **Trạng thái**: Status (IncomeStatus)
- **Liên kết**: TransactionId, OrderId
- **Phê duyệt**: ApprovedBy, RejectReason
- **Tài khoản ngân hàng**: UserBankAccountId, BankAccountNumber, BankAccountHolderName, BankCode, BankName, BankBranchName

### IncomeCategory Entity

Entity `IncomeCategory` kế thừa từ `BaseCategory` và có các thuộc tính:

- **Từ BaseCategory**: Id, Name, Description, DisplayOrder
- **Cây danh mục**: ParentId, Parent, Children (self-referencing)
- **Phê duyệt**: ApprovedBy

### IncomeHistory Entity

Entity `IncomeHistory` kế thừa từ `BaseEntityWithKey<int>` và lưu trữ lịch sử thay đổi trạng thái:

- **IncomeId**: ID của doanh thu
- **Status**: Trạng thái mới
- **Reason**: Lý do từ chối (nếu có)
- **Note**: Ghi chú

## Pattern Copy-on-Reference

Hệ thống áp dụng pattern **Copy-on-Reference** tương tự như Expense:

- Khi tạo Income với UserBankAccountId, thông tin ngân hàng được **copy** vào các trường BankAccountNumber, BankAccountHolderName, BankCode, BankName, BankBranchName
- Điều này đảm bảo:
  - Lưu trữ thông tin ngân hàng tại thời điểm tạo doanh thu
  - Dữ liệu lịch sử không bị ảnh hưởng khi thay đổi thông tin tài khoản
  - Không cần join với UserBankAccount khi hiển thị danh sách

## Quy trình xử lý

### 1. Tạo doanh thu (Pending)

- User tạo doanh thu với status = Pending
- Có thể liên kết với Order
- Có thể chọn tài khoản ngân hàng nhận tiền
- Thông tin ngân hàng được copy vào các trường tương ứng

### 2. Phê duyệt doanh thu (Approved)

- Approver duyệt doanh thu
- Lưu ApprovedBy vào database
- Tạo record trong IncomeHistory

### 3. Từ chối doanh thu (Rejected)

- Approver từ chối doanh thu
- Bắt buộc nhập lý do từ chối (RejectReason)
- Tạo record trong IncomeHistory

### 4. Nhận tiền (Received)

- Cập nhật status = Received
- **Tạo Transaction** và cộng tiền vào ví
- Liên kết Income với Transaction qua TransactionId
- Tạo record trong IncomeHistory

## Tích hợp với hệ thống Transaction

Khi doanh thu chuyển sang trạng thái **Received**:

1. Tạo Transaction mới
2. Set TransactionDirection = Income
3. Set TransactionType phù hợp (hoặc thêm type mới nếu cần)
4. Set IncomeCategoryId trong Transaction
5. Cộng tiền vào ví
6. Link Income với Transaction

## Cập nhật các thành phần liên quan

### Transaction Entity

- Thêm `IncomeCategoryId` và `IncomeCategory` navigation property

### UserBankAccount Entity

- Thêm `Incomes` collection để liên kết với Income

### LadaDbContext

- Thêm DbSet cho Income, IncomeCategory, IncomeHistory
- Đăng ký mapping cho các entity mới

## Mapping Files

### IncomeMap.cs

- Mapping cho Income entity
- Relationships với IncomeCategory, Transaction, Order, UserBankAccount

### IncomeCategoryMap.cs

- Mapping cho IncomeCategory entity
- Self-referencing relationship với Parent và Children

### IncomeHistoryMap.cs

- Mapping cho IncomeHistory entity
- Indexes cho IncomeId và CreatedTime
- Cascade delete khi xóa Income

## Migration

Để tạo migration cho hệ thống mới:

```bash
dotnet ef migrations add AddIncomeManagement -p Ladaer.BackEnd\Ladaer.BackEnd.csproj
```

## So sánh với Expense

| Đặc điểm        | Expense                  | Income                  |
| --------------- | ------------------------ | ----------------------- |
| Định hướng      | Trừ tiền                 | Cộng tiền               |
| Trạng thái cuối | Paid                     | Received                |
| Navigation      | UserBankAccount.Expenses | UserBankAccount.Incomes |
| Category        | ExpenseCategory          | IncomeCategory          |
| Transaction     | Trừ tiền khi Paid        | Cộng tiền khi Received  |

## Lưu ý

1. **ApprovedBy**: UserId của người duyệt, có thể khác với người celu.
2. **TransactionId**: Chỉ được set khi doanh thu chuyển sang trạng thái Received.
3. **Bank information**: Cần copy thông tin ngân hàng khi tạo Income để đảm bảo dữ liệu lịch sử.
4. **Soft delete**: Không được hỗ trợ, cần implement thêm nếu cần.
