Files
hotelsync/backend/migrations/015_rental.sql
HotelSync b48e50e62b Rental: connect to API, improve cell UI; remove price from room labels
Backend:
- Migration 015_rental.sql: rental_objects + rental_bookings tables, seed demo data
- New routes: GET/POST/PATCH/DELETE rental-objects and rental-bookings per hotel
- Register rentalRoutes in app.ts

Frontend:
- api.ts: add rental.listObjects, listBookings, createBooking, updateBooking, deleteBooking
- CalendarPage: fetch rental objects + bookings from API instead of mock data
- BookingCalendar: rental cell UI redesigned — colored squares + working hours + time slots (matches design spec)
- BookingCalendar: remove base rate price from desktop room label column (irrelevant with dynamic pricing)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 15:46:01 +03:00

53 lines
3.0 KiB
SQL

-- Rental objects (tennis court, sauna, conference hall, etc.)
CREATE TABLE IF NOT EXISTS rental_objects (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
hotel_id UUID NOT NULL REFERENCES hotels(id) ON DELETE CASCADE,
name TEXT NOT NULL,
icon TEXT NOT NULL DEFAULT '🏨',
color TEXT NOT NULL DEFAULT 'bg-slate-500',
text_color TEXT NOT NULL DEFAULT 'text-slate-700 dark:text-slate-400',
price_per_hour INTEGER NOT NULL DEFAULT 0,
price_per_day INTEGER NOT NULL DEFAULT 0,
open_hour INTEGER NOT NULL DEFAULT 8,
close_hour INTEGER NOT NULL DEFAULT 22,
max_hours_per_slot INTEGER,
buffer_minutes INTEGER NOT NULL DEFAULT 0,
sort_order INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- Rental bookings (hourly / full-day slots)
CREATE TABLE IF NOT EXISTS rental_bookings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
hotel_id UUID NOT NULL REFERENCES hotels(id) ON DELETE CASCADE,
object_id UUID NOT NULL REFERENCES rental_objects(id) ON DELETE CASCADE,
date DATE NOT NULL,
is_full_day BOOLEAN NOT NULL DEFAULT false,
start_hour INTEGER NOT NULL DEFAULT 0,
end_hour INTEGER NOT NULL DEFAULT 0,
guest_name TEXT NOT NULL,
guest_phone TEXT NOT NULL DEFAULT '',
linked_room_id UUID REFERENCES rooms(id),
total_amount INTEGER NOT NULL DEFAULT 0,
paid_amount INTEGER NOT NULL DEFAULT 0,
status TEXT NOT NULL DEFAULT 'confirmed',
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- Seed demo rental objects for all existing hotels (idempotent)
INSERT INTO rental_objects (hotel_id, name, icon, color, text_color, price_per_hour, price_per_day, open_hour, close_hour, sort_order)
SELECT h.id, 'Теннисный корт', '🎾', 'bg-green-500', 'text-green-700 dark:text-green-400', 1500, 8000, 8, 22, 1
FROM hotels h
WHERE NOT EXISTS (SELECT 1 FROM rental_objects ro WHERE ro.hotel_id = h.id AND ro.name = 'Теннисный корт');
INSERT INTO rental_objects (hotel_id, name, icon, color, text_color, price_per_hour, price_per_day, open_hour, close_hour, max_hours_per_slot, sort_order)
SELECT h.id, 'Баня', '🛁', 'bg-orange-500', 'text-orange-700 dark:text-orange-400', 2500, 12000, 10, 23, 4, 2
FROM hotels h
WHERE NOT EXISTS (SELECT 1 FROM rental_objects ro WHERE ro.hotel_id = h.id AND ro.name = 'Баня');
INSERT INTO rental_objects (hotel_id, name, icon, color, text_color, price_per_hour, price_per_day, open_hour, close_hour, sort_order)
SELECT h.id, 'Конференц-зал', '🏛️', 'bg-violet-500', 'text-violet-700 dark:text-violet-400', 3000, 15000, 9, 20, 3
FROM hotels h
WHERE NOT EXISTS (SELECT 1 FROM rental_objects ro WHERE ro.hotel_id = h.id AND ro.name = 'Конференц-зал');