This commit is contained in:
Iliyan Angelov
2025-11-21 15:15:48 +02:00
parent 9a6190e8ef
commit f469cf7806
13 changed files with 129 additions and 88 deletions

View File

@@ -0,0 +1,57 @@
#!/usr/bin/env python3
"""
Script to add the 'accountant' role to the database.
Run this script once to create the accountant role if it doesn't exist.
"""
import sys
from pathlib import Path
# Add the Backend directory to the path
backend_dir = Path(__file__).parent
sys.path.insert(0, str(backend_dir))
from src.config.database import SessionLocal
from src.models.role import Role
def add_accountant_role():
"""Add the accountant role to the database if it doesn't exist."""
db = SessionLocal()
try:
# Check if accountant role already exists
existing_role = db.query(Role).filter(Role.name == 'accountant').first()
if existing_role:
print("✓ Accountant role already exists in the database.")
print(f" Role ID: {existing_role.id}")
print(f" Role Name: {existing_role.name}")
return
# Create the accountant role
accountant_role = Role(
name='accountant',
description='Accountant role with access to financial data, payments, and invoices'
)
db.add(accountant_role)
db.commit()
db.refresh(accountant_role)
print("✓ Accountant role created successfully!")
print(f" Role ID: {accountant_role.id}")
print(f" Role Name: {accountant_role.name}")
print(f" Description: {accountant_role.description}")
except Exception as e:
db.rollback()
print(f"✗ Error creating accountant role: {e}")
sys.exit(1)
finally:
db.close()
if __name__ == '__main__':
print("Adding accountant role to the database...")
print("-" * 50)
add_accountant_role()
print("-" * 50)
print("Done!")

View File

@@ -0,0 +1,201 @@
#!/usr/bin/env python3
import sys
import os
from pathlib import Path
import json
sys.path.insert(0, str(Path(__file__).parent))
from sqlalchemy.orm import Session
from src.config.database import SessionLocal
from src.models.page_content import PageContent, PageType
from datetime import datetime
def get_db():
db = SessionLocal()
try:
return db
finally:
pass
def seed_about_page(db: Session):
print("=" * 80)
print("SEEDING ABOUT PAGE CONTENT")
print("=" * 80)
about_data = {
"title": "About Luxury Hotel",
"subtitle": "Where Excellence Meets Unforgettable Experiences",
"description": "Discover the story behind our commitment to luxury hospitality and exceptional service.",
"story_content": "For over three decades, Luxury Hotel has been a beacon of excellence in the hospitality industry. Founded with a vision to redefine luxury travel, we have grown from a single property to a collection of world-renowned destinations, each offering a unique blend of timeless elegance and modern sophistication. Our journey has been marked by countless awards, memorable moments, and the unwavering trust of our guests who return year after year.",
"mission": "To provide unparalleled luxury hospitality experiences that exceed expectations, creating lasting memories for our guests through exceptional service, attention to detail, and genuine care.",
"vision": "To be recognized as the world's premier luxury hotel brand, setting the standard for excellence in hospitality while maintaining our commitment to sustainability and community engagement.",
"about_hero_image": "https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1920&h=1080&fit=crop",
"values": json.dumps([
{
"icon": "Heart",
"title": "Passion",
"description": "We are passionate about hospitality and dedicated to creating exceptional experiences for every guest."
},
{
"icon": "Award",
"title": "Excellence",
"description": "We strive for excellence in every aspect of our service, from the smallest detail to the grandest gesture."
},
{
"icon": "Shield",
"title": "Integrity",
"description": "We conduct our business with honesty, transparency, and respect for our guests and community."
},
{
"icon": "Users",
"title": "Service",
"description": "Our guests are at the heart of everything we do. Your comfort and satisfaction are our top priorities."
}
]),
"features": json.dumps([
{
"icon": "Star",
"title": "Premium Accommodations",
"description": "Luxuriously appointed rooms and suites designed for ultimate comfort and relaxation."
},
{
"icon": "Clock",
"title": "24/7 Service",
"description": "Round-the-clock concierge and room service to attend to your needs at any time."
},
{
"icon": "Award",
"title": "Award-Winning",
"description": "Recognized for excellence in hospitality and guest satisfaction."
}
]),
"team": json.dumps([
{
"name": "Sarah Johnson",
"role": "General Manager",
"image": "https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=400&h=400&fit=crop",
"bio": "With over 15 years of experience in luxury hospitality, Sarah leads our team with passion and dedication.",
"social_links": {
"linkedin": "https://linkedin.com/in/sarahjohnson",
"twitter": "https://twitter.com/sarahjohnson"
}
},
{
"name": "Michael Chen",
"role": "Head Chef",
"image": "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&h=400&fit=crop",
"bio": "Award-winning chef with expertise in international cuisine, bringing world-class dining experiences to our guests.",
"social_links": {
"linkedin": "https://linkedin.com/in/michaelchen",
"twitter": "https://twitter.com/michaelchen"
}
},
{
"name": "Emily Rodriguez",
"role": "Guest Relations Manager",
"image": "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=400&h=400&fit=crop",
"bio": "Ensuring every guest feels valued and receives personalized attention throughout their stay.",
"social_links": {
"linkedin": "https://linkedin.com/in/emilyrodriguez"
}
}
]),
"timeline": json.dumps([
{
"year": "2010",
"title": "Grand Opening",
"description": "Luxury Hotel opened its doors, welcoming guests to a new standard of luxury hospitality.",
"image": "https://images.unsplash.com/photo-1566073771259-6a8506099945?w=800&h=600&fit=crop"
},
{
"year": "2015",
"title": "First Award",
"description": "Received our first 'Best Luxury Hotel' award, recognizing our commitment to excellence.",
"image": "https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=800&h=600&fit=crop"
},
{
"year": "2018",
"title": "Major Renovation",
"description": "Completed a comprehensive renovation, adding state-of-the-art facilities and expanding our capacity.",
"image": "https://images.unsplash.com/photo-1590490360182-c33d57733427?w=800&h=600&fit=crop"
},
{
"year": "2020",
"title": "Sustainability Initiative",
"description": "Launched our sustainability program, committing to eco-friendly practices and community engagement.",
"image": "https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=800&h=600&fit=crop"
},
{
"year": "2023",
"title": "International Recognition",
"description": "Achieved international recognition as one of the world's top luxury hotels.",
"image": "https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=800&h=600&fit=crop"
}
]),
"achievements": json.dumps([
{
"icon": "Award",
"title": "Best Luxury Hotel 2023",
"description": "Recognized as the best luxury hotel in the region for exceptional service and amenities.",
"year": "2023",
"image": "https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=400&h=300&fit=crop"
},
{
"icon": "Star",
"title": "5-Star Rating",
"description": "Maintained our prestigious 5-star rating for over a decade, a testament to our consistent excellence.",
"year": "2022",
"image": "https://images.unsplash.com/photo-1566073771259-6a8506099945?w=400&h=300&fit=crop"
},
{
"icon": "Award",
"title": "Sustainable Hotel of the Year",
"description": "Awarded for our commitment to environmental sustainability and green practices.",
"year": "2021",
"image": "https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=400&h=300&fit=crop"
},
{
"icon": "Users",
"title": "Guest Satisfaction Excellence",
"description": "Achieved 98% guest satisfaction rate, the highest in our category.",
"year": "2023",
"image": "https://images.unsplash.com/photo-1590490360182-c33d57733427?w=400&h=300&fit=crop"
}
]),
"meta_title": "About Us - Luxury Hotel | Our Story, Mission & Vision",
"meta_description": "Learn about Luxury Hotel's commitment to excellence, our story, values, and the dedicated team that makes every stay unforgettable."
}
existing = db.query(PageContent).filter(PageContent.page_type == PageType.ABOUT).first()
if existing:
for key, value in about_data.items():
setattr(existing, key, value)
existing.updated_at = datetime.utcnow()
print("✓ Updated existing about page content")
else:
new_content = PageContent(
page_type=PageType.ABOUT,
**about_data
)
db.add(new_content)
print("✓ Created new about page content")
db.commit()
print("\n✅ About page content seeded successfully!")
print("=" * 80)
if __name__ == "__main__":
db = get_db()
try:
seed_about_page(db)
except Exception as e:
print(f"\n❌ Error: {e}")
import traceback
traceback.print_exc()
db.rollback()
finally:
db.close()

