'Depart' flow is now exclusively a past-date historical record. On today
and future dates a room with only a morning checkout and no new arrival
classifies as vacant — the room IS free for tonight regardless of the
11am checkout. The departed booking's status still drives the left bracket
colour and the checkout time still appears in the sliver for late checkouts.
B2B rooms (depart + new arrival on the same day) are unaffected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
bookingsForSiteOnDate uses strict `departure > viewDate`, so a booking
that departed yesterday (departure_date = yesterday) doesn't appear as
prevBooking when computing today's card. prevVacant was therefore true,
causing the vacant card to span left into yesterday's margin — visually
indistinguishable from an ongoing stay.
Fix: check departingBookingForSite(yesterday) as prevDepartedBooking.
Include it in prevVacant guard (prevVacant = !prevBooking && !prevDepartedBooking)
and use its status for previous_status so the correct coloured bracket
appears on the left without the card spanning into yesterday.
Result: day after a checkout shows vacant card with coloured left bracket
(blue = still-arrived, purple = departed in NewBook) but full left border;
consecutive vacant days from the second night onward still span left into
each other correctly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
A day-card represents that night. 'Depart' is a live operational state
(checkout tracking) that only makes sense for today: on a future date the
room's last occupied night is the previous day (shown as Stay), and the
departure morning itself leaves the night vacant. classifyRoom now takes
opts.future — when set, a departing-only room stays 'vacant' (or arrive/B2B
if someone arrives), with the departing booking's coloured sliver on the
left and the late-checkout time still shown in the bracket.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- A vacant room spans into adjacent vacant days (left/right border removed, card extends into the margin) exactly like multi-night bookings
- An occupied room adjacent to a vacant day shows a grey 'vacant' sliver bracket on that side (previously no bracket rendered at all when the neighbouring day was empty)
- previous_status falls back to 'vacant' when nothing occupied yesterday; next_status falls back to 'vacant' when nothing occupies tomorrow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- debug-room now returns full raw NewBook booking objects so all
field names are visible for diagnosis
- guest_name extraction also tries guests[0].firstname+lastname
(original PHP plugin pattern), not just guests[0].guest_name
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SETTINGS_URL is the base host only; routes are prefixed /settings/api.
Was calling /api/internal/... which returned nothing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
global_config lives in settings_db, not room_planner_db. Replace the
broken cross-DB pool query with an HTTP call to the new internal
settings endpoint. Falls back to NewBook order gracefully if settings
service is unavailable or rooms haven't been synced yet.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Flow filter chips are now semantic: Departing = depart|B2B,
Arriving = arrive|B2B, so B2B rooms appear in both chips. Adds
missing Arriving filter.
- Forward → button added to date bar (right of datepicker)
- booking_locked normalised to real boolean — NewBook returns '0'/'1'
strings which were all truthy, causing padlock on every room
- guest_name fallback: also try booking.guest_name (flat field) before
account_for_name in case NewBook omits the guests[] array
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Category ordering on the default view now uses the admin-configured
sort_order from global_config.newbook.rooms rather than the raw
NewBook site_category_order. Falls back to NewBook order if the
settings row is absent. Also overrides category_order on each room.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Settings page: add overflow-y:auto + flex:1 so content scrolls within
page-content (which has overflow:hidden)
- Checkout time: move departure time out of B2B card stats row and into
the left-bracket sliver, matching original plugin behaviour:
- Only shown while prev booking status is still 'arrived' (not yet
checked out); collapses to normal bracket once NewBook flips to
'departed'
- Positioned absolutely over the ::before left bracket area
- Remove the forced 'departed' override on prev_status — let NewBook's
real status drive bracket colour so the sliver shows correctly
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The original WordPress plugin (class-hhdl-ajax.php line 409) uses
list_type='staying', which returns bookings whose stay *overlaps* the
date window (arrival <= period_to AND departure >= period_from).
Using list_type='all' was returning bookings filtered by booking-placed
date (or a flat dump), completely missing tomorrow-arriving bookings
that are needed for right-bracket display. Switching to 'staying' with
the original yesterday→tomorrow window gives 50 bookings vs 89 before,
and correctly includes adjacent-day arrivals.
Verified on dev: room 101 now shows confirmed right-bracket for July 5
arrival, room 102 now correctly classifies as back-to-back.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NewBook API returns category_id on site objects; exclusion check was using
the non-existent site_category_id field so excluded categories config never worked.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extend booking fetch window to day-after-tomorrow so tomorrow-arriving
bookings appear in nextBooking lookups (some NewBook regions exclude
arrivals exactly on period_to date, causing right brackets to not render).
Add booking_site_id fallback in site-ID matching so bookings are found
correctly even when NewBook returns booking_site_id instead of site_id in
the booking object (was causing some rooms to show as vacant).
Remove category debug logging (no longer needed).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
spans_next was using departure > viewDate (today), which made any 1-night
booking extend the card to the right. Fixed to departure > tomorrow so the
card only extends when it's also active tomorrow.
Night counter used Date.parse() on NewBook datetime strings, which browsers
parse as local time and shift off by hours in BST. Replaced with utcDay()
which slices the YYYY-MM-DD prefix and calls Date.UTC() — always correct.
When multiple bookings overlap today, prefer the one arriving today so an
arriving guest takes priority over a stale stopover. Also treat a co-active
non-arriving booking as the B2B departing context.
Force previous-day bracket to show as "departed" (purple) when that booking
departs today, without waiting for NewBook to update its status field.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolve NewBook category fields from site_category_id, category_id, or
category.id (whichever is present) so categories work regardless of which
naming convention the NewBook region uses. Log the first site's keys on
each /api/rooms request to confirm field names in docker compose logs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NewBook returns 412 if task_type is absent. The original dailylist plugin
always passes [-1] as a fallback when no specific types are configured.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NewBook-connected daily housekeeping planner. Replaces the hotelhubmodule-housekeeping-dailylist
WordPress plugin. LXC 120 · 10.10.10.120:3080 · slug: room-planner.
- 3-day booking window (yesterday/today/tomorrow) fetched live from NewBook
- Task completion ticks back to NewBook; room status patches NewBook directly
- 23px border sliver CSS system for adjacent-day booking status
- 3-state filter cycling (off→inclusive→exclusive) for categories and flow types
- Stat filters for outstanding tasks and clean/dirty status
- Rolling 48h activity log with checkout/checkin/status/tasks events
- newbook_pings event bus for future NewBook poller integration
- Room modal with permission-gated guest/rate/notes, task checkboxes, status buttons
- Placeholder sections for future linen-count and routine-tasks modules
- Settings page: task type colours, twin/extra-bed detection, category exclusions
- Mobile-first layout (sidebar desktop, compact top bar mobile)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>