# Porting katalog dan jadwal rental publik

Tanggal: 17 Oktober 2026.

## Cakupan selesai

| Sumber `pos/` | Controller CI4 | Route publik |
| --- | --- | --- |
| `store_rental.php` | `PublicRental` | `store_rental`, `store_rental.php` |
| `store_rental_schedule.php` | `PublicRentalSchedule` | `store_rental_schedule`, `store_rental_schedule.php` |

Kedua halaman memakai GET tanpa login kasir. Respons memakai `Cache-Control: no-store`. ID divalidasi sebagai angka positif; parameter berbentuk array/SQL atau ID tidak ditemukan dialihkan ke beranda. Halaman hanya membaca toko dan rental aktif.

Detail rental mempertahankan informasi produk/toko, harga dan satuan, gambar, deskripsi, produk terkait, kalender harian/jam, perhitungan estimasi harga, tautan berbagi/WhatsApp, serta pilihan periode menuju checkout rental. Parameter `product_id` tetap didukung sebagai fallback bila `rental_id` tidak diberikan.

Jadwal toko menampilkan rental aktif dengan informasi satuan, harga, jumlah, dan kalender per produk. Data kalender diambil dari `rental_transactions`, dibatasi ID produk dan toko; transaksi `cancelled`/`rejected` dan periode yang sudah selesai dikecualikan. Kalender merupakan informasi saat halaman dimuat; ketersediaan akhir harus diperiksa kembali oleh checkout/booking di dalam transaksi.

## Penyesuaian

- Kalender publik tidak lagi membaca atau menampilkan nama pelanggan dari transaksi sewa; hanya periode dan label reservasi umum yang dikirim ke browser.
- Query kalender memakai binding ID rental dan toko, termasuk ketika satu toko mempunyai beberapa produk.
- Kesalahan pencatatan pengunjung tidak menghalangi halaman. Kesalahan membaca jadwal menampilkan peringatan; tombol booking detail dinonaktifkan, kalender toko tidak diinisialisasi dan badge ketersediaan menjadi tidak diketahui.
- Data PHP yang dimasukkan ke JavaScript memakai JSON escaping. Handler gambar menggunakan `this.src` agar nama file tidak disisipkan sebagai kode JavaScript.
- Fungsi lama `addToCartProduct()` yang tidak dipakai di halaman rental dihapus. Fungsi tersebut mengirim ID rental ke keranjang produk biasa, padahal kedua tabel mempunyai ID terpisah. Keranjang belanja produk biasa tetap dapat dilihat melalui tombol mengambang.
- Tidak ada reservasi/checkout rental atau pengiriman WhatsApp nyata yang dijalankan pada tahap ini.

## Validasi

- Seluruh suite: **358 tes / 2.458 assertion**, lulus.
- Tambahan **12 tes / 43 assertion** memeriksa route publik, ID rusak/hilang/fallback, pembatasan toko, pengecualian status batal, tidak terbukanya data pelanggan, tracking gagal, render halaman kosong/jam/hari, JSON aman, serta penanganan kegagalan kalender.
- Lint **360 file PHP** bersih; JavaScript kedua view lulus `node --check`.
- Pengujian memakai database tiruan dan render PHP. Belum dilakukan pengujian browser/flatpickr, database aplikasi, atau pemeriksaan ketersediaan dengan koneksi MySQL nyata.

## Sisa porting

Tahap ini menyelesaikan **2 dari 14 file** sebelumnya. Tersisa **12 file utama/publik**:

1. `booking_api.php`
2. `checkout_rental.php`
3. `checkout_rental_otp.php`
4. `checkout_rental_special.php`
5. `checkout_rental_success.php`
6. `forgot_password.php`
7. `order_meja.php`
8. `pricing.php`
9. `register.php`
10. `tracking.php`
11. `upgrade.php`
12. `web1.php`

Tautan `checkout_rental.php` dari detail rental belum mempunyai handler CI; belum dapat digunakan untuk menyelesaikan pemesanan. Berikutnya alur checkout rental/OTP/sukses dan booking khusus. Aplikasi lama menggunakan dua tabel/alur reservasi: `rental_transactions` dan `booking_rentals`; keduanya perlu dicegah saling melewati pemeriksaan ketersediaan ketika booking khusus dipindahkan.

## Status akhir — 17 Oktober 2026

Seluruh file PHP yang tersisa sudah diporting. Sisa terbaru **0**; lihat [PORTING_SELESAI.md](PORTING_SELESAI.md) dan [PORTING_INVENTARIS.md](PORTING_INVENTARIS.md). Angka sisa di atas adalah catatan historis tahap ini.