View File

@@ -0,0 +1,70 @@
import sys
import os
from datetime import datetime, timedelta
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
from sqlalchemy.orm import Session
from src.config.database import SessionLocal
from src.models.banner import Banner
from src.models.system_settings import SystemSettings
from src.models.user import User
def seed_banners(db: Session):
print('Seeding banners...')
admin_user = db.query(User).filter(User.email == 'admin@hotel.com').first()
admin_id = admin_user.id if admin_user else None
existing_banners = db.query(Banner).all()
if existing_banners:
for banner in existing_banners:
db.delete(banner)
db.commit()
print(f' ✓ Removed {len(existing_banners)} existing banner(s)')
banners_data = [{'title': 'Welcome to Unparalleled Luxury', 'description': 'Where timeless elegance meets modern sophistication. Experience the pinnacle of hospitality in our award-winning luxury hotel.', 'image_url': 'https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1920', 'link_url': '/rooms', 'position': 'home', 'display_order': 1, 'is_active': True, 'start_date': datetime.utcnow() - timedelta(days=30), 'end_date': datetime.utcnow() + timedelta(days=365)}, {'title': 'Exclusive Presidential Suites', 'description': 'Indulge in our most opulent accommodations. Spacious suites with panoramic views, private terraces, and personalized butler service.', 'image_url': 'https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1920', 'link_url': '/rooms', 'position': 'home', 'display_order': 2, 'is_active': True, 'start_date': datetime.utcnow() - timedelta(days=7), 'end_date': datetime.utcnow() + timedelta(days=365)}, {'title': 'World-Class Spa & Wellness', 'description': 'Rejuvenate your mind, body, and soul. Our award-winning spa offers bespoke treatments using the finest luxury products.', 'image_url': 'https://images.unsplash.com/photo-1544161515-4ab6ce6db874?w=1920', 'link_url': '/services', 'position': 'home', 'display_order': 3, 'is_active': True, 'start_date': datetime.utcnow() - timedelta(days=1), 'end_date': datetime.utcnow() + timedelta(days=365)}, {'title': 'Michelin-Starred Culinary Excellence', 'description': 'Savor extraordinary flavors crafted by world-renowned chefs. Our fine dining restaurants offer an unforgettable gastronomic journey.', 'image_url': 'https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?w=1920', 'link_url': '/services', 'position': 'home', 'display_order': 4, 'is_active': True, 'start_date': datetime.utcnow(), 'end_date': datetime.utcnow() + timedelta(days=365)}, {'title': 'Private Yacht & Exclusive Experiences', 'description': 'Create unforgettable memories with our curated luxury experiences. From private yacht charters to exclusive cultural tours.', 'image_url': 'https://images.unsplash.com/photo-1544551763-46a013bb70d5?w=1920', 'link_url': '/services', 'position': 'home', 'display_order': 5, 'is_active': True, 'start_date': datetime.utcnow() - timedelta(days=15), 'end_date': datetime.utcnow() + timedelta(days=365)}]
for banner_data in banners_data:
new_banner = Banner(**banner_data)
db.add(new_banner)
print(f' ✓ Created banner: {banner_data['title']}')
db.commit()
print('✓ Banners seeded successfully!\n')
def seed_company_info(db: Session):
print('Seeding company information...')
admin_user = db.query(User).filter(User.email == 'admin@hotel.com').first()
admin_id = admin_user.id if admin_user else None
company_settings = [{'key': 'company_name', 'value': 'Luxury Hotel', 'description': 'Company name displayed throughout the application'}, {'key': 'company_tagline', 'value': 'Experience Unparalleled Elegance', 'description': 'Company tagline or slogan'}, {'key': 'company_logo_url', 'value': '', 'description': 'URL to company logo image (upload via admin dashboard)'}, {'key': 'company_favicon_url', 'value': '', 'description': 'URL to company favicon image (upload via admin dashboard)'}, {'key': 'company_phone', 'value': '+1 (555) 123-4567', 'description': 'Company contact phone number'}, {'key': 'company_email', 'value': 'info@luxuryhotel.com', 'description': 'Company contact email address'}, {'key': 'company_address', 'value': '123 Luxury Avenue, Premium District, City 12345, Country', 'description': 'Company physical address'}, {'key': 'tax_rate', 'value': '10.0', 'description': 'Default tax rate percentage (e.g., 10.0 for 10%)'}, {'key': 'platform_currency', 'value': 'EUR', 'description': 'Platform-wide currency setting for displaying prices'}]
for setting_data in company_settings:
existing = db.query(SystemSettings).filter(SystemSettings.key == setting_data['key']).first()
if existing:
existing.value = setting_data['value']
existing.description = setting_data['description']
if admin_id:
existing.updated_by_id = admin_id
print(f' ✓ Updated setting: {setting_data['key']}')
else:
new_setting = SystemSettings(key=setting_data['key'], value=setting_data['value'], description=setting_data['description'], updated_by_id=admin_id)
db.add(new_setting)
print(f' ✓ Created setting: {setting_data['key']}')
db.commit()
print('✓ Company information seeded successfully!\n')
def main():
db: Session = SessionLocal()
try:
print('=' * 80)
print('SEEDING BANNERS AND COMPANY INFORMATION')
print('=' * 80)
print()
seed_banners(db)
seed_company_info(db)
print('=' * 80)
print('✓ All data seeded successfully!')
print('=' * 80)
except Exception as e:
db.rollback()
print(f'\n✗ Error seeding data: {e}')
import traceback
traceback.print_exc()
raise
finally:
db.close()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,75 @@
import sys
import os
import json
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
from sqlalchemy.orm import Session
from src.config.database import SessionLocal
from src.models.page_content import PageContent, PageType
def seed_homepage_content(db: Session):
existing = db.query(PageContent).filter(PageContent.page_type == PageType.HOME).first()
luxury_features = [{'icon': 'Sparkles', 'title': 'Premium Amenities', 'description': 'World-class facilities designed for your comfort and relaxation'}, {'icon': 'Crown', 'title': 'Royal Service', 'description': 'Dedicated concierge service available 24/7 for all your needs'}, {'icon': 'Award', 'title': 'Award-Winning', 'description': 'Recognized for excellence in hospitality and guest satisfaction'}, {'icon': 'Shield', 'title': 'Secure & Private', 'description': 'Your privacy and security are our top priorities'}, {'icon': 'Heart', 'title': 'Personalized Care', 'description': 'Tailored experiences crafted just for you'}, {'icon': 'Gem', 'title': 'Luxury Design', 'description': 'Elegantly designed spaces with attention to every detail'}]
luxury_gallery = ['https://images.unsplash.com/photo-1566073771259-6a8506099945?w=800', 'https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=800', 'https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=800', 'https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=800', 'https://images.unsplash.com/photo-1590490360182-c33d57733427?w=800', 'https://images.unsplash.com/photo-1551882547-ff40c63fe5fa?w=800']
luxury_testimonials = [{'name': 'Sarah Johnson', 'title': 'Business Executive', 'quote': 'An absolutely stunning experience. The attention to detail and level of service exceeded all expectations.', 'image': 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=200'}, {'name': 'Michael Chen', 'title': 'Travel Enthusiast', 'quote': 'The epitome of luxury. Every moment was perfect, from check-in to check-out.', 'image': 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=200'}, {'name': 'Emma Williams', 'title': 'Luxury Traveler', 'quote': 'This hotel redefines what luxury means. I will definitely return.', 'image': 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=200'}]
luxury_services = [{'icon': 'UtensilsCrossed', 'title': 'Fine Dining', 'description': 'Michelin-starred restaurants offering world-class cuisine', 'image': 'https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?w=600'}, {'icon': 'Wine', 'title': 'Premium Bar', 'description': 'Extensive wine collection and craft cocktails in elegant settings', 'image': 'https://images.unsplash.com/photo-1514362545857-3bc16c4c7d1b?w=600'}, {'icon': 'Dumbbell', 'title': 'Spa & Wellness', 'description': 'Rejuvenating spa treatments and state-of-the-art fitness center', 'image': 'https://images.unsplash.com/photo-1544161515-4ab6ce6db874?w=600'}, {'icon': 'Car', 'title': 'Concierge Services', 'description': 'Personalized assistance for all your travel and entertainment needs', 'image': 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=600'}]
luxury_experiences = [{'icon': 'Sunset', 'title': 'Sunset Rooftop', 'description': 'Breathtaking views and exclusive rooftop experiences', 'image': 'https://images.unsplash.com/photo-1514933651103-005eec06c04b?w=600'}, {'icon': 'Ship', 'title': 'Yacht Excursions', 'description': 'Private yacht charters for unforgettable sea adventures', 'image': 'https://images.unsplash.com/photo-1544551763-46a013bb70d5?w=600'}, {'icon': 'Music', 'title': 'Live Entertainment', 'description': 'World-class performances and exclusive events', 'image': 'https://images.unsplash.com/photo-1470229722913-7c0e2dbbafd3?w=600'}, {'icon': 'Palette', 'title': 'Art & Culture', 'description': 'Curated art collections and cultural experiences', 'image': 'https://images.unsplash.com/photo-1578301978018-3005759f48f7?w=600'}]
awards = [{'icon': 'Trophy', 'title': 'Best Luxury Hotel 2024', 'description': 'Awarded by International Luxury Travel Association', 'image': 'https://images.unsplash.com/photo-1579783902614-a3fb3927b6a5?w=400', 'year': '2024'}, {'icon': 'Star', 'title': '5-Star Excellence', 'description': 'Consistently rated 5 stars by leading travel publications', 'image': 'https://images.unsplash.com/photo-1606761568499-6d2451b23c66?w=400', 'year': '2023'}, {'icon': 'Award', 'title': 'Sustainable Luxury', 'description': 'Recognized for environmental responsibility and sustainability', 'image': 'https://images.unsplash.com/photo-1473341304170-971dccb5ac1e?w=400', 'year': '2024'}]
partners = [{'name': 'Luxury Travel Group', 'logo': 'https://images.unsplash.com/photo-1599305445671-ac291c95aaa9?w=200', 'link': '#'}, {'name': 'Premium Airlines', 'logo': 'https://images.unsplash.com/photo-1436491865332-7a61a109cc05?w=200', 'link': '#'}, {'name': 'Exclusive Events', 'logo': 'https://images.unsplash.com/photo-1511578314322-379afb476865?w=200', 'link': '#'}, {'name': 'Fine Dining Network', 'logo': 'https://images.unsplash.com/photo-1555396273-367ea4eb4db5?w=200', 'link': '#'}]
stats = [{'icon': 'Users', 'number': '50,000+', 'label': 'Happy Guests'}, {'icon': 'Award', 'number': '25+', 'label': 'Awards Won'}, {'icon': 'Star', 'number': '4.9', 'label': 'Average Rating'}, {'icon': 'Globe', 'number': '100+', 'label': 'Countries Served'}]
amenities = [{'icon': 'Wifi', 'title': 'High-Speed WiFi', 'description': 'Complimentary high-speed internet throughout the property', 'image': ''}, {'icon': 'Coffee', 'title': '24/7 Room Service', 'description': 'Round-the-clock dining and beverage service', 'image': ''}, {'icon': 'Car', 'title': 'Valet Parking', 'description': 'Complimentary valet parking for all guests', 'image': ''}, {'icon': 'Plane', 'title': 'Airport Transfer', 'description': 'Luxury airport transfer service available', 'image': ''}]
testimonials = [{'name': 'Robert Martinez', 'role': 'CEO, Tech Corp', 'image': 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=200', 'rating': 5, 'comment': 'Exceptional service and attention to detail. The staff went above and beyond to make our stay memorable.'}, {'name': 'Lisa Anderson', 'role': 'Travel Blogger', 'image': 'https://images.unsplash.com/photo-1487412720507-e7ab37603c6f?w=200', 'rating': 5, 'comment': "The most luxurious hotel experience I've ever had. Every detail was perfect."}, {'name': 'David Thompson', 'role': 'Investment Banker', 'image': 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=200', 'rating': 5, 'comment': 'Outstanding facilities and impeccable service. Highly recommend for business travelers.'}]
gallery_images = ['https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=800', 'https://images.unsplash.com/photo-1590490360182-c33d57733427?w=800', 'https://images.unsplash.com/photo-1551882547-ff40c63fe5fa?w=800', 'https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=800', 'https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=800', 'https://images.unsplash.com/photo-1566073771259-6a8506099945?w=800']
homepage_data = {'page_type': PageType.HOME, 'title': 'Luxury Hotel - Experience Unparalleled Elegance', 'subtitle': 'Where timeless luxury meets modern sophistication', 'description': 'Discover a world of refined elegance and exceptional service', 'hero_title': 'Welcome to Luxury', 'hero_subtitle': 'Experience the pinnacle of hospitality', 'hero_image': 'https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200', 'luxury_section_title': 'Experience Unparalleled Luxury', 'luxury_section_subtitle': 'Where elegance meets comfort in every detail', 'luxury_section_image': 'https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=1200', 'luxury_features': json.dumps(luxury_features), 'luxury_gallery_section_title': 'Our Luxury Gallery', 'luxury_gallery_section_subtitle': 'A glimpse into our world of elegance', 'luxury_gallery': json.dumps(luxury_gallery), 'luxury_testimonials_section_title': 'What Our Guests Say', 'luxury_testimonials_section_subtitle': 'Testimonials from our valued guests', 'luxury_testimonials': json.dumps(luxury_testimonials), 'luxury_services_section_title': 'Premium Services', 'luxury_services_section_subtitle': 'Indulge in our world-class amenities', 'luxury_services': json.dumps(luxury_services), 'luxury_experiences_section_title': 'Exclusive Experiences', 'luxury_experiences_section_subtitle': 'Create unforgettable memories', 'luxury_experiences': json.dumps(luxury_experiences), 'awards_section_title': 'Awards & Recognition', 'awards_section_subtitle': 'Recognized for excellence worldwide', 'awards': json.dumps(awards), 'partners_section_title': 'Our Partners', 'partners_section_subtitle': 'Trusted by leading brands', 'partners': json.dumps(partners), 'amenities_section_title': 'Premium Amenities', 'amenities_section_subtitle': 'Everything you need for a perfect stay', 'amenities': json.dumps(amenities), 'testimonials_section_title': 'Guest Reviews', 'testimonials_section_subtitle': 'Hear from our satisfied guests', 'testimonials': json.dumps(testimonials), 'gallery_section_title': 'Photo Gallery', 'gallery_section_subtitle': 'Explore our beautiful spaces', 'gallery_images': json.dumps(gallery_images), 'about_preview_title': 'About Our Luxury Hotel', 'about_preview_subtitle': 'A legacy of excellence', 'about_preview_content': 'Discover a world of refined elegance and exceptional service. Our hotel combines timeless luxury with modern amenities to create an unforgettable experience. With over 50,000 satisfied guests and numerous awards, we continue to set the standard for luxury hospitality.', 'about_preview_image': 'https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=800', 'stats': json.dumps(stats), 'cta_title': 'Ready to Experience Luxury?', 'cta_subtitle': 'Book your stay today and discover the difference', 'cta_button_text': 'Book Now', 'cta_button_link': '/rooms', 'cta_image': 'https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1200', 'is_active': True}
if existing:
for key, value in homepage_data.items():
if key != 'page_type':
setattr(existing, key, value)
print('✓ Updated existing homepage content')
else:
new_content = PageContent(**homepage_data)
db.add(new_content)
print('✓ Created new homepage content')
db.commit()
def seed_footer_content(db: Session):
existing = db.query(PageContent).filter(PageContent.page_type == PageType.FOOTER).first()
contact_info = {'phone': '+1 (555) 123-4567', 'email': 'info@luxuryhotel.com', 'address': '123 Luxury Avenue, Premium District, City 12345'}
social_links = {'facebook': 'https://facebook.com/luxuryhotel', 'twitter': 'https://twitter.com/luxuryhotel', 'instagram': 'https://instagram.com/luxuryhotel', 'linkedin': 'https://linkedin.com/company/luxuryhotel', 'youtube': 'https://youtube.com/luxuryhotel'}
footer_links = {'quick_links': [{'label': 'Home', 'url': '/'}, {'label': 'Rooms & Suites', 'url': '/rooms'}, {'label': 'About Us', 'url': '/about'}, {'label': 'Contact', 'url': '/contact'}, {'label': 'Gallery', 'url': '/gallery'}], 'support_links': [{'label': 'FAQ', 'url': '/faq'}, {'label': 'Privacy Policy', 'url': '/privacy'}, {'label': 'Terms of Service', 'url': '/terms'}, {'label': 'Cancellation Policy', 'url': '/cancellation'}, {'label': 'Accessibility', 'url': '/accessibility'}]}
badges = [{'text': '5-Star Rated', 'icon': 'Star'}, {'text': 'Award Winning', 'icon': 'Award'}, {'text': 'Eco Certified', 'icon': 'Leaf'}, {'text': 'Luxury Collection', 'icon': 'Crown'}]
footer_data = {'page_type': PageType.FOOTER, 'title': 'Luxury Hotel', 'subtitle': 'Experience Unparalleled Elegance', 'description': 'Your gateway to luxury hospitality and exceptional service', 'contact_info': json.dumps(contact_info), 'social_links': json.dumps(social_links), 'footer_links': json.dumps(footer_links), 'badges': json.dumps(badges), 'copyright_text': '© {YEAR} Luxury Hotel. All rights reserved.', 'is_active': True}
if existing:
for key, value in footer_data.items():
if key != 'page_type':
setattr(existing, key, value)
print('✓ Updated existing footer content')
else:
new_content = PageContent(**footer_data)
db.add(new_content)
print('✓ Created new footer content')
db.commit()
def main():
db: Session = SessionLocal()
try:
print('=' * 80)
print('SEEDING HOMEPAGE AND FOOTER CONTENT')
print('=' * 80)
print()
print('Seeding homepage content...')
seed_homepage_content(db)
print('\nSeeding footer content...')
seed_footer_content(db)
print('\n' + '=' * 80)
print('✓ All content seeded successfully!')
print('=' * 80)
except Exception as e:
db.rollback()
print(f'\n✗ Error seeding content: {e}')
import traceback
traceback.print_exc()
raise
finally:
db.close()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,156 @@
import sys
import os
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent))
from sqlalchemy.orm import Session
from src.config.database import SessionLocal
from src.models.role import Role
from src.models.room_type import RoomType
from src.models.user import User
import bcrypt
from datetime import datetime
def get_db():
db = SessionLocal()
try:
return db
finally:
pass
def seed_roles(db: Session):
print('=' * 80)
print('SEEDING ROLES')
print('=' * 80)
roles_data = [
{'name': 'admin', 'description': 'Administrator with full access'},
{'name': 'staff', 'description': 'Staff member with limited admin access'},
{'name': 'customer', 'description': 'Regular customer'},
{'name': 'accountant', 'description': 'Accountant role with access to financial data, payments, and invoices'}
]
for role_data in roles_data:
existing = db.query(Role).filter(Role.name == role_data['name']).first()
if existing:
print(f' ✓ Role "{role_data["name"]}" already exists')
else:
role = Role(**role_data)
db.add(role)
print(f' ✓ Created role: {role_data["name"]}')
db.commit()
print('✓ Roles seeded successfully!\n')
def seed_room_types(db: Session):
print('=' * 80)
print('SEEDING ROOM TYPES')
print('=' * 80)
room_types_data = [
{
'name': 'Standard Room',
'description': 'Comfortable and well-appointed standard accommodation',
'base_price': 150.00,
'capacity': 2,
'amenities': ['Free WiFi', 'Air Conditioning', 'TV', 'Minibar', 'Safe']
},
{
'name': 'Superior Room',
'description': 'Spacious room with enhanced amenities and better views',
'base_price': 200.00,
'capacity': 2,
'amenities': ['Free WiFi', 'Air Conditioning', 'Smart TV', 'Minibar', 'Safe', 'Coffee Maker']
},
{
'name': 'Deluxe Room',
'description': 'Luxurious room with premium furnishings and amenities',
'base_price': 280.00,
'capacity': 3,
'amenities': ['Free WiFi', 'Air Conditioning', 'Smart TV', 'Netflix', 'Minibar', 'Safe', 'Coffee Maker', 'Premium Toiletries']
},
{
'name': 'Executive Suite',
'description': 'Elegant suite with separate living area and premium amenities',
'base_price': 400.00,
'capacity': 4,
'amenities': ['Free WiFi', 'Air Conditioning', 'Smart TV', 'Netflix', 'Minibar', 'Safe', 'Espresso Machine', 'Premium Toiletries', 'Bathrobes', 'Work Desk']
},
{
'name': 'Presidential Suite',
'description': 'The ultimate in luxury with expansive space and exclusive amenities',
'base_price': 800.00,
'capacity': 6,
'amenities': ['Free WiFi', 'Air Conditioning', 'Smart TV', 'Netflix', 'Private Bar', 'Jacuzzi', 'Butler Service', 'Premium Toiletries', 'Bathrobes', 'Private Terrace']
}
]
import json
for rt_data in room_types_data:
existing = db.query(RoomType).filter(RoomType.name == rt_data['name']).first()
if existing:
print(f' ✓ Room type "{rt_data["name"]}" already exists')
else:
amenities = rt_data.pop('amenities')
room_type = RoomType(**rt_data, amenities=json.dumps(amenities))
db.add(room_type)
print(f' ✓ Created room type: {rt_data["name"]} (€{rt_data["base_price"]:.2f}/night)')
db.commit()
print('✓ Room types seeded successfully!\n')
def seed_admin_user(db: Session):
print('=' * 80)
print('SEEDING ADMIN USER')
print('=' * 80)
admin_role = db.query(Role).filter(Role.name == 'admin').first()
if not admin_role:
print(' ❌ Admin role not found! Please seed roles first.')
return
admin_email = 'admin@hotel.com'
existing_admin = db.query(User).filter(User.email == admin_email).first()
if existing_admin:
print(f' ✓ Admin user "{admin_email}" already exists')
else:
password = 'admin123' # Default password - should be changed in production
password_bytes = password.encode('utf-8')
salt = bcrypt.gensalt()
hashed_password = bcrypt.hashpw(password_bytes, salt).decode('utf-8')
admin_user = User(
email=admin_email,
password=hashed_password,
full_name='Administrator',
role_id=admin_role.id,
is_active=True,
currency='EUR'
)
db.add(admin_user)
db.commit()
print(f' ✓ Created admin user: {admin_email}')
print(f' ⚠️ Default password: admin123 (please change in production!)')
print('✓ Admin user seeded successfully!\n')
def main():
db = get_db()
try:
seed_roles(db)
seed_room_types(db)
seed_admin_user(db)
print('=' * 80)
print('✅ Initial data seeding completed successfully!')
print('=' * 80)
except Exception as e:
print(f'\n❌ Error: {e}')
import traceback
traceback.print_exc()
db.rollback()
finally:
db.close()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,42 @@
import sys
import os
import json
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
from sqlalchemy.orm import Session
from src.config.database import SessionLocal, engine
from src.models.page_content import PageContent
from src.models.user import User
def seed_luxury_content():
db: Session = SessionLocal()
try:
existing = db.query(PageContent).filter(PageContent.page_type == 'home').first()
luxury_features = [{'icon': 'Sparkles', 'title': 'Premium Amenities', 'description': 'World-class facilities designed for your comfort and relaxation'}, {'icon': 'Crown', 'title': 'Royal Service', 'description': 'Dedicated concierge service available 24/7 for all your needs'}, {'icon': 'Award', 'title': 'Award-Winning', 'description': 'Recognized for excellence in hospitality and guest satisfaction'}, {'icon': 'Shield', 'title': 'Secure & Private', 'description': 'Your privacy and security are our top priorities'}, {'icon': 'Heart', 'title': 'Personalized Care', 'description': 'Tailored experiences crafted just for you'}, {'icon': 'Gem', 'title': 'Luxury Design', 'description': 'Elegantly designed spaces with attention to every detail'}]
luxury_testimonials = [{'name': 'Sarah Johnson', 'title': 'Business Executive', 'quote': 'An absolutely stunning experience. The attention to detail and level of service exceeded all expectations.', 'image': ''}, {'name': 'Michael Chen', 'title': 'Travel Enthusiast', 'quote': 'The epitome of luxury. Every moment was perfect, from check-in to check-out.', 'image': ''}, {'name': 'Emma Williams', 'title': 'Luxury Traveler', 'quote': 'This hotel redefines what luxury means. I will definitely return.', 'image': ''}]
if existing:
existing.luxury_section_title = 'Experience Unparalleled Luxury'
existing.luxury_section_subtitle = 'Where elegance meets comfort in every detail'
existing.luxury_section_image = None
existing.luxury_features = json.dumps(luxury_features)
existing.luxury_gallery = json.dumps([])
existing.luxury_testimonials = json.dumps(luxury_testimonials)
existing.about_preview_title = 'About Our Luxury Hotel'
existing.about_preview_content = 'Discover a world of refined elegance and exceptional service. Our hotel combines timeless luxury with modern amenities to create an unforgettable experience.'
existing.about_preview_image = None
print('✓ Updated existing home page content with luxury sections')
else:
new_content = PageContent(page_type='home', luxury_section_title='Experience Unparalleled Luxury', luxury_section_subtitle='Where elegance meets comfort in every detail', luxury_section_image=None, luxury_features=json.dumps(luxury_features), luxury_gallery=json.dumps([]), luxury_testimonials=json.dumps(luxury_testimonials), about_preview_title='About Our Luxury Hotel', about_preview_content='Discover a world of refined elegance and exceptional service. Our hotel combines timeless luxury with modern amenities to create an unforgettable experience.', about_preview_image=None, is_active=True)
db.add(new_content)
print('✓ Created new home page content with luxury sections')
db.commit()
print('✓ Luxury content seeded successfully!')
except Exception as e:
db.rollback()
print(f'✗ Error seeding luxury content: {e}')
raise
finally:
db.close()
if __name__ == '__main__':
print('Seeding luxury content...')
seed_luxury_content()
print('Done!')

View File

@@ -0,0 +1,517 @@
#!/usr/bin/env python3
import sys
import os
from pathlib import Path
import json
sys.path.insert(0, str(Path(__file__).parent))
from sqlalchemy.orm import Session
from src.config.database import SessionLocal
from src.models.page_content import PageContent, PageType
from datetime import datetime
def get_db():
db = SessionLocal()
try:
return db
finally:
pass
def seed_privacy_policy(db: Session):
print("=" * 80)
print("SEEDING PRIVACY POLICY PAGE CONTENT")
print("=" * 80)
privacy_content = """
<h2>Introduction</h2>
<p>At our hotel, we are committed to protecting your privacy and ensuring the security of your personal information. This Privacy Policy explains how we collect, use, disclose, and safeguard your information when you visit our website or use our services.</p>
<h2>Information We Collect</h2>
<p>We collect information that you provide directly to us, including:</p>
<ul>
<li>Personal identification information (name, email address, phone number)</li>
<li>Payment information (credit card details, billing address)</li>
<li>Booking and reservation details</li>
<li>Preferences and special requests</li>
</ul>
<h2>How We Use Your Information</h2>
<p>We use the information we collect to:</p>
<ul>
<li>Process and manage your bookings and reservations</li>
<li>Communicate with you about your bookings and our services</li>
<li>Improve our services and customer experience</li>
<li>Send you promotional materials (with your consent)</li>
<li>Comply with legal obligations</li>
</ul>
<h2>Data Security</h2>
<p>We implement appropriate technical and organizational measures to protect your personal information against unauthorized access, alteration, disclosure, or destruction.</p>
<h2>Your Rights</h2>
<p>You have the right to:</p>
<ul>
<li>Access your personal information</li>
<li>Correct inaccurate information</li>
<li>Request deletion of your information</li>
<li>Object to processing of your information</li>
<li>Data portability</li>
</ul>
<h2>Contact Us</h2>
<p>If you have any questions about this Privacy Policy, please contact us at privacy@hotel.com.</p>
<p><strong>Last updated:</strong> """ + datetime.now().strftime("%B %d, %Y") + """</p>
"""
privacy_data = {
"title": "Privacy Policy",
"subtitle": "Your privacy is important to us",
"description": "Learn how we collect, use, and protect your personal information.",
"content": privacy_content,
"meta_title": "Privacy Policy - Luxury Hotel | Data Protection & Privacy",
"meta_description": "Read our privacy policy to understand how we collect, use, and protect your personal information when you use our hotel booking services."
}
existing = db.query(PageContent).filter(PageContent.page_type == PageType.PRIVACY).first()
if existing:
for key, value in privacy_data.items():
setattr(existing, key, value)
existing.updated_at = datetime.utcnow()
print("✓ Updated existing privacy policy page content")
else:
new_content = PageContent(
page_type=PageType.PRIVACY,
**privacy_data
)
db.add(new_content)
print("✓ Created new privacy policy page content")
db.commit()
print("\n✅ Privacy policy page content seeded successfully!")
print("=" * 80)
def seed_terms_conditions(db: Session):
print("=" * 80)
print("SEEDING TERMS & CONDITIONS PAGE CONTENT")
print("=" * 80)
terms_content = """
<h2>Agreement to Terms</h2>
<p>By accessing and using our hotel's website and services, you accept and agree to be bound by the terms and provision of this agreement.</p>
<h2>Booking Terms</h2>
<p>When making a reservation with us, you agree to:</p>
<ul>
<li>Provide accurate and complete information</li>
<li>Be responsible for all charges incurred during your stay</li>
<li>Comply with hotel policies and regulations</li>
<li>Respect other guests and hotel property</li>
</ul>
<h2>Payment Terms</h2>
<p>Payment terms include:</p>
<ul>
<li>A 20% deposit is required to secure your booking</li>
<li>The remaining balance is due on arrival at the hotel</li>
<li>All prices are subject to applicable taxes and fees</li>
<li>Payment methods accepted: credit cards, debit cards, and cash</li>
</ul>
<h2>Cancellation Policy</h2>
<p>Our cancellation policy is as follows:</p>
<ul>
<li>Cancellations made 48 hours or more before check-in: Full refund of deposit</li>
<li>Cancellations made less than 48 hours before check-in: Deposit is non-refundable</li>
<li>No-shows: Full booking amount is charged</li>
</ul>
<h2>Check-in and Check-out</h2>
<p>Standard check-in time is 3:00 PM and check-out time is 11:00 AM. Early check-in and late check-out may be available upon request and subject to availability.</p>
<h2>Guest Responsibilities</h2>
<p>Guests are responsible for:</p>
<ul>
<li>Any damage to hotel property</li>
<li>Compliance with all hotel rules and regulations</li>
<li>Respecting quiet hours and other guests</li>
<li>Proper use of hotel facilities</li>
</ul>
<h2>Limitation of Liability</h2>
<p>The hotel shall not be liable for any loss, damage, or injury to persons or property during your stay, except where such loss, damage, or injury is caused by our negligence.</p>
<h2>Modifications to Terms</h2>
<p>We reserve the right to modify these terms at any time. Changes will be effective immediately upon posting on our website.</p>
<h2>Contact Information</h2>
<p>For questions about these terms, please contact us at legal@hotel.com.</p>
<p><strong>Last updated:</strong> """ + datetime.now().strftime("%B %d, %Y") + """</p>
"""
terms_data = {
"title": "Terms & Conditions",
"subtitle": "Please read these terms carefully",
"description": "Terms and conditions governing your use of our hotel booking services.",
"content": terms_content,
"meta_title": "Terms & Conditions - Luxury Hotel | Booking Terms & Policies",
"meta_description": "Read our terms and conditions to understand the rules and policies governing your bookings and stay at our luxury hotel."
}
existing = db.query(PageContent).filter(PageContent.page_type == PageType.TERMS).first()
if existing:
for key, value in terms_data.items():
setattr(existing, key, value)
existing.updated_at = datetime.utcnow()
print("✓ Updated existing terms & conditions page content")
else:
new_content = PageContent(
page_type=PageType.TERMS,
**terms_data
)
db.add(new_content)
print("✓ Created new terms & conditions page content")
db.commit()
print("\n✅ Terms & conditions page content seeded successfully!")
print("=" * 80)
def seed_refunds_policy(db: Session):
print("=" * 80)
print("SEEDING REFUNDS POLICY PAGE CONTENT")
print("=" * 80)
refunds_content = """
<h2>Refund Policy Overview</h2>
<p>At our hotel, we understand that plans can change. This policy outlines our refund procedures and timelines for various scenarios.</p>
<h2>Booking Cancellations</h2>
<p>Refunds for cancelled bookings are processed as follows:</p>
<ul>
<li><strong>More than 48 hours before check-in:</strong> Full refund of the 20% deposit</li>
<li><strong>48 hours or less before check-in:</strong> Deposit is non-refundable</li>
<li><strong>No-show:</strong> No refund will be issued</li>
</ul>
<h2>Early Check-out</h2>
<p>If you check out earlier than your reserved departure date:</p>
<ul>
<li>You will be charged for the nights you stayed</li>
<li>The remaining 80% balance for unused nights will be refunded</li>
<li>Refunds are processed within 5-7 business days</li>
</ul>
<h2>Service Issues</h2>
<p>If you experience service issues during your stay:</p>
<ul>
<li>Please report the issue immediately to our front desk</li>
<li>We will make every effort to resolve the issue promptly</li>
<li>If the issue cannot be resolved, partial or full refunds may be considered on a case-by-case basis</li>
</ul>
<h2>Refund Processing Time</h2>
<p>Refunds are typically processed within:</p>
<ul>
<li><strong>Credit/Debit Cards:</strong> 5-7 business days</li>
<li><strong>Bank Transfers:</strong> 7-10 business days</li>
<li><strong>Cash Payments:</strong> Refunds will be processed via bank transfer</li>
</ul>
<h2>Refund Method</h2>
<p>Refunds will be issued to the original payment method used for the booking. If the original payment method is no longer available, please contact us to arrange an alternative refund method.</p>
<h2>Non-Refundable Bookings</h2>
<p>Some special offers or promotional rates may be non-refundable. This will be clearly stated at the time of booking.</p>
<h2>Force Majeure</h2>
<p>In cases of force majeure (natural disasters, pandemics, government restrictions, etc.), we will work with you to reschedule your booking or provide appropriate refunds based on the circumstances.</p>
<h2>Dispute Resolution</h2>
<p>If you have concerns about a refund decision, please contact our customer service team. We are committed to resolving all disputes fairly and promptly.</p>
<h2>Contact Us</h2>
<p>For refund inquiries, please contact us at refunds@hotel.com or call our customer service line.</p>
<p><strong>Last updated:</strong> """ + datetime.now().strftime("%B %d, %Y") + """</p>
"""
refunds_data = {
"title": "Refunds Policy",
"subtitle": "Our commitment to fair refunds",
"description": "Learn about our refund policies and procedures for bookings and cancellations.",
"content": refunds_content,
"meta_title": "Refunds Policy - Luxury Hotel | Cancellation & Refund Terms",
"meta_description": "Understand our refund policy, including cancellation terms, processing times, and how to request refunds for your hotel bookings."
}
existing = db.query(PageContent).filter(PageContent.page_type == PageType.REFUNDS).first()
if existing:
for key, value in refunds_data.items():
setattr(existing, key, value)
existing.updated_at = datetime.utcnow()
print("✓ Updated existing refunds policy page content")
else:
new_content = PageContent(
page_type=PageType.REFUNDS,
**refunds_data
)
db.add(new_content)
print("✓ Created new refunds policy page content")
db.commit()
print("\n✅ Refunds policy page content seeded successfully!")
print("=" * 80)
def seed_cancellation_policy(db: Session):
print("=" * 80)
print("SEEDING CANCELLATION POLICY PAGE CONTENT")
print("=" * 80)
cancellation_content = """
<h2>Cancellation Policy Overview</h2>
<p>We understand that plans can change. This policy outlines our cancellation procedures and fees.</p>
<h2>Standard Cancellation Terms</h2>
<p>For standard bookings, the following cancellation terms apply:</p>
<ul>
<li><strong>More than 48 hours before check-in:</strong> Full refund of the 20% deposit</li>
<li><strong>48 hours or less before check-in:</strong> Deposit is non-refundable</li>
<li><strong>No-show:</strong> No refund will be issued</li>
</ul>
<h2>Special Rate Bookings</h2>
<p>Some special rates or promotional offers may have different cancellation terms. Please review your booking confirmation for specific details.</p>
<h2>How to Cancel</h2>
<p>To cancel your booking:</p>
<ul>
<li>Log into your account and visit "My Bookings"</li>
<li>Select the booking you wish to cancel</li>
<li>Click "Cancel Booking" and confirm</li>
<li>Or contact us directly via phone or email</li>
</ul>
<h2>Refund Processing</h2>
<p>Refunds will be processed to the original payment method within 5-10 business days after cancellation confirmation.</p>
<p><strong>Last updated:</strong> """ + datetime.now().strftime("%B %d, %Y") + """</p>
"""
cancellation_data = {
"title": "Cancellation Policy",
"subtitle": "Flexible cancellation options for your peace of mind",
"description": "Learn about our cancellation policy, fees, and refund procedures.",
"content": cancellation_content,
"meta_title": "Cancellation Policy - Luxury Hotel | Booking Cancellation Terms",
"meta_description": "Review our cancellation policy to understand cancellation fees, refund procedures, and terms for modifying or canceling your hotel booking."
}
existing = db.query(PageContent).filter(PageContent.page_type == PageType.CANCELLATION).first()
if existing:
for key, value in cancellation_data.items():
setattr(existing, key, value)
existing.updated_at = datetime.utcnow()
print("✓ Updated existing cancellation policy page content")
else:
new_content = PageContent(
page_type=PageType.CANCELLATION,
**cancellation_data
)
db.add(new_content)
print("✓ Created new cancellation policy page content")
db.commit()
print("\n✅ Cancellation policy page content seeded successfully!")
print("=" * 80)
def seed_accessibility_policy(db: Session):
print("=" * 80)
print("SEEDING ACCESSIBILITY PAGE CONTENT")
print("=" * 80)
accessibility_content = """
<h2>Our Commitment to Accessibility</h2>
<p>We are committed to ensuring that our hotel and website are accessible to all guests, regardless of ability. We strive to provide an inclusive experience for everyone.</p>
<h2>Hotel Accessibility Features</h2>
<p>Our hotel offers the following accessibility features:</p>
<ul>
<li>Wheelchair-accessible rooms with roll-in showers</li>
<li>Accessible parking spaces</li>
<li>Elevator access to all floors</li>
<li>Ramp access to main entrances</li>
<li>Accessible public restrooms</li>
<li>Visual and auditory emergency alarms</li>
<li>Service animal friendly</li>
</ul>
<h2>Website Accessibility</h2>
<p>We are continuously working to improve the accessibility of our website. Our website includes:</p>
<ul>
<li>Keyboard navigation support</li>
<li>Screen reader compatibility</li>
<li>Alt text for images</li>
<li>High contrast options</li>
<li>Resizable text</li>
</ul>
<h2>Requesting Accommodations</h2>
<p>If you require specific accommodations during your stay, please contact us at least 48 hours before your arrival. We will do our best to accommodate your needs.</p>
<h2>Feedback</h2>
<p>We welcome feedback on how we can improve accessibility. Please contact us with your suggestions or concerns.</p>
<p><strong>Last updated:</strong> """ + datetime.now().strftime("%B %d, %Y") + """</p>
"""
accessibility_data = {
"title": "Accessibility",
"subtitle": "Committed to providing an inclusive experience for all guests",
"description": "Learn about our accessibility features and accommodations.",
"content": accessibility_content,
"meta_title": "Accessibility - Luxury Hotel | Accessible Accommodations",
"meta_description": "Discover our commitment to accessibility, including accessible rooms, facilities, and website features for guests with disabilities."
}
existing = db.query(PageContent).filter(PageContent.page_type == PageType.ACCESSIBILITY).first()
if existing:
for key, value in accessibility_data.items():
setattr(existing, key, value)
existing.updated_at = datetime.utcnow()
print("✓ Updated existing accessibility page content")
else:
new_content = PageContent(
page_type=PageType.ACCESSIBILITY,
**accessibility_data
)
db.add(new_content)
print("✓ Created new accessibility page content")
db.commit()
print("\n✅ Accessibility page content seeded successfully!")
print("=" * 80)
def seed_faq_page(db: Session):
print("=" * 80)
print("SEEDING FAQ PAGE CONTENT")
print("=" * 80)
faq_content = """
<h2>Frequently Asked Questions</h2>
<p>Find answers to common questions about our hotel, bookings, and services.</p>
<h2>Booking & Reservations</h2>
<h3>How do I make a reservation?</h3>
<p>You can make a reservation online through our website, by phone, or by email. Simply select your dates, choose your room, and complete the booking process.</p>
<h3>What is the deposit requirement?</h3>
<p>A 20% deposit is required to secure your booking. The remaining balance is due upon arrival at the hotel.</p>
<h3>Can I modify my booking?</h3>
<p>Yes, you can modify your booking by logging into your account and visiting "My Bookings", or by contacting us directly. Changes are subject to availability and may incur fees.</p>
<h2>Check-in & Check-out</h2>
<h3>What are your check-in and check-out times?</h3>
<p>Check-in is from 3:00 PM, and check-out is by 11:00 AM. Early check-in and late check-out may be available upon request, subject to availability.</p>
<h3>Do you offer early check-in or late check-out?</h3>
<p>Early check-in and late check-out are available upon request, subject to availability. Additional fees may apply.</p>
<h2>Payment & Cancellation</h2>
<h3>What payment methods do you accept?</h3>
<p>We accept major credit cards, debit cards, and bank transfers. Payment can be made online or at the hotel.</p>
<h3>What is your cancellation policy?</h3>
<p>For cancellations made more than 48 hours before check-in, the deposit is fully refundable. Cancellations made 48 hours or less before check-in are non-refundable. Please see our Cancellation Policy page for full details.</p>
<h2>Hotel Services & Amenities</h2>
<h3>What amenities are included?</h3>
<p>Our hotel offers complimentary Wi-Fi, parking, fitness center access, and more. Please check the room details for specific amenities.</p>
<h3>Do you have parking available?</h3>
<p>Yes, we offer complimentary parking for all guests. Valet parking is also available for an additional fee.</p>
<h3>Is Wi-Fi available?</h3>
<p>Yes, complimentary high-speed Wi-Fi is available throughout the hotel.</p>
<h2>Special Requests</h2>
<h3>Can I request a specific room?</h3>
<p>Yes, you can make special requests when booking. We will do our best to accommodate your preferences, subject to availability.</p>
<h3>Do you accommodate dietary restrictions?</h3>
<p>Yes, please inform us of any dietary restrictions or allergies when making your reservation, and we will do our best to accommodate your needs.</p>
<h2>Contact & Support</h2>
<h3>How can I contact the hotel?</h3>
<p>You can contact us by phone, email, or through our website's contact form. Our team is available 24/7 to assist you.</p>
<p><strong>Last updated:</strong> """ + datetime.now().strftime("%B %d, %Y") + """</p>
"""
faq_data = {
"title": "Frequently Asked Questions",
"subtitle": "Find answers to common questions",
"description": "Get answers to frequently asked questions about bookings, services, and policies.",
"content": faq_content,
"meta_title": "FAQ - Luxury Hotel | Frequently Asked Questions",
"meta_description": "Find answers to common questions about hotel bookings, check-in, payment, cancellation, amenities, and more."
}
existing = db.query(PageContent).filter(PageContent.page_type == PageType.FAQ).first()
if existing:
for key, value in faq_data.items():
setattr(existing, key, value)
existing.updated_at = datetime.utcnow()
print("✓ Updated existing FAQ page content")
else:
new_content = PageContent(
page_type=PageType.FAQ,
**faq_data
)
db.add(new_content)
print("✓ Created new FAQ page content")
db.commit()
print("\n✅ FAQ page content seeded successfully!")
print("=" * 80)
def main():
db = get_db()
try:
print("\n")
seed_privacy_policy(db)
print("\n")
seed_terms_conditions(db)
print("\n")
seed_refunds_policy(db)
print("\n")
seed_cancellation_policy(db)
print("\n")
seed_accessibility_policy(db)
print("\n")
seed_faq_page(db)
print("\n")
print("=" * 80)
print("✅ ALL POLICY PAGES SEEDED SUCCESSFULLY!")
print("=" * 80)
print("\n")
except Exception as e:
print(f"\n❌ Error: {e}")
import traceback
traceback.print_exc()
db.rollback()
finally:
db.close()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,139 @@
import sys
import os
from pathlib import Path
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():
db = SessionLocal()
try:
return db
finally:
pass
def seed_rooms(db: Session):
print('=' * 80)
print('SEEDING ROOMS - DELETING EXISTING AND CREATING 50 NEW LUXURY ROOMS')
print('=' * 80)
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})')
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)...')
room_ids = [room.id for room in existing_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)')
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)')
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)')
for room in existing_rooms:
db.delete(room)
db.commit()
print(f'✓ Deleted {len(existing_rooms)} room(s)')
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']
luxury_room_images = ['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', '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', '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']
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_configs = [((1, 3), 8, 'Garden View', (35, 45), 8, False), ((1, 3), 8, 'City View', (40, 50), 9, False), ((4, 6), 6, 'City View', (45, 55), 10, False), ((4, 6), 6, 'Pool View', (50, 60), 11, True), ((7, 9), 5, 'Ocean View', (55, 70), 12, True), ((7, 9), 5, 'Mountain View', (60, 75), 12, False), ((10, 12), 4, 'Panoramic View', (80, 100), 14, True), ((10, 12), 4, 'Sea View', (90, 110), 15, True), ((13, 15), 3, 'Ocean View', (120, 150), 16, True), ((13, 15), 3, 'Beach View', (130, 160), 17, True), ((16, 16), 2, 'Panoramic View', (200, 250), 20, True)]
rooms_created = []
room_counter = 101
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
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 not room_type:
room_type = random.choice(room_types)
base_price = float(room_type.base_price)
floor_premium = (floor - 1) * 5
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
random_variation = base_price * random.uniform(-0.05, 0.1)
size_min, size_max = size_range
size_premium = (size_min + size_max) / 2 * 0.5
price = base_price + floor_premium + view_premium + random_variation + size_premium
price = max(base_price * 0.95, price)
price = round(price, 2)
selected_amenities = random.sample(all_amenities, min(amenities_count, len(all_amenities)))
if floor >= 13:
premium_count = min(2, len(premium_amenities))
selected_amenities.extend(random.sample(premium_amenities, premium_count))
size_min, size_max = size_range
room_size = f'{random.randint(size_min, size_max)} sqm'
capacity = room_type.capacity
if random.random() > 0.7:
capacity = max(1, capacity + random.randint(-1, 1))
room_number = f'{floor}{room_counter % 100:02d}'
room_counter += 1
shuffled_images = luxury_room_images.copy()
random.shuffle(shuffled_images)
image_urls = shuffled_images[:3]
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_weights = [0.85, 0.05, 0.05, 0.05]
status = random.choices([RoomStatus.available, RoomStatus.occupied, RoomStatus.maintenance, RoomStatus.cleaning], weights=status_weights)[0]
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()

