---
name: Financial Reporting Feature
description: Finance Report module - form structure, CSV/PDF import, view page with tabs, export PDF, and key implementation details
type: project
---

## Finance Report Module Overview

The finance report feature is at `app/{id}/finance-reports` with create, edit, view, and list pages.

### Form Structure
- Single `transactions` TableRepeater (previously two separate incomes/expenses tables)
- Virtual `type` field (income/expense) — not in DB, `dehydrated(false)`, used to filter category dropdown reactively
- Type is hydrated from `transaction_category.type` on edit
- Fields per row: type, date, category (filtered by type), description, amount
- Amount uses Indonesian currency format: `$money($input, ',', '.', 2)` — dot as thousands, comma as decimal, 2 decimal places
- All summary fields (saving, total_income, total_expense, total_balance, initial_balance) also use 2 decimal places
- Totals auto-calculated on form submit via `mutateFormDataBeforeCreate` / `mutateFormDataBeforeSave`
- Calculate Totals button available for manual recalculation

### Import Features
- **Import CSV**: uploads CSV with columns (date, type, category, description, amount). Sample file at `storage/app/public/sample-finance-report-import.csv` with real TransactionCategory names
- **Import PDF**: sends BCA e-statement PDF to `https://bca-parser.omahkoding.space/api/parse-json` with Bearer token from `config('app.bca_parser_token')`. API returns `debet` (income) and `credit` (expense) with `tgl` (day) and `uraian` (description)
- Both imports format amounts as Indonesian currency strings before inserting into form state

### Data Model
- `FinanceReport` has `transactions()`, `incomes()`, `expenses()` relationships
- `transactions()` returns all Transaction records (used by form)
- `incomes()` / `expenses()` filter by `transaction_category.type` (used by view page and PDF export)
- `Transaction.amount` is `decimal(15,2)` (migrated from bigint)
- `Transaction.setAmountAttribute` properly parses Indonesian format: removes dots, converts comma to period
- `transaction_category_id` is constrained FK to `transaction_categories`

### View Page
- Custom blade at `resources/views/filament/finance-reports/view.blade.php`
- Uses Alpine.js tabs: All, Jurnal Keuangan, Posting Keuangan, Laba Rugi, Arus Kas, Neraca
- Data prepared in `ViewFinanceReport::getViewData()` — same structure as PDF export controller
- Export PDF button links to `route('finance.export-pdf')`

### PDF Export
- Controller: `FinanceReportExportController::exportPdf()`
- Template: `resources/views/filament/finance-reports/export-pdf.blade.php`
- Uses `barryvdh/laravel-dompdf`
- Sections: Jurnal Keuangan, Posting Keuangan, Laba Rugi, Arus Kas, Neraca (Balance Sheet)

### Key Files
- `app/Filament/Resources/FinanceReportResource.php` — form & table definition
- `app/Filament/Resources/FinanceReportResource/Pages/CreateFinanceReport.php`
- `app/Filament/Resources/FinanceReportResource/Pages/EditFinanceReport.php`
- `app/Filament/Resources/FinanceReportResource/Pages/ViewFinanceReport.php`
- `app/Models/FinanceReport.php`
- `app/Models/Transaction.php`
- `app/Models/TransactionCategory.php`
- `app/Http/Controllers/FinanceReportExportController.php`

### Important Notes
- When setting amounts programmatically (imports, calculate), always format with `number_format($val, 2, ',', '.')` — raw floats break the money mask
- When parsing amounts from form state, always do: `str_replace('.', '', $val)` then `str_replace(',', '.', $val)` then cast to float
- The `type` virtual field in raw form state (`$this->data['transactions']`) is needed for calculations since it's not dehydrated into `$data['transactions']`
