# PMS Module Enhancement — v2 Changelog

This release significantly enhances the **Property Management System (PMS)** module
of `hotel-erpmvc` while preserving the existing project structure, conventions and
coding style (PSR-4 namespaces, PDO/MySQL, Bootstrap 5 views, CSRF-protected forms).

All changes are additive — existing routes, table columns and views remain
backwards-compatible.

---

## ✨ New features

### Reservations
- **Edit existing reservations** — full edit form with date/room/rate/special-request fields.
- **Cancel with reason** — releases the room and stamps `cancelled_at` + `cancel_reason`.
- **Record payments** — multi-payment ledger linked to invoice & reservation; auto-marks invoice as `paid` when settled.
- **Folio line items** — add ad-hoc charges (mini-bar, laundry, restaurant…) that update the reservation total.
- **Printable folio** — clean, print-optimised invoice view (`/pms/reservations/{id}/folio`).
- **Smart filters & search** — filter the reservations list by status, dates, and free-text (ref / name / email).
- **CSV export** — one-click export of the (filtered) reservations list.
- **Booking-reference auto-generation** — `BK-YYYY-####` pattern preserved.
- **Auto-invoice on booking** — `INV-YYYY-#####` created at storeReservation / walk-in.

### Validation & safety
- **Room availability conflict detection** — overlapping reservations are blocked at create *and* edit time.
- **Date-order validation** — check-out must be after check-in.
- **Transactional storeReservation / walk-in / addPayment** — rollback on error.

### PMS dashboard
- New landing page (`/pms` or `/pms/dashboard`) with KPIs:
  arrivals today · departures today · in-house · occupancy % · ADR · RevPAR.
- Live arrivals & departures tables with one-click open.

### Availability matrix
- New view (`/pms/availability`) shows a colour-coded room-by-day grid with selectable date range (1–31 days).

### Guests
- **Create guest** from the Guests list (modal).
- **Edit guest profile** (modal on the profile page).
- **VIP toggle** + **loyalty points adjustment** (with floor at 0).
- **Full-text search** on the guest list.

### Rooms / Key cards
- **Key-card regeneration** (`/pms/keycards/{id}/regenerate`) — secure random 12-hex code.

### Groups
- **Create group bookings** UI added (was list-only before).

### Night audit
- Captures **ADR** and **RevPAR** in addition to occupancy / revenue / no-shows.
- Listing UI shows the new columns.

### Calendar
- Colour-coded by status (confirmed vs. checked-in), weekend columns highlighted, cells link to the underlying reservation.

---

## 🗄 Database changes (idempotent migration)

Run `database/migrations/002_pms_enhance.sql` — fully idempotent (safe to re-run).
The Install wizard now auto-runs all migrations in `database/migrations/*.sql` sorted by filename, so a fresh install picks this up automatically.

| Table | Column / Object | Type |
|---|---|---|
| `reservations` | `cancelled_at`       | `DATETIME NULL` |
| `reservations` | `cancel_reason`      | `VARCHAR(255) NULL` |
| `reservations` | `special_requests`   | `TEXT NULL` |
| `reservations` | `created_by`         | `INT NULL` |
| `night_audits` | `adr`                | `DECIMAL(12,2) DEFAULT 0` |
| `night_audits` | `revpar`             | `DECIMAL(12,2) DEFAULT 0` |
| **new** `reservation_charges` | (full table) | folio line items |
| Index | `idx_res_status` on `reservations(status)` | |
| Index | `idx_res_dates`  on `reservations(room_id, check_in, check_out)` | |

---

## 🗺 New / changed routes (all PMS-scoped)

```
GET   pms                                    -> PmsController@dashboard
GET   pms/dashboard                          -> PmsController@dashboard
GET   pms/reservations/export                -> PmsController@exportReservations  (CSV)
GET   pms/reservations/{id}/edit             -> PmsController@editReservation
POST  pms/reservations/{id}/update           -> PmsController@updateReservation
POST  pms/reservations/{id}/cancel           -> PmsController@cancelReservation
POST  pms/reservations/{id}/payment          -> PmsController@addPayment
POST  pms/reservations/{id}/charge           -> PmsController@addCharge
GET   pms/reservations/{id}/folio            -> PmsController@folio
GET   pms/availability                       -> PmsController@availability
POST  pms/groups/store                       -> PmsController@storeGroup
POST  pms/guests/store                       -> PmsController@storeGuest
POST  pms/guests/{id}/update                 -> PmsController@updateGuest
POST  pms/guests/{id}/vip                    -> PmsController@toggleVip
POST  pms/guests/{id}/loyalty                -> PmsController@adjustLoyalty
POST  pms/keycards/{id}/regenerate           -> PmsController@regenerateKey
```

All existing routes are **unchanged**.

---

## 📂 Files changed / added

### Added
- `app/Views/pms/dashboard.php`
- `app/Views/pms/availability.php`
- `app/Views/pms/folio.php`
- `database/migrations/002_pms_enhance.sql`
- `tests/run_pms_tests.php` — 75-assertion test harness
- `tests/render_views.php`  — view-render smoke test
- `PMS_CHANGELOG.md` (this file)

### Modified
- `app/Controllers/PmsController.php` (rewritten with new actions & helpers)
- `app/Controllers/InstallController.php` (runs *all* migration files in order)
- `app/Views/layouts/app.php` (PMS sub-menu adds *Dashboard* & *Availability*)
- `app/Views/pms/reservations.php` (filters, balance column, edit shortcut, CSV export)
- `app/Views/pms/reservation_form.php` (handles edit mode + special_requests)
- `app/Views/pms/reservation_show.php` (folio charges, payments, cancel / pay / charge modals)
- `app/Views/pms/calendar.php` (colour by status, weekend highlight, clickable cells)
- `app/Views/pms/guests.php` (search + add modal)
- `app/Views/pms/guest_profile.php` (edit modal, VIP toggle, loyalty adjust)
- `app/Views/pms/keycards.php` (regenerate action)
- `app/Views/pms/groups.php` (create modal)
- `app/Views/pms/night_audit.php` (ADR / RevPAR columns)
- `config/routes.php` (new PMS routes)

---

## 🧪 Test results

```text
$ php tests/run_pms_tests.php
RESULTS: 75 passed, 0 failed

$ php tests/render_views.php
Rendered: 15 ok, 0 bad
```

Coverage includes:
1. Reservation create with conflict & date validation
2. Conflict-detection unit helper (overlap edge cases)
3. Check-in / check-out lifecycle + auto housekeeping turnover
4. Payment ledger + invoice status flip + negative-amount rejection
5. Reservation edit with total recalculation
6. Cancellation with reason + room release
7. Folio charges and total update
8. Walk-in flow (with availability check)
9. Night audit ADR & RevPAR persistence
10. Guest CRUD + VIP toggle + loyalty (with floor)
11. Room CRUD + status update
12. Key-card regeneration
13. Group bookings create
14. CSRF helper sanity
15. Routing & autoload sanity (10 new routes registered)
16. All 15 PMS views render without warnings

---

## 🚀 Upgrade instructions

1. **Backup** your database first.
2. Replace files from this patch into your existing install (preserves directory structure).
3. Run the new migration:
   ```bash
   mysql -u <user> -p <db_name> < database/migrations/002_pms_enhance.sql
   ```
   *(Or just run `php` of the Install wizard from step 3 again — it now runs all migrations automatically.)*
4. Clear any opcache: `kill -USR2 $(pidof php-fpm)` (or restart your web server).
5. Visit **`/pms/dashboard`** to see the new landing page.

No data migration is required; existing reservations / guests / rooms continue to work unchanged.
