# Issue #14: Expense & Income Management

Memperbaiki bug kolom data yang kosong pada halaman "Manajemen Pengeluaran" dan menambahkan fitur "Pemasukan" (Income) dengan menggabungkan keduanya ke dalam satu modul transaksi kas (Cash Transactions) yang terpadu, sesuai dengan permintaan issue.

## User Review Required

> [!IMPORTANT]
> **Penyatuan Modul (Unification)**
> Sesuai kriteria "Gabungkan fitur expense dan income ke dalam satu modul yang terpadu", saya berencana untuk me-rename tabel `expenses` menjadi `cash_transactions`. Semua kode yang berhubungan dengan `Expense` (Model, Controller, Service) akan diubah menjadi `CashTransaction` dengan tambahan kolom `type` ('income' atau 'expense').
> 
> Apakah Anda setuju dengan pendekatan me-rename keseluruhan tabel dan struktur kode dari *Expense* menjadi *Cash Transaction*, atau Anda lebih memilih tetap menggunakan tabel `expenses` lalu kita hanya menambahkan kolom `type` di dalamnya tanpa mengubah nama tabel?
> 
> *Saran dari saya*: Me-rename menjadi `cash_transactions` lebih sesuai secara bisnis/domain agar lebih mudah dipahami oleh programmer junior di masa depan (bahwa ini mencakup kas masuk dan kas keluar).

## Proposed Changes

---

### Database Layer (Migrations & Models)

Kita akan membuat database lebih masuk akal untuk mencatatkan pemasukan dan pengeluaran secara bersamaan.

#### [NEW] Migration: `modify_expenses_table_to_cash_transactions`
- Rename tabel `expenses` menjadi `cash_transactions`.
- Drop foreign key lama: `expenses_expense_account_id_foreign`.
- Rename kolom `expense_account_id` menjadi `related_account_id` (karena akun ini bisa jadi akun beban atau akun pendapatan).
- Tambahkan foreign key baru untuk `related_account_id`.
- Tambahkan kolom `type` dengan tipe data ENUM berisi `['income', 'expense']`, default `'expense'`.

#### [RENAME/MODIFY] `app/Models/Expense.php` -> `app/Models/CashTransaction.php`
- Ubah nama class dari `Expense` menjadi `CashTransaction`.
- Tambahkan properti `protected $table = 'cash_transactions';`.
- Ubah fillable properties: hapus `expense_account_id` diganti dengan `type` dan `related_account_id`.
- Ubah nama relasi dari `expenseAccount()` menjadi `relatedAccount()`.

---

### Backend Logic & Service (Controllers & Services)

Kita perlu menyesuaikan Form Request, Service, dan Controller agar bisa menghandle dua tipe transaksi (Income dan Expense).

#### [RENAME/MODIFY] `app/Services/ExpenseService.php` -> `app/Services/CashTransactionService.php`
- Ubah `createExpense()` menjadi `createTransaction(array $data)`.
- Mengatur logika pembuatan Journal Entry secara otomatis berdasarkan `type`:
    - **Jika `type === 'expense'`**: `related_account` di-[Debit] dan `cash_account` di-[Credit].
    - **Jika `type === 'income'`**: `cash_account` di-[Debit] dan `related_account` di-[Credit].

#### [RENAME/MODIFY] `app/Http/Controllers/ExpenseController.php` -> `app/Http/Controllers/CashTransactionController.php`
- **`index()`**: Mengambil data `CashTransaction::with(['relatedAccount', 'cashAccount', 'createdBy'])`.
- **`create()`**: Mengambil tiga list akun untuk frontend:
    - `$expenseAccounts`: Akun dengan klasifikasi `expense` (Beban).
    - `$incomeAccounts`: Akun dengan klasifikasi `revenue` (Pendapatan).
    - `$cashAccounts`: Akun aset kas/bank.
- **`store()`**: Meneruskan payload ke tipe Service yang baru.

