Commit graph

18 commits

Author SHA1 Message Date
185b2ec163 Fall back to DOW averages for dry/wet when spend settings not configured
Covers model returns data (covers * spend) but if resos spend settings are
absent the result is zero, which previously bypassed the DOW fallback. Now
fall back to DOW when the covers-based dry or wet is zero.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 18:17:42 +00:00
1fae3ce60b Fix sync not updating arrival/departure dates on re-sync
ON CONFLICT clause was missing arrival_date, departure_date, nights, and
room_number — so early checkouts (where NewBook updates booking_departure
to the actual checkout date) never propagated to the DB columns. Reverts
the COUNT(DISTINCT) workaround since the root cause is now fixed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 17:23:09 +00:00
455396c965 Fix cascading InFailedSQLTransactionError in covers forecast
When forecast_rooms_for_date throws inside covers_model, asyncpg aborts the
whole transaction. The exception was being caught with a warning but no rollback,
so every subsequent query in the same request failed. Added db.rollback() in
all three exception handlers (breakfast pickupv2, dinner pickupv2, per-day loop)
and moved public.py's rollback into a finally block so it always fires even
when covers_model returns normally with a corrupted transaction.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 16:50:09 +00:00
4bad66c91a Fix revenue endpoint 500 — rollback SQLAlchemy session after caught exceptions
When forecast_covers_range or forecast_revenue_for_date throw DB exceptions,
the swallowed exception leaves the async session in an aborted transaction state.
Subsequent queries (DOW averages, per-date accom) then fail with
InFailedSQLTransactionError. Adding db.rollback() in the except blocks
resets the session so the fallback path can continue cleanly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 14:53:54 +00:00
da8c27d0de Add DOW-average fallback for dry/wet forecast when covers data is zero
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-20 12:41:53 +00:00
f0d4fb3beb Use occupied_rooms from occupancy report for past-date OTB, excluding overflow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-20 12:37:28 +00:00
d8ad753a62 Fix available_rooms to use is_included flag from room category settings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-20 12:32:45 +00:00
4e783bd508 Fix available_rooms query: use newbook_occupancy_report_data not daily_occupancy
The table is newbook_occupancy_report_data (per-category rows). Aggregate
SUM(available - maintenance) WHERE category_id != '5' to get the correct
available room count excluding overflow and maintenance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-20 11:32:35 +00:00
e04ae18711 Fix /public/forecast/rooms to use available_rooms excluding overflow
Replace static system_config.total_rooms (80, includes overflow) with
per-day available_rooms from daily_occupancy table. This ensures
occupancy % is calculated against the correct base (non-overflow rooms)
consistent with how the rest of the app reports occupancy. Falls back
to system_config.total_rooms when daily_occupancy has no data for a date.
Also adds available_rooms per-day to the response payload.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-20 10:51:51 +00:00
5fbf155f62 Add weather sync job, API endpoints and settings UI
Fetches daily ERA5 weather from Open-Meteo (no API key).
Configurable location, timezone and sync time via Settings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-13 21:10:03 +00:00
1aa52c563e Add Resos connection status card to Settings — read-only, sourced from central Settings
Replaces the removed API key form with a status card showing whether the
Resos key is configured in the central Settings app, plus a Test Connection
button. Adds back the GET /settings/resos and POST /settings/resos/test
endpoints (now reading from central_settings rather than system_config).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-13 15:02:42 +00:00
3650c92175 Move Resos API key to central Settings service; add sidebar scrollbar styling
Removes the standalone resos_api_key from the forecasting app's own
system_config table. All credential fetches now go through
central_settings.get_resos_credentials() / get_resos_credentials_sync()
which pull from the Settings app (LXC 116) via the internal integration
endpoint — the same pattern already used for NewBook. The Resos API
Config section is removed from the forecasting Settings page; users
manage the key in the central Settings app instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-13 14:35:35 +00:00
76ed477c3a Remove bookability and competitor rates — moved to Rate Monitor app
Deletes bookability.py, competitor_rates.py, Bookability.tsx,
CompetitorRates.tsx. Removes their imports, router mounts, and nav items.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-05 12:14:26 +00:00
1612468122 Bookability: run date refresh synchronously, update timestamp immediately
Backend now awaits the refresh in a thread executor instead of queuing a
background task, so the response returns only after data is written. Frontend
drops the 3s setTimeout and invalidates the cache immediately on success.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-05 10:08:20 +00:00
7223ae9c30 Bookability: show last-updated timestamp per date column
Backend adds valid_from to DateRateInfo and computes date_last_updated dict
(max valid_from across categories per date). Frontend renders it as a small
timestamp below the date in each column header — time only if today, date+time
if older. Full ISO string in title tooltip.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-05 10:03:17 +00:00
3c66e777e4 Patch fetch_room_categories and fetch_gl_accounts to use central NewBook creds
These two endpoints were missed in the central settings migration. They now try
the Settings service first and fall back to app-local system_config.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-05 09:26:49 +00:00
aeb99650bd NewBook credentials from central Settings service
Stack-wide NewBook config lives in the Settings app (LXC 116) and is
fetched live via SETTINGS_URL/SETTINGS_SECRET — same pattern as cashup,
room-planner and maintenance. App-local system_config credentials remain
as a fallback for standalone/dev use. The app's Settings → Newbook page
no longer edits credentials; it points to the central app and keeps
Test Connection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-04 19:36:41 +00:00
75d2c1fa9d Forecasting app: hybrid port to HNF stack
Python FastAPI ML backend kept intact; auth replaced with central hnf_session cookie verification. Frontend rebuilt on React 18 + TS + Vite with stack design system, Plotly charts retained. Shared Postgres via DATABASE_URL; schema applied on startup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-04 18:49:34 +00:00