From 46020576f81324e00431e72339d98965c93a8c1e Mon Sep 17 00:00:00 2001 From: jtricerolph Date: Mon, 6 Jul 2026 06:53:44 +0000 Subject: [PATCH] Stats: fall back to all rate plans when no benchmark rate configured Co-Authored-By: Claude Fable 5 --- backend/api/direct.py | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/backend/api/direct.py b/backend/api/direct.py index 8be2cc4..2331aec 100644 --- a/backend/api/direct.py +++ b/backend/api/direct.py @@ -572,21 +572,41 @@ async def hotel_stats(hotel_id: int, user=Depends(get_current_user)): bench_rate = hotel["benchmark_rate"] or "" result = await db.execute( - text("""SELECT DISTINCT ON (stay_date, room_id) - stay_date, room_id, availability, price_incl + text("""SELECT DISTINCT ON (stay_date, room_id, rate_id) + stay_date, room_id, rate_id, availability, price_incl FROM direct_rates - WHERE hotel_id = :hid AND rate_id = :rate + WHERE hotel_id = :hid AND stay_date BETWEEN :fd AND :td - ORDER BY stay_date, room_id, scraped_at DESC"""), - {"hid": hotel_id, "rate": bench_rate, + ORDER BY stay_date, room_id, rate_id, scraped_at DESC"""), + {"hid": hotel_id, "fd": today - timedelta(days=365), "td": today + timedelta(days=365)} ) rows = result.mappings().all() room_labels = hotel["room_labels"] or {} - by_room: dict = {} + + # One entry per (room, date): prefer the benchmark rate plan when scraped, + # otherwise fall back to max availability / cheapest price across plans. + by_room_date: dict = {} for r in rows: - by_room.setdefault(r["room_id"], []).append(r) + entry = by_room_date.setdefault((r["room_id"], r["stay_date"]), { + "stay_date": r["stay_date"], "availability": 0, "price_incl": None, "bench": False, + }) + is_bench = bench_rate and r["rate_id"] == bench_rate + if is_bench: + entry.update({ + "availability": r["availability"] or 0, + "price_incl": r["price_incl"], + "bench": True, + }) + elif not entry["bench"]: + entry["availability"] = max(entry["availability"], r["availability"] or 0) + if r["price_incl"] is not None and (entry["price_incl"] is None or r["price_incl"] < entry["price_incl"]): + entry["price_incl"] = r["price_incl"] + + by_room: dict = {} + for (room_id, _), entry in by_room_date.items(): + by_room.setdefault(room_id, []).append(entry) result_out = {} for room_id, room_stock_val in stock.items():