Files
Hotel-Booking/Backend/seed_rooms.py
Iliyan Angelov a38ab4fa82 updates
2025-11-20 21:06:30 +02:00

318 lines
15 KiB
Python

#!/usr/bin/env python3
"""
Seed script to delete all existing rooms and create 50 sample luxury hotel rooms
"""
import sys
import os
from pathlib import Path
# Add the parent directory to the path so we can import from src
sys.path.insert(0, str(Path(__file__).parent))
from sqlalchemy.orm import Session
from src.config.database import SessionLocal, engine
from src.models.room import Room, RoomStatus
from src.models.room_type import RoomType
from datetime import datetime
import json
import random
def get_db():
"""Get database session"""
db = SessionLocal()
try:
return db
finally:
pass
def seed_rooms(db: Session):
"""Delete all existing rooms and create 50 sample luxury rooms"""
print("=" * 80)
print("SEEDING ROOMS - DELETING EXISTING AND CREATING 50 NEW LUXURY ROOMS")
print("=" * 80)
# Get all room types
room_types = db.query(RoomType).all()
if not room_types:
print("❌ No room types found! Please create room types first.")
return
print(f"\n✓ Found {len(room_types)} room type(s)")
for rt in room_types:
print(f" - {rt.name} (ID: {rt.id}, Base Price: {rt.base_price})")
# Delete all existing rooms
# First, we need to handle related records that reference these rooms
from src.models.booking import Booking
from src.models.review import Review
from src.models.favorite import Favorite
existing_rooms = db.query(Room).all()
if existing_rooms:
print(f"\n🗑️ Deleting {len(existing_rooms)} existing room(s)...")
# Get all room IDs
room_ids = [room.id for room in existing_rooms]
# Delete bookings that reference these rooms
bookings_with_rooms = db.query(Booking).filter(Booking.room_id.in_(room_ids)).all()
if bookings_with_rooms:
print(f" ⚠️ Found {len(bookings_with_rooms)} booking(s) referencing these rooms")
for booking in bookings_with_rooms:
db.delete(booking)
print(f" ✓ Deleted {len(bookings_with_rooms)} booking(s)")
# Delete reviews that reference these rooms
reviews_with_rooms = db.query(Review).filter(Review.room_id.in_(room_ids)).all()
if reviews_with_rooms:
print(f" ⚠️ Found {len(reviews_with_rooms)} review(s) referencing these rooms")
for review in reviews_with_rooms:
db.delete(review)
print(f" ✓ Deleted {len(reviews_with_rooms)} review(s)")
# Delete favorites that reference these rooms
favorites_with_rooms = db.query(Favorite).filter(Favorite.room_id.in_(room_ids)).all()
if favorites_with_rooms:
print(f" ⚠️ Found {len(favorites_with_rooms)} favorite(s) referencing these rooms")
for favorite in favorites_with_rooms:
db.delete(favorite)
print(f" ✓ Deleted {len(favorites_with_rooms)} favorite(s)")
# Now delete the rooms
for room in existing_rooms:
db.delete(room)
db.commit()
print(f"✓ Deleted {len(existing_rooms)} room(s)")
# Luxury room configurations
views = [
"Ocean View", "City View", "Garden View", "Mountain View",
"Pool View", "Beach View", "Panoramic View", "Sea View"
]
room_sizes = [
"35 sqm", "40 sqm", "45 sqm", "50 sqm", "55 sqm",
"60 sqm", "70 sqm", "80 sqm", "90 sqm", "100 sqm",
"120 sqm", "150 sqm", "180 sqm", "200 sqm", "250 sqm"
]
# Real luxury hotel room images from Unsplash (defined once, used for all rooms)
luxury_room_images = [
# Luxury hotel rooms
"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1596394516093-501ba68a0ba6?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1618221195710-dd6b41faaea8?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1566665797739-1674de7a421a?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1200&h=800&fit=crop",
# Suite images
"https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1595576508898-0ad5c879a061?w=1200&h=800&fit=crop",
# Additional luxury rooms
"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1596394516093-501ba68a0ba6?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1618221195710-dd6b41faaea8?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1566665797739-1674de7a421a?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1595576508898-0ad5c879a061?w=1200&h=800&fit=crop",
"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop",
]
# Comprehensive luxury amenities
all_amenities = [
"Free WiFi", "High-Speed Internet", "Smart TV", "Netflix",
"Air Conditioning", "Climate Control", "Private Balcony",
"Ocean View", "City View", "Minibar", "Coffee Maker",
"Espresso Machine", "Refrigerator", "Safe", "Iron & Ironing Board",
"Hair Dryer", "Premium Toiletries", "Bathrobes", "Slippers",
"Work Desk", "Ergonomic Chair", "USB Charging Ports",
"Bluetooth Speaker", "Sound System", "Blackout Curtains",
"Pillow Menu", "Turndown Service", "Room Service", "24/7 Concierge"
]
premium_amenities = [
"Jacuzzi Bathtub", "Steam Shower", "Rain Shower", "Bidet",
"Private Pool", "Outdoor Terrace", "Fireplace", "Wine Cellar",
"Private Bar", "Butler Service", "Private Elevator", "Helipad Access"
]
# Room configurations: (floor_range, room_numbers_per_floor, view, size_range, amenities_count, featured)
room_configs = [
# Standard Rooms (Floors 1-3)
((1, 3), 8, "Garden View", (35, 45), 8, False),
((1, 3), 8, "City View", (40, 50), 9, False),
# Superior Rooms (Floors 4-6)
((4, 6), 6, "City View", (45, 55), 10, False),
((4, 6), 6, "Pool View", (50, 60), 11, True),
# Deluxe Rooms (Floors 7-9)
((7, 9), 5, "Ocean View", (55, 70), 12, True),
((7, 9), 5, "Mountain View", (60, 75), 12, False),
# Executive Suites (Floors 10-12)
((10, 12), 4, "Panoramic View", (80, 100), 14, True),
((10, 12), 4, "Sea View", (90, 110), 15, True),
# Luxury Suites (Floors 13-15)
((13, 15), 3, "Ocean View", (120, 150), 16, True),
((13, 15), 3, "Beach View", (130, 160), 17, True),
# Presidential Suites (Floor 16)
((16, 16), 2, "Panoramic View", (200, 250), 20, True),
]
rooms_created = []
room_counter = 101 # Starting room number
print(f"\n🏨 Creating 50 luxury rooms...\n")
for config in room_configs:
floor_range, rooms_per_floor, view_type, size_range, amenities_count, featured = config
for floor in range(floor_range[0], floor_range[1] + 1):
for _ in range(rooms_per_floor):
if len(rooms_created) >= 50:
break
# Select random room type based on floor
if floor <= 3:
room_type = random.choice([rt for rt in room_types if 'standard' in rt.name.lower() or 'superior' in rt.name.lower()] or room_types)
elif floor <= 6:
room_type = random.choice([rt for rt in room_types if 'superior' in rt.name.lower() or 'deluxe' in rt.name.lower()] or room_types)
elif floor <= 9:
room_type = random.choice([rt for rt in room_types if 'deluxe' in rt.name.lower() or 'executive' in rt.name.lower()] or room_types)
elif floor <= 12:
room_type = random.choice([rt for rt in room_types if 'executive' in rt.name.lower() or 'suite' in rt.name.lower()] or room_types)
else:
room_type = random.choice([rt for rt in room_types if 'suite' in rt.name.lower() or 'presidential' in rt.name.lower()] or room_types)
# If no matching room type, use random
if not room_type:
room_type = random.choice(room_types)
# Calculate price (base price + floor premium + view premium + random variation)
base_price = float(room_type.base_price)
floor_premium = (floor - 1) * 5 # +5 per floor
view_premium = 20 if "Ocean" in view_type or "Sea" in view_type or "Beach" in view_type else 0
view_premium += 15 if "Panoramic" in view_type else 0
view_premium += 10 if "Mountain" in view_type else 0
view_premium += 5 if "Pool" in view_type else 0
# Add random variation (-5% to +10% of base price)
random_variation = base_price * random.uniform(-0.05, 0.10)
# Size premium (larger rooms cost more)
size_min, size_max = size_range
size_premium = (size_min + size_max) / 2 * 0.5 # ~0.5 per sqm
price = base_price + floor_premium + view_premium + random_variation + size_premium
# Ensure minimum price and round to 2 decimal places
price = max(base_price * 0.95, price)
price = round(price, 2)
# Select amenities
selected_amenities = random.sample(all_amenities, min(amenities_count, len(all_amenities)))
if floor >= 13: # Add premium amenities for luxury suites
premium_count = min(2, len(premium_amenities))
selected_amenities.extend(random.sample(premium_amenities, premium_count))
# Room size
size_min, size_max = size_range
room_size = f"{random.randint(size_min, size_max)} sqm"
# Capacity (based on room type, with some variation)
capacity = room_type.capacity
if random.random() > 0.7: # 30% chance to have different capacity
capacity = max(1, capacity + random.randint(-1, 1))
# Room number
room_number = f"{floor}{room_counter % 100:02d}"
room_counter += 1
# Select 3 unique images for each room (ensure we always have images)
# Shuffle the list each time to get different combinations
shuffled_images = luxury_room_images.copy()
random.shuffle(shuffled_images)
image_urls = shuffled_images[:3] # Always take first 3 after shuffle
# Description
descriptions = [
f"Elegantly designed {view_type.lower()} room with modern luxury amenities and breathtaking views.",
f"Spacious {view_type.lower()} accommodation featuring premium furnishings and world-class comfort.",
f"Luxurious {view_type.lower()} room with sophisticated decor and exceptional attention to detail.",
f"Exquisite {view_type.lower()} suite offering unparalleled elegance and personalized service.",
f"Opulent {view_type.lower()} accommodation with bespoke interiors and premium amenities.",
]
description = random.choice(descriptions)
# Status (mostly available, some in maintenance/cleaning)
status_weights = [0.85, 0.05, 0.05, 0.05] # available, occupied, maintenance, cleaning
status = random.choices(
[RoomStatus.available, RoomStatus.occupied, RoomStatus.maintenance, RoomStatus.cleaning],
weights=status_weights
)[0]
# Create room
room = Room(
room_type_id=room_type.id,
room_number=room_number,
floor=floor,
status=status,
price=price,
featured=featured,
capacity=capacity,
room_size=room_size,
view=view_type,
images=json.dumps(image_urls),
amenities=json.dumps(selected_amenities),
description=description
)
db.add(room)
rooms_created.append({
'number': room_number,
'floor': floor,
'type': room_type.name,
'view': view_type,
'price': price
})
print(f" ✓ Created Room {room_number} - Floor {floor}, {room_type.name}, {view_type}, {room_size}, €{price:.2f}")
db.commit()
print(f"\n✅ Successfully created {len(rooms_created)} luxury rooms!")
print(f"\n📊 Summary:")
featured_count = sum(1 for r in rooms_created if any(
config[5] and r['floor'] >= config[0][0] and r['floor'] <= config[0][1]
for config in room_configs
))
print(f" - Featured rooms: {featured_count}")
print(f" - Floors: {min(r['floor'] for r in rooms_created)} - {max(r['floor'] for r in rooms_created)}")
print(f" - Price range: €{min(r['price'] for r in rooms_created):.2f} - €{max(r['price'] for r in rooms_created):.2f}")
print("=" * 80)
if __name__ == "__main__":
db = get_db()
try:
seed_rooms(db)
except Exception as e:
print(f"\n❌ Error: {e}")
import traceback
traceback.print_exc()
db.rollback()
finally:
db.close()