# Implementation Plan - Create Models and Migrations

The goal is to create migration files and Eloquent models based on the provided entity-relationship diagram. Each model will include `fillable` attributes and implement `Filterable` and [SelectOptions](app/Models/Traits/SelectOptions.php#10-15) traits.
**Note:** All tables will include `id` (PK, auto-increment), `created_at` (timestamp), and `updated_at` (timestamp) by default.

## Proposed Changes

### Database Migrations

Create migration files for the following tables:

1.  `departments`
    - `user_id` (FK -> users)
    - `name` (string)
    - `status` (string, default: OriginStatusType::Active)
    - `deleted_at` (soft deletes)
2.  `banks`
    - `code` (string)
    - `name` (string)
    - `status` (string, default: OriginStatusType::Active)
    - `deleted_at` (soft deletes)
3.  `vendors` (Renamed from customers)
    - `name` (string)
    - `company_name` (string)
    - `phone` (string)
    - `address` (text)
    - `city` (string)
    - `status` (string, default: OriginStatusType::Active)
    - `deleted_at` (soft deletes)
4.  `categories`
    - `name` (string)
    - `period_type` (string, default: PeriodType::Monthly)
    - `status` (string, default: OriginStatusType::Active)
    - `deleted_at` (soft deletes)
5.  `companies`
    - `code` (string)
    - `name` (string)
    - `status` (string, default: OriginStatusType::Active)
    - `deleted_at` (soft deletes)
6.  `user_departments`
    - `user_id` (FK -> users)
    - `department_id` (FK -> departments)
    - `type` (string, default: UserDepartmentType::User)
    - `is_finance` (boolean)
7.  `user_banks`
    - `user_id` (FK -> users)
    - `bank_id` (FK -> banks)
    - `account_number` (bigInteger)
    - `account_name` (string)
    - `status` (string, default: OriginStatusType::Active)
8.  `user_companies`
    - `user_id` (FK -> users)
    - `company_id` (FK -> companies)
9.  `user_owners`
    - `owner_id` (FK -> users)
    - `user_id` (FK -> users)
10. `user_categories`
    - `user_id` (FK -> users)
    - `category_id` (FK -> categories)
    - `department_id` (FK -> departments)
11. `notifications`
    - `user_id` (FK -> users)
    - `budget_id` (FK -> budgets, nullable)
    - `transaction_id` (FK -> transactions, nullable)
    - `payment_id` (FK -> payments, nullable)
    - `module_type` (string, default: ModuleType::Budget)
    - `type` (string, default: NotificationType::Info)
    - `title` (string)
    - `message` (text)
    - `link` (string)
    - `is_read` (boolean)
    - `read_at` (timestamp, nullable)
12. `balances`
    - `company_id` (FK -> companies)
    - `code` (string)
    - `user_id` (FK -> users)
    - `department_id` (FK -> departments)
    - `debit_amount` (bigInteger)
    - `credit_amount` (bigInteger)
    - `year` (year)
    - `month` (tinyInteger)
13. `approval_logs`
    - `user_id` (FK -> users)
    - `budget_id` (FK -> budgets, nullable)
    - `budget_detail_id` (FK -> budget_details, nullable)
    - `payment_id` (FK -> payments, nullable)
    - `module_type` (string, default: ModuleType::Budget)
    - `action` (string, default: ActionStatusType::Submit)
    - `level` (string, default: UserDepartmentType::Manager)
    - `is_finance` (boolean)
    - `note` (text, nullable)
    - `ip_address` (string)
    - `user_agent` (longText)
14. `attachments`
    - `transaction_id` (FK -> transactions, nullable)
    - `payment_id` (FK -> payments, nullable)
    - `module_type` (string, default: ModuleType::Transaction)
    - `type` (string, default: AttachmentContentType::Image)
    - `label` (string)
    - `value` (longText)
    - `description` (longText, nullable)
15. `budgets`
    - `company_id` (FK -> companies)
    - `user_id` (FK -> users)
    - `balance_id` (FK -> balances)
    - `department_id` (FK -> departments)
    - `name` (string)
    - `code` (string)
    - `date` (date)
    - `year` (year)
    - `debit_amount` (bigInteger)
    - `credit_amount` (bigInteger)
    - `description` (text, nullable)
    - `status` (string, default: BudgetStatusType::Draft)
    - `status_message` (text, nullable)
    - `review_at` (timestamp, nullable)
16. `budget_details`
    - `budget_id` (FK -> budgets)
    - `user_id` (FK -> users)
    - `code` (string)
    - `name` (string)
    - `description` (text, nullable)
    - `quantity` (bigInteger)
    - `unit_type` (string, default: UnitType::Unit)
    - `price` (bigInteger)
    - `price_total` (bigInteger)
    - `status` (string, default: BudgetStatusType::Draft)
    - `status_message` (text, nullable)
17. `transactions`
    - `budget_detail_id` (FK -> budget_details)
    - `user_id` (FK -> users)
    - `vendor_id` (FK -> vendors)
    - `code` (string)
    - `name` (string)
    - `description` (text, nullable)
    - `quantity` (bigInteger)
    - `unit_type` (string, default: UnitType::Unit)
    - `price` (bigInteger)
    - `price_total` (bigInteger)
    - `status` (string, default: BudgetStatusType::Draft)
    - `status_message` (text, nullable)
18. `payments`
    - `company_id` (FK -> companies)
    - `department_id` (FK -> departments)
    - `budget_id` (FK -> budgets)
    - `user_review_id` (FK -> users)
    - `user_bank_id` (FK -> user_banks)
    - `bank_id` (FK -> banks)
    - `code` (string)
    - `type` (string, default: PaymentType::Full)
    - `method` (string, default: PaymentMethodType::EBanking)
    - `amount` (bigInteger)
    - `payment_date` (date)
    - `due_date` (date)
    - `cheque_number` (string)
    - `description` (text, nullable)
    - `status` (string, default: PaymentStatusType::Pending)
    - `status_message` (text, nullable)
    - `review_at` (timestamp, nullable)
19. `code_configs`
    - `module` (string, default: ModuleType::Budget, unique)
    - `prefix` (string)
    - `separator` (string, default: '/')
    - `digits` (integer, default: 4)
    - `last_number` (integer, default: 0)
    - `is_user_alias` (boolean)

### Models

Create models for all the above tables in `app/Models`.
Each model will:

- Use `HasFactory`, `SoftDeletes` (where applicable), `Filterable`, `SelectOptions`.
- Define `$fillable` array matching the columns.
- Define `$casts` for attributes like `is_finance`, `is_read`, dates, and enums.
- Define relationships (`belongsTo`, `hasMany`, `belongsToMany`) based on FKs and pivot tables.
  - **CRITICAL:** All `belongsTo`, `hasMany`, `hasOne` relationships MUST explicitly define the foreign key and owner key columns.
    - Example: `return $this->belongsTo(User::class, 'user_id');`
    - Example: `return $this->hasMany(Transaction::class, 'budget_detail_id');`
  - `user_departments`, `user_banks`, `user_companies`, `user_categories` will be treated as Pivot models.
  - `User` belongsToMany `Department`, `Bank`, `Company`, `Category`.
  - Implement `hasManyThrough` for deep relationships.

### Enums

- `OriginStatusType`: Active, Inactive
- `UserType`: PresidentDirector, Director, Manager, User
- `PeriodType`: Daily, Weekly, Monthly, Quarterly, Annually
- `UserDepartmentType`: User, Manager, Director
- `ModuleType`: Budget, Transaction, Payment, BudgetDetail
- `NotificationType`: Info, ApprovalRequest, Reminder, Monitoring
- `ActionStatusType`: Submit, Approve, Revise, Reject
- `AttachmentContentType`: Image, Pdf (no change if exists)
- `UnitType`: Pct, Unit, Pack, Pair, Liter, Dozen, Meter
- `PaymentType`: Full, Partial
- `PaymentStatusType`: Pending, Review, Cancel, Paid
- `PaymentMethodType`: EBanking, ChequeGiro, MainCash, PettyCash, CashUsd
- `BudgetStatusType`: Draft, Review, Approved, Rejected

### Database Migration Rules

- All columns using an **Enum** as a default value or type MUST have an index: `->index()`.
- Code columns MUST have an index: `->index()`.
- All boolean type using false as default value.

## Verification Plan

### Automated Tests

- Run `php artisan migrate:fresh` to ensure all migrations run successfully without errors.
- Run a script to verify that models can be instantiated and traits are loaded.
