Matrix: past/sold-out cells show last rate strikethrough, icons at bottom
Sold-out cells: amber (was red), show last known available rate with strikethrough. Past dates: grey, same strikethrough treatment, no eye icon (Booking.com won't serve past availability), history chart still accessible. Date column headers also hide the eye link for past dates. Backend adds a second query returning last_available_rate (most recent available + non-null rate_gross) per hotel+date for the full range. Icons are now 12px and stacked below the rate text in a flex-column cell layout. Price index badge sits between rate and icons. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
1ffda18872
commit
d737940a00
2 changed files with 89 additions and 43 deletions
|
|
@ -671,6 +671,32 @@ async def get_competitor_matrix(
|
|||
'scraped_at': row.scraped_at.isoformat() if row.scraped_at else None,
|
||||
}
|
||||
|
||||
# Last available rate per hotel+date (used for sold-out / past-date display)
|
||||
last_avail_result = await db.execute(
|
||||
text(f"""
|
||||
SELECT DISTINCT ON (r.hotel_id, r.rate_date)
|
||||
r.hotel_id,
|
||||
r.rate_date,
|
||||
r.rate_gross AS last_available_rate
|
||||
FROM booking_com_rates r
|
||||
JOIN booking_com_hotels h ON r.hotel_id = h.id
|
||||
WHERE {tier_filter}
|
||||
AND h.is_active = TRUE
|
||||
AND r.rate_date >= :from_date AND r.rate_date <= :to_date
|
||||
AND r.availability_status = 'available'
|
||||
AND r.rate_gross IS NOT NULL
|
||||
ORDER BY r.hotel_id, r.rate_date, r.scraped_at DESC
|
||||
"""),
|
||||
{'from_date': start, 'to_date': end}
|
||||
)
|
||||
last_avail: Dict[int, Dict[str, float]] = {}
|
||||
for row in last_avail_result.fetchall():
|
||||
last_avail.setdefault(row.hotel_id, {})[row.rate_date.isoformat()] = float(row.last_available_rate)
|
||||
|
||||
for hotel_id, date_map in rates_by_hotel.items():
|
||||
for rate_date, cell in date_map.items():
|
||||
cell['last_available_rate'] = last_avail.get(hotel_id, {}).get(rate_date)
|
||||
|
||||
# Most recent scrape touching each date, across ALL hotels — a partial
|
||||
# scrape may refresh the date without touching the displayed hotels, so
|
||||
# per-cell scraped_at can lag behind this column-level timestamp
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue