234 lines
5.8 KiB
Markdown
234 lines
5.8 KiB
Markdown
# Hướng dẫn thêm Enum mới
|
|
|
|
## Tổng quan
|
|
|
|
Hệ thống sử dụng PHP Enums với i18n support. Khi cần thêm giá trị enum mới (Service Type, Contract Type, v.v.), chỉ cần cập nhật 3 chỗ.
|
|
|
|
## Cấu trúc Enum hiện có
|
|
|
|
```
|
|
app/Enums/
|
|
├── ContractStatus.php # Trạng thái hợp đồng
|
|
├── ContractType.php # Loại hợp đồng
|
|
├── HandoverStatus.php # Trạng thái bàn giao
|
|
└── ServiceType.php # Loại dịch vụ
|
|
```
|
|
|
|
## Ví dụ: Thêm Service Type mới
|
|
|
|
Giả sử cần thêm loại dịch vụ "Bảo trì định kỳ" (maintenance).
|
|
|
|
### Bước 1: Thêm case vào Enum
|
|
|
|
**File:** `app/Enums/ServiceType.php`
|
|
|
|
```php
|
|
enum ServiceType: string
|
|
{
|
|
case MANAGEMENT_FEE = 'management_fee';
|
|
case GRATITUDE = 'gratitude';
|
|
case SELF_BUSINESS = 'self_business';
|
|
case MAINTENANCE = 'maintenance'; // ← THÊM MỚI
|
|
|
|
public function label(): string
|
|
{
|
|
return match ($this) {
|
|
self::MANAGEMENT_FEE => __('enums.service.management_fee'),
|
|
self::GRATITUDE => __('enums.service.gratitude'),
|
|
self::SELF_BUSINESS => __('enums.service.self_business'),
|
|
self::MAINTENANCE => __('enums.service.maintenance'), // ← THÊM MỚI
|
|
};
|
|
}
|
|
|
|
public function color(): string
|
|
{
|
|
return match ($this) {
|
|
self::MANAGEMENT_FEE => 'info',
|
|
self::GRATITUDE => 'success',
|
|
self::SELF_BUSINESS => 'warning',
|
|
self::MAINTENANCE => 'primary', // ← THÊM MỚI
|
|
};
|
|
}
|
|
|
|
// options() tự động lấy tất cả cases - KHÔNG cần sửa
|
|
}
|
|
```
|
|
|
|
### Bước 2: Thêm translation tiếng Việt
|
|
|
|
**File:** `lang/vi/enums.php`
|
|
|
|
```php
|
|
return [
|
|
// ... existing keys ...
|
|
|
|
'service' => [
|
|
'management_fee' => 'Phí quản lý',
|
|
'gratitude' => 'Tri ân',
|
|
'self_business' => 'Tự doanh',
|
|
'maintenance' => 'Bảo trì định kỳ', // ← THÊM MỚI
|
|
],
|
|
|
|
// ... existing keys ...
|
|
];
|
|
```
|
|
|
|
### Bước 3: Thêm translation tiếng Anh
|
|
|
|
**File:** `lang/en/enums.php`
|
|
|
|
```php
|
|
return [
|
|
// ... existing keys ...
|
|
|
|
'service' => [
|
|
'management_fee' => 'Management fee',
|
|
'gratitude' => 'Gratitude',
|
|
'self_business' => 'Self business',
|
|
'maintenance' => 'Periodic maintenance', // ← THÊM MỚI
|
|
],
|
|
|
|
// ... existing keys ...
|
|
];
|
|
```
|
|
|
|
### Bước 4: Reload browser
|
|
|
|
Không cần chạy lệnh nào, chỉ cần reload trang.
|
|
|
|
## Ví dụ: Thêm Contract Type mới
|
|
|
|
### Bước 1: Thêm case
|
|
|
|
**File:** `app/Enums/ContractType.php`
|
|
|
|
```php
|
|
enum ContractType: string
|
|
{
|
|
case SALE = 'sale';
|
|
case LEASE = 'lease';
|
|
case BCC = 'bcc';
|
|
case CONSORTIUM = 'consortium'; // ← THÊM MỚI
|
|
|
|
public function label(): string
|
|
{
|
|
return match ($this) {
|
|
self::SALE => __('enums.contract_type.sale'),
|
|
self::LEASE => __('enums.contract_type.lease'),
|
|
self::BCC => __('enums.contract_type.bcc'),
|
|
self::CONSORTIUM => __('enums.contract_type.consortium'), // ← THÊM MỚI
|
|
};
|
|
}
|
|
|
|
public function color(): string
|
|
{
|
|
return match ($this) {
|
|
self::SALE => 'success',
|
|
self::LEASE => 'info',
|
|
self::BCC => 'warning',
|
|
self::CONSORTIUM => 'primary', // ← THÊM MỚI
|
|
};
|
|
}
|
|
}
|
|
```
|
|
|
|
### Bước 2-3: Thêm translations
|
|
|
|
```php
|
|
// lang/vi/enums.php
|
|
'contract_type' => [
|
|
'sale' => 'HĐ Mua bán',
|
|
'lease' => 'HĐ Thuê',
|
|
'bcc' => 'HĐ Hợp tác kinh doanh (BCC)',
|
|
'consortium' => 'HĐ Liên doanh', // ← THÊM MỚI
|
|
],
|
|
|
|
// lang/en/enums.php
|
|
'contract_type' => [
|
|
'sale' => 'Sale contract',
|
|
'lease' => 'Lease contract',
|
|
'bcc' => 'Business cooperation contract (BCC)',
|
|
'consortium' => 'Consortium contract', // ← THÊM MỚI
|
|
],
|
|
```
|
|
|
|
## Template Enum (Copy-paste)
|
|
|
|
Khi tạo enum mới, copy template sau:
|
|
|
|
```php
|
|
<?php
|
|
|
|
namespace App\Enums;
|
|
|
|
/**
|
|
* [Tên] Enum
|
|
*
|
|
* Để thêm giá trị mới:
|
|
* 1. Thêm case mới vào enum
|
|
* 2. Thêm label trong lang/vi/enums.php và lang/en/enums.php
|
|
* 3. Reload browser
|
|
*/
|
|
enum [EnumName]: string
|
|
{
|
|
case [CASE_1] = '[value_1]';
|
|
case [CASE_2] = '[value_2]';
|
|
|
|
public function label(): string
|
|
{
|
|
return match ($this) {
|
|
self::[CASE_1] => __('enums.[enum_name].[value_1]'),
|
|
self::[CASE_2] => __('enums.[enum_name].[value_2]'),
|
|
};
|
|
}
|
|
|
|
public function color(): string
|
|
{
|
|
return match ($this) {
|
|
self::[CASE_1] => 'success',
|
|
self::[CASE_2] => 'info',
|
|
};
|
|
}
|
|
|
|
public static function options(): array
|
|
{
|
|
return collect(self::cases())->mapWithKeys(fn ($case) => [
|
|
$case->value => $case->label(),
|
|
])->toArray();
|
|
}
|
|
}
|
|
```
|
|
|
|
## Cách sử dụng Enum trong code
|
|
|
|
### Trong Filament Form
|
|
```php
|
|
Select::make('service_type')
|
|
->label(__('enums.service_type'))
|
|
->options(ServiceType::options())
|
|
->required(),
|
|
```
|
|
|
|
### Trong Filament Table
|
|
```php
|
|
TextColumn::make('service_type')
|
|
->badge()
|
|
->color(fn (string $state): string => ServiceType::from($state)->color())
|
|
->formatStateUsing(fn (string $state): string => ServiceType::from($state)->label()),
|
|
```
|
|
|
|
### Trong PHP code
|
|
```php
|
|
$type = ServiceType::MANAGEMENT_FEE;
|
|
echo $type->label(); // "Phí quản lý"
|
|
echo $type->value; // "management_fee"
|
|
echo $type->color(); // "info"
|
|
```
|
|
|
|
## Lưu ý
|
|
|
|
1. **`options()` method** - PHẢI là `static` (không phải instance method)
|
|
2. **Translation keys** - Phải có trong CẢ `lang/vi/enums.php` VÀ `lang/en/enums.php`
|
|
3. **Color values** - Sử dụng Filament colors: `primary`, `success`, `warning`, `danger`, `info`, `gray`
|
|
4. **Case values** - Nên dùng snake_case (ví dụ: `management_fee`, không phải `ManagementFee`)
|