▶ 1. Reservation creation + conflict detection ✓ storeReservation redirects to list ✓ no error flashed on valid reservation ✓ reservation row inserted ✓ reservation status is confirmed ✓ total calc = rate × nights (120×2=240) ✓ booking_ref begins with BK- ✓ special_requests saved ✓ invoice auto-created on storeReservation ✓ invoice number prefix INV- ✓ overlap conflict detected and flashed ✓ no extra reservation inserted on conflict ✓ invalid date range rejected ▶ 2. Conflict-detection unit helper ✓ roomHasConflict returns true for overlapping range ✓ roomHasConflict returns false for non-overlapping range ✓ roomHasConflict false for different room ▶ 3. Check-in / Check-out lifecycle ✓ reservation moves to checked_in ✓ room marked occupied ✓ actual_check_in stamped ✓ reservation moves to checked_out ✓ room moves to cleaning on check-out ✓ housekeeping turnover task auto-created on check-out ▶ 4. Payment recording (folio settlement) ✓ payment row inserted ✓ reservation paid total = 100 ✓ invoice paid total = 100 ✓ invoice fully paid ✓ invoice status flips to paid ✓ non-positive payment rejected ▶ 5. Reservation update (edit) ✓ total recalculated on update (150×3) ✓ special_requests updated ▶ 6. Cancellation releases room ✓ reservation marked cancelled ✓ cancelled_at stamped ✓ cancel_reason saved ✓ room released back to vacant ▶ 7. Folio charges + total update ✓ charge row inserted ✓ reservation total updated to 415.5 ▶ 8. Walk-in with conflict & no-conflict cases ✓ walk-in succeeds when no overlap ✓ walk-in guest created ✓ walk-in reservation created in checked_in status ▶ 9. Night audit (with ADR / RevPAR) ✓ night_audit row inserted ✓ ADR & RevPAR columns populated ▶ 10. Guest CRUD + VIP toggle + loyalty ✓ guest stored as VIP ✓ toggleVip flips off ✓ +50 loyalty applied ✓ loyalty floored at 0 (GREATEST) ▶ 11. Room CRUD + status update ✓ storeRoom created room ✓ updateRoomStatus changed status ▶ 12. Key card regeneration ✓ key_card_code regenerated to new value ✓ new key code is non-trivial length ▶ 13. Group bookings create ✓ group stored ▶ 14. CSRF validation ✓ CSRF check rejects empty token (hash_equals) ▶ 15. Routes file & autoload sanity ✓ route GET /pms/dashboard registered ✓ route GET /pms/availability registered ✓ route GET /pms/reservations/export registered ✓ route POST cancel registered ✓ route POST payment registered ✓ route POST charge registered ✓ route GET folio registered ✓ route POST regenerate key registered ✓ route POST toggleVip registered ✓ route POST adjust loyalty registered ▶ 16. View files exist ✓ view exists: pms/dashboard.php ✓ view exists: pms/availability.php ✓ view exists: pms/reservations.php ✓ view exists: pms/reservation_form.php ✓ view exists: pms/reservation_show.php ✓ view exists: pms/folio.php ✓ view exists: pms/calendar.php ✓ view exists: pms/guests.php ✓ view exists: pms/guest_profile.php ✓ view exists: pms/keycards.php ✓ view exists: pms/groups.php ✓ view exists: pms/night_audit.php ✓ view exists: pms/walkin.php ✓ view exists: pms/properties.php ✓ view exists: pms/rooms.php ============================================================ RESULTS: 75 passed, 0 failed ============================================================