# Phase 3: Rate Management — DONE

**Completed:** 2026-03-16

## Summary

Rate management with seasonal pricing, rate engine service, availability engine, Filament admin CRUD, API endpoints for hotel managers (3 endpoints) and customers (1 endpoint), API resources, form requests, and comprehensive Pest tests.

## Files Created

### Services (2)
- `app/Services/HotelManager/HotelRateService.php` — Core rate engine: getNightlyRate (seasonal > base fallback), calculateStayPrice (multi-night with seasonal boundary support), getNightlyBreakdown (date→price array). Supports 3-tier pricing (base, member, resort).
- `app/Services/HotelManager/HotelAvailabilityService.php` — Availability engine: getAvailability (per-room-type counts), isRoomTypeAvailable (boolean check), getAvailableRooms (collection). Excludes rooms with overlapping CONFIRMED/CHECKED_IN reservations, OUT_OF_ORDER/MAINTENANCE status, and inactive rooms. Respects occupancy limits (adults, children, total).

### Filament Admin (1)
- `app/Filament/Resources/HotelResource/RelationManagers/SeasonalRatesRelationManager.php` — Inline CRUD for seasonal rates on HotelResource with room type selector, season enum, date range with overlap validation, 3-tier pricing, min/max stay, color-coded season badges.

### API Resources (2)
- `app/Http/Resources/HotelManager/HotelSeasonalRateResource.php` — Seasonal rate detail with room type info, pricing, date range.
- `app/Http/Resources/HotelManager/HotelAvailabilityResource.php` — Room type availability with total_price, nightly_breakdown, amenities, photos.

### Form Requests (1)
- `app/Http/Requests/HotelManager/CheckAvailabilityRequest.php` — Validates check_in (date, after_or_equal:today), check_out (date, after:check_in), adults (int ≥ 1), children (int ≥ 0).

### Hotel Manager Controllers (3)
- `app/Http/Controllers/Api/Employee/HotelManager/ListRatesController.php` — GET `/manage/rates` — List all seasonal rates, filterable by room_type_id and season.
- `app/Http/Controllers/Api/Employee/HotelManager/ListRoomTypeRatesController.php` — GET `/manage/room-types/{roomType}/rates` — Rates for a specific room type.
- `app/Http/Controllers/Api/Employee/HotelManager/CheckAvailabilityController.php` — GET `/manage/availability` — Check availability with pricing and nightly breakdown (base prices, no member pricing for manager view).

### Customer Controllers (1)
- `app/Http/Controllers/Api/Hotel/CheckHotelAvailabilityController.php` — GET `/hotels/{hotel}/availability` — Check availability with member-aware pricing. Only returns room types with available rooms.

### Tests (1)
- `tests/Feature/Controllers/HotelManager/RatesTest.php` — 11 tests covering rate listing, filtering, availability counts, reservation conflicts, room status exclusion, occupancy limits, rate engine (seasonal/base/multi-season), and customer member vs non-member pricing.

## Files Modified

- `app/Filament/Resources/HotelResource.php` — Added SeasonalRatesRelationManager to getRelations().
- `routes/api.php` — Added 3 manager routes under `/manage` prefix + 1 customer availability route.

## API Routes

### Hotel Manager (requires `hotel_manager` role + place attachment)
| Method | URL | Controller |
|--------|-----|-----------|
| GET | `/v1/places/{place}/hotels/{hotel}/manage/rates` | ListRatesController |
| GET | `/v1/places/{place}/hotels/{hotel}/manage/room-types/{roomType}/rates` | ListRoomTypeRatesController |
| GET | `/v1/places/{place}/hotels/{hotel}/manage/availability` | CheckAvailabilityController |

### Customer (authenticated users)
| Method | URL | Controller |
|--------|-----|-----------|
| GET | `/v1/places/{place}/hotels/{hotel}/availability` | CheckHotelAvailabilityController |

## Quality Checks

- **Pint:** PASS (0 issues after auto-fix of 1 unused import)
- **PHPStan level 7:** PASS (0 errors)
- **Pest tests:** 43 passing (18 from Phase 1 + 14 from Phase 2 + 11 new)

## Design Decisions

- **Rate resolution priority**: Seasonal rate → room type base price. For member pricing within seasonal rates: resort_money_price → member_money_price → money_price.
- **Multi-season stays**: Each night is independently resolved against seasonal rates, allowing stays that span seasonal boundaries to have mixed rates.
- **Manager vs customer availability**: Manager sees all room types (even those with 0 availability) with base pricing. Customer sees only available room types with member-aware pricing.
- **Date overlap validation**: SeasonalRatesRelationManager validates that date ranges don't overlap for the same room type within the same hotel via custom Closure validation rule.
- **Availability query**: Uses two-pass approach — first finds rooms with overlapping reservations (CONFIRMED/CHECKED_IN), then excludes those plus OUT_OF_ORDER/MAINTENANCE rooms.

## Notes

- No commits created — user will commit manually.
- Swagger annotations present on all 4 new controllers.
