Future dates: morning-only departure classifies as vacant, not depart

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>
This commit is contained in:
jtricerolph 2026-07-04 18:55:31 +00:00
parent 7fb9e245d9
commit 663eda34af
2 changed files with 9 additions and 4 deletions

View file

@ -52,7 +52,10 @@ export function departingBookingForSite(bookings, siteId, viewDate) {
// Classify a site's booking state for a given view date.
// Returns a rich descriptor used to build the room card.
export function classifyRoom(site, allBookings, viewDate, yesterday, tomorrow) {
// opts.future: viewDate is after the real today. A day-card represents that
// night, so a morning-only departure doesn't occupy it — 'depart' is a live
// operational state (checkout tracking) that only applies to today/past.
export function classifyRoom(site, allBookings, viewDate, yesterday, tomorrow, opts = {}) {
const siteId = String(site.site_id)
// Primary: booking that occupies the room on viewDate (arrival <= viewDate < departure)
@ -100,7 +103,7 @@ export function classifyRoom(site, allBookings, viewDate, yesterday, tomorrow) {
flowType = 'stopover'
}
}
} else if (effectiveDeparting) {
} else if (effectiveDeparting && !opts.future) {
primaryBooking = effectiveDeparting
flowType = 'depart'
}

View file

@ -116,7 +116,8 @@ export async function roomRoutes(app) {
const siteBookings = bookings.filter(matchFn)
const classified = classifyRoom(site, bookings, viewDate, yesterday, tomorrow)
const future = viewDate > new Date().toISOString().slice(0, 10)
const classified = classifyRoom(site, bookings, viewDate, yesterday, tomorrow, { future })
return {
view_date: viewDate, yesterday, tomorrow,
@ -198,13 +199,14 @@ export async function roomRoutes(app) {
}
// Classify each site
const future = viewDate > new Date().toISOString().slice(0, 10)
const rooms = []
for (const site of sites) {
const catId = String(site.site_category_id ?? site.category_id ?? site.category?.id ?? '')
const isExcluded = excludedCategories.includes(catId)
if (isExcluded && hideExcluded) continue
const classified = classifyRoom(site, bookings, viewDate, yesterday, tomorrow)
const classified = classifyRoom(site, bookings, viewDate, yesterday, tomorrow, { future })
// Override category_order with settings value if available
const catOrderOverride = settingsCatOrder[catId]