From a0874484a326415b1585dceb44cb72aec5d11571 Mon Sep 17 00:00:00 2001 From: jtricerolph Date: Wed, 8 Jul 2026 13:59:05 +0000 Subject: [PATCH] Today/future depart-only rooms show as vacant, not depart MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit '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 --- backend/src/lib/booking-flow.js | 8 ++++---- backend/src/routes/rooms.js | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/backend/src/lib/booking-flow.js b/backend/src/lib/booking-flow.js index f0618b1..e02dd97 100644 --- a/backend/src/lib/booking-flow.js +++ b/backend/src/lib/booking-flow.js @@ -52,9 +52,9 @@ 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. -// 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. +// opts.past: viewDate is strictly before the real today. A day-card represents that +// night, so a morning-only departure doesn't occupy it — 'depart' is a historical +// record that only applies when reviewing past dates. export function classifyRoom(site, allBookings, viewDate, yesterday, tomorrow, opts = {}) { const siteId = String(site.site_id) @@ -110,7 +110,7 @@ export function classifyRoom(site, allBookings, viewDate, yesterday, tomorrow, o flowType = 'stopover' } } - } else if (effectiveDeparting && !opts.future) { + } else if (effectiveDeparting && opts.past) { primaryBooking = effectiveDeparting flowType = 'depart' } diff --git a/backend/src/routes/rooms.js b/backend/src/routes/rooms.js index 3b5f79d..ad999ff 100644 --- a/backend/src/routes/rooms.js +++ b/backend/src/routes/rooms.js @@ -116,8 +116,8 @@ export async function roomRoutes(app) { const siteBookings = bookings.filter(matchFn) - const future = viewDate > new Date().toISOString().slice(0, 10) - const classified = classifyRoom(site, bookings, viewDate, yesterday, tomorrow, { future }) + const past = viewDate < new Date().toISOString().slice(0, 10) + const classified = classifyRoom(site, bookings, viewDate, yesterday, tomorrow, { past }) return { view_date: viewDate, yesterday, tomorrow, @@ -199,14 +199,15 @@ export async function roomRoutes(app) { } // Classify each site - const future = viewDate > new Date().toISOString().slice(0, 10) + const serverToday = new Date().toISOString().slice(0, 10) + const past = viewDate < serverToday 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, { future }) + const classified = classifyRoom(site, bookings, viewDate, yesterday, tomorrow, { past }) // Override category_order with settings value if available const catOrderOverride = settingsCatOrder[catId]