#### [NEW] `app/Http/Requests/StoreCashTransactionRequest.php`
- Form request untuk validasi input:
    - `type` harus bernilai 'income' atau 'expense'.
    - `related_account_id` harus valid dan exist di tabel `accounts`.
    - `cash_account_id` harus valid dan exist.
    - `amount` minimal > 0.
- Delete file request yang lama (`StoreExpenseRequest.php`).

#### [MODIFY] `routes/web.php`
- Ganti Route mapping `expenses` menjadi `cash-transactions`.
- Menjalankan Wayfinder CLI (`php artisan wayfinder:generate`) untuk memperbarui file-file TypeScript helper dari auto-generated routes.

---

### Frontend (React + Inertia)

Memperbaiki bug *Empty Columns* karena salah nama props yang diharapkan (frontend mengharapkan `expenseAccount`, sedangkan Laravel mengembalikan `expense_account` dalam format JSON snake_case).

#### [RENAME/MODIFY] `resources/js/pages/Expenses` -> `resources/js/pages/CashTransactions`

**`Index.tsx`**:
- Mengubah tipe `Expense` menjadi `CashTransaction`.
- Memperbaiki data binding: mengubah `row.original.expenseAccount` menjadi `row.original.related_account` agar kolom tidak kosong (Sesuai Issue #14).
- Menambahkan kolom **Tipe** dengan label/badge berwarna (Hijau untuk Pemasukan, Merah untuk Pengeluaran) menggunakan komponen Badge UI.

**`Create.tsx`**:
- Menambahkan layout Tabs/Segmented Control (Beban / Pendapatan) di tampilan antarmuka. Pilihan tab akan mengubah state `type`.
- Jika Tab = Pemasukan, Dropdown akun terkait nama labelnya menjadi "Akun Pendapatan" dan me-mapping dropdown list ke `$incomeAccounts`.
- Jika Tab = Pengeluaran, Dropdown nama labelnya "Akun Beban" dan me-mapping ke `$expenseAccounts`.

#### [RENAME/MODIFY] `resources/js/types/expense.ts` -> `resources/js/types/cash-transaction.ts`
- Sesuaikan tipe Typescript dengan kembalian JSON Laravel yaitu menggunakan *snake_case* pada relasi:
  ```typescript
  type: 'income' | 'expense';
  related_account?: Account;
  cash_account?: Account;
  created_by?: User;
  ```

## Open Questions

1. Apakah kita harus membuat data seeder atau melakukan migrasi otomatis untuk data lama (karena semua data `expenses` lama otomatis akan memiliki default `type = 'expense'`)?  Saya rasa memberikan `default('expense')` di field `type` pada migrasi database sudah cukup untuk membuat fitur tetap aman dan data lama tetap bisa jalan. Setuju?
2. Bagaimana perlakuan Menu di sidebar? Jika kita menggabungkan ke dalam satu modul, kita sebaiknya mengubah nama menu di layout utama (jika ada) dari "Manajemen Pengeluaran" menjadi "Manajemen Kas" atau "Pemasukan & Pengeluaran".

## Verification Plan

### Automated Tests
- Menjalankan `php artisan test --compact` untuk memastikan perubahan nama dari Expense ke CashTransaction tidak memecah test eksisting, dan jika ada test yang terkait, saya akan memperbaruinya (mengganti test case `ExpenseControllerTest` ke `CashTransactionControllerTest`).

### Manual Verification
- Buka dashboard lalu ke menu Pemasukan & Pengeluaran.
- Tinjau agar kolom **Related Account** dan **Cash Account** yang sebelumnya kosong, sekarang menampilkan data sesuai perbaikan Typescript property (`expense_account`).
- Pencet "Input Transaksi", dan verifikasi form memiliki Tab *Pemasukan* dan *Pengeluaran*, yang menampilkan *Income Accounts* atau *Expense Accounts* yang sesuai dengan input.
- Input data baru (1 Income, 1 Expense), lalu periksa apakah Jurnal Entri yang digenerate oleh sistem di sisi backend arah Debit/Kredit-nya sudah berimbang dan benar sesuai prinsip akuntansi.
