Table now matches the format used elsewhere in the app: one row per
meter (Consumption/Usage/Standing/Extras/VAT/Total/Basis/Period
Estimate) instead of a category rollup, mirroring the utilities app's
own Reports/Estimates pages (basis text, merged extras column).
Adds two charts below the table: total utility cost (this year vs
prior year) and one small per-category consumption chart (this year
vs prior year), both fed by the new /api/internal/trend endpoint,
aligned to the report's own month so paging to an older week shows
the right trailing-12-month window rather than today's.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Follows the same app_settings/DB pattern already used for the
Forecasting integration: utilities_url and utilities_api_key are now
editable from Reports Settings, with env vars kept only as a fallback.
Avoids needing to SSH in and hand-edit .env to authenticate against
the utilities app's internal API.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replaces the Utilities placeholder with a cost-breakdown table by
category (usage/standing/CCL/RAB levy/fixed extras/VAT/total) sourced
from the utilities app's internal API, plus a projected-total note for
the current month. Mirrors the existing forecasting integration
pattern (best-effort fetch, doesn't break the rest of the report on
failure). Also adds the missing UTILITIES_URL/UTILITIES_API_KEY env
vars to docker-compose.yml, needed by both this and the pre-existing
directors-forecast integration.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Same fix as maintenance/room-planner: manifest scope was the app's
own base path instead of "/", and AuthGate unconditionally hard-
navigated window.top to the central /login on session expiry even
when not embedded in the portal iframe — together these dropped an
installed/standalone reports PWA into the portal's framed browser
view instead of staying in its own window.
AuthGate now only bounces to central login when actually embedded
(passing ?from= so it returns here afterwards); standalone or
directly-opened tabs get an in-app login form and never navigate
away. Also wired up the previously-dead inactivity auto-logout timer.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Worksheet save now persists forecast_dry/forecast_wet per day to day_overrides
so the report page always shows the same totals the user saw on the worksheet,
rather than making a second independent forecasting API call that can return
slightly different values.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Checkbox in the header switches between 364-day same-weekday comparison
and same calendar-date last year. Default remains DOW-aligned.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Past dates already excluded from pickup calculation; suppress display to
avoid giving the impression the stored override is still active.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Past dates: zero out pickup (override ignored), use actuals for dry/wet
(fall back to override/forecast only if no actual exists), lock dry/wet
inputs read-only. Pickup + OTB total is now capped at available rooms
so occupancy can't exceed 100%. Totals row also excludes past pickup.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removed display:block override on .wa-charts-row; charts that sit
two-per-row on screen now do the same on paper instead of stacking.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend:
- Always fetch full calendar month (not truncated at week ending)
- Add month_daily[] to response (per-day TY/LY by dept, is_actual flag)
Frontend:
- New 'Sales History' section with:
- Monthly dept line chart: 12-month x-axis, TY vs prior year per dept
(Rooms/Dry/Wet solid, LY dashed — same colour per dept)
- Rolling 12-month average trend (moved from Month Progress)
- Month Progress section gains cumulative line chart:
- X-axis = day of month, 6 lines (3 TY solid + 3 LY dashed)
- TY lines stop at week ending; LY spans full month
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Override overflow:hidden on .page-content and .app-shell so the full
report flows to paper instead of clipping at screen height
- break-inside:avoid on each section so they land whole on a page
- Charts stack vertically on print (full width each) rather than 2-col grid
- Hide sidebar, toolbar; reset backgrounds and shadows for clean output
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Stacked bar chart (Rooms/Dry/Wet) for the previous 12 months and last
12 months side by side, with a reference line marking the boundary.
No extra API calls — data comes from the existing 36-month fetch.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
toISOString() returns UTC, so midnight local in BST (UTC+1) lands on
the previous UTC day, making each arrow step 6 days instead of 7.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace raw monthly totals with a proper rolling 12-month average trend.
Fetches 36 months of data; the 12 display points each show the average
of the 12 months ending on that point (TY) and the same window shifted
back a year (LY), producing a smooth upward trend vs last year.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Full weekly actuals report matching the spreadsheet layout:
- Week summary table (Rooms/Dry/Wet vs Budget vs Last Year vs Last Week)
- Grouped bar chart + dept split pie chart
- 5-week rolling summary table
- Occupancy table by day of week (rooms, occ%, ARR, RevPAR)
- Month progress to date (totals + dept split) with progress bar chart
- 12-month turnover trend line chart by dept
- Utilities placeholder (pending meter readings app)
Budget values come from the forecasting API which distributes monthly
budget proportionally to daily sales — so high-demand weeks (e.g.
Christmas) carry a higher budget share. Gross shown as net × 1.20.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add explicit generic return types to dfGetWorksheet/dfSaveWorksheet/
dfGetReport so TypeScript can infer the response shape in the component.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Embeds a Directors Forecast section in the Reports sidebar (hard-coded
under "Directors Reports"). Worksheet tab: day-by-day OTB grid with
editable pickup rooms, dry/wet overrides, ML suggestion column and live
forecast recalculation. Report tab: forecast vs budget vs last-year
comparison, occupancy summary, weekly revenue bands and snapshot tracking.
Backend: forecast-db.js (read-only pool to forecasting_db), new tables
(forecast_sessions, day_overrides, forecast_snapshots) and full REST
routes under /api/directors-forecast. docker-compose FORECAST_DATABASE_URL
added.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>