View File

@@ -0,0 +1,165 @@
import sys
import os
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent))
from sqlalchemy.orm import Session
from src.config.database import SessionLocal
from src.models.role import Role
from src.models.user import User
import bcrypt
from datetime import datetime
def get_db():
db = SessionLocal()
try:
return db
finally:
pass
def seed_users(db: Session):
print('=' * 80)
print('SEEDING USERS')
print('=' * 80)
# Get roles
admin_role = db.query(Role).filter(Role.name == 'admin').first()
staff_role = db.query(Role).filter(Role.name == 'staff').first()
customer_role = db.query(Role).filter(Role.name == 'customer').first()
if not admin_role or not staff_role or not customer_role:
print(' ❌ Roles not found! Please seed roles first.')
return
users_data = [
{
'email': 'gnxsoft@gnxsoft.com',
'password': 'gnxsoft123',
'full_name': 'GNXSoft Admin',
'phone': '+1 (555) 111-2222',
'role': 'admin',
'currency': 'EUR',
'is_active': True
},
{
'email': 'admin@gnxsoft.com',
'password': 'admin123',
'full_name': 'Administrator',
'phone': '+1 (555) 222-3333',
'role': 'admin',
'currency': 'EUR',
'is_active': True
},
{
'email': 'staff@gnxsoft.com',
'password': 'staff123',
'full_name': 'Staff Member',
'phone': '+1 (555) 333-4444',
'role': 'staff',
'currency': 'EUR',
'is_active': True
},
{
'email': 'customer@gnxsoft.com',
'password': 'customer123',
'full_name': 'Customer User',
'phone': '+1 (555) 444-5555',
'role': 'customer',
'currency': 'EUR',
'is_active': True
},
{
'email': 'john.doe@gnxsoft.com',
'password': 'customer123',
'full_name': 'John Doe',
'phone': '+1 (555) 555-6666',
'role': 'customer',
'currency': 'USD',
'is_active': True
},
{
'email': 'jane.smith@gnxsoft.com',
'password': 'customer123',
'full_name': 'Jane Smith',
'phone': '+1 (555) 666-7777',
'role': 'customer',
'currency': 'EUR',
'is_active': True
},
{
'email': 'robert.wilson@gnxsoft.com',
'password': 'customer123',
'full_name': 'Robert Wilson',
'phone': '+1 (555) 777-8888',
'role': 'customer',
'currency': 'GBP',
'is_active': True
},
{
'email': 'maria.garcia@gnxsoft.com',
'password': 'customer123',
'full_name': 'Maria Garcia',
'phone': '+1 (555) 888-9999',
'role': 'customer',
'currency': 'EUR',
'is_active': True
}
]
role_map = {
'admin': admin_role.id,
'staff': staff_role.id,
'customer': customer_role.id
}
created_count = 0
skipped_count = 0
for user_data in users_data:
existing = db.query(User).filter(User.email == user_data['email']).first()
if existing:
print(f' ⚠️ User "{user_data["email"]}" already exists, skipping...')
skipped_count += 1
continue
password = user_data.pop('password')
role_name = user_data.pop('role')
role_id = role_map[role_name]
password_bytes = password.encode('utf-8')
salt = bcrypt.gensalt()
hashed_password = bcrypt.hashpw(password_bytes, salt).decode('utf-8')
user = User(
email=user_data['email'],
password=hashed_password,
full_name=user_data['full_name'],
phone=user_data.get('phone'),
role_id=role_id,
currency=user_data.get('currency', 'EUR'),
is_active=user_data.get('is_active', True)
)
db.add(user)
print(f' ✓ Created user: {user_data["email"]} ({role_name}) - Password: {password}')
created_count += 1
db.commit()
print(f'\n✓ Users seeded successfully!')
print(f' - Created: {created_count} user(s)')
print(f' - Skipped: {skipped_count} user(s) (already exist)')
print('=' * 80)
def main():
db = get_db()
try:
seed_users(db)
except Exception as e:
print(f'\n❌ Error: {e}')
import traceback
traceback.print_exc()
db.rollback()
finally:
db.close()
if __name__ == '__main__':
main()