# Porting laporan ke CI4

Pembaruan: 16 Oktober 2026.

Seluruh 29 URL dari `pos/reports/*.php` kini mempunyai route GET/POST dengan filter `auth`, termasuk varian `.php`. Terdapat 28 halaman laporan dan satu redirect kompatibilitas (`penjualan_office` ke `penjualan_sales`).

## Cakupan

| Kelompok | URL di bawah `reports/` |
| --- | --- |
| Penjualan | `sales_report`, `sales_detailed_report`, `cancelled_sales_report`, `daily_sales_report` |
| Pembelian | `purchases_report` |
| Produk/kategori | `product_sales_report`, `category_sales_report` |
| Pembayaran/staf | `payment_method_sales_report`, `staff_performance_report`, `busy_hours_report` |
| Keuangan | `laba_rugi`, `profit_transaksi`, `cash_flow`, `cash_in_report`, `cash_out_report`, `cash_sessions`, `affiliate_transactions` |
| Sales/packing | `penjualan_sales`, `penjualan_packing`, `penjualan_office` |
| Grafik | `daily_sales_chart`, `product_sales_chart`, `category_sales_chart`, `payment_type_sales_chart`, `busy_hours_chart`, `comparison_chart`, `profit_vs_expense_chart` |
| Stok | `expiring_batches`, `restock_planner` |

Controller `Report*` memakai koneksi CI4 dan view `app/Views/reports/`. Tidak ada dependensi runtime pada file PHP dari folder `pos`. Query detail penjualan dan rincian sesi dipindahkan dari view ke controller.

## Ekspor dan aksi

- CSV dan XLSX dikembalikan sebagai response unduhan CI4. Beberapa pilihan `.xls` tetap berisi CSV sesuai perilaku aplikasi lama; jangan menganggap seluruh ekspor Excel memakai format workbook yang sama.
- Pilihan `export=pdf` pada laporan lama mempertahankan halaman HTML untuk cetak/Save as PDF melalui browser; bukan generator PDF di server.
- Output ekspor/cetak ditampung dalam response dengan pembersihan buffer pada early return maupun kegagalan.
- Bookmark Penjualan Office diarahkan ke Penjualan Sales sambil mempertahankan query string.
- Penutupan sesi kas memeriksa toko, mengunci sesi, menolak pembaruan ulang sesi tertutup, dan melakukan rollback saat penyimpanan gagal. Aturan siapa yang boleh menutup sesi tetap mengikuti aplikasi lama (pengguna yang sudah login pada toko tersebut).
- Koreksi harga Penjualan Sales tetap memerlukan Super Admin. Detail dikunci dan dibatasi berdasarkan toko; nilai negatif/tidak valid ditolak. Detail dan total header diperbarui dalam satu transaksi. Input angka bertitik desimal tidak dikalikan seratus karena kesalahan parsing pemisah ribuan.

## Verifikasi

- PHP lint: **203 file**, lulus.
- Seluruh PHPUnit suite: **74 tes, 1.097 assertion**, lulus.
- `tests/unit/ReportPortTest.php`: **16 tes, 341 assertion**, mencakup route semua laporan, render halaman, redirect lama, CSV/XLSX/cetak, dispatch berulang, filter toko, formula profit menggunakan fixture, penutupan sesi, koreksi harga, dan rollback.
- Tes memakai koneksi database tiruan. Tidak ada data MySQL aplikasi yang diubah selama pengujian.

Jalankan dari folder `pos_kiosq_id_ci`:

```sh
/Applications/MAMP/bin/php/php8.3.14/bin/php vendor/bin/phpunit --no-coverage
```

## Batas verifikasi

Formula dan pemilihan data laporan umumnya mengikuti versi `pos`, termasuk perbedaan penggunaan harga snapshot/harga produk aktif serta tanggal transaksi/tanggal pencatatan pada laporan yang berbeda. Tahap ini belum menyelaraskan semua definisi akuntansi antar laporan.

Perlu membandingkan hasil dengan aplikasi lama menggunakan data MySQL yang sama: transaksi dibatalkan, retur, paket produk, konversi satuan, perubahan harga historis, potongan marketplace, dan rentang tanggal. Uji grafik, pencetakan, workbook unduhan, penutupan sesi, dan koreksi harga dari browser. Tes tiruan belum membuktikan eksekusi seluruh query pada schema MySQL asli atau rekonsiliasi nilai laporan.

Tahap berikutnya adalah pengaturan. Tools/integrasi, deposit, API/webhook, cron, CRM, dan halaman publik belum termasuk tahap laporan.
