Files
Hotel-Booking/Backend/seeders/settings_seeder.py
Iliyan Angelov 5a8ca3c475 updates
2025-12-06 03:27:35 +02:00

340 lines
12 KiB
Python

"""
Settings Seeder
Seeds the database with system settings
"""
import sys
from pathlib import Path
from datetime import datetime, timezone
# Add parent directory to path to import modules
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from sqlalchemy.orm import Session
from src.shared.config.database import SessionLocal
from src.shared.config.logging_config import get_logger
from src.system.models.system_settings import SystemSettings
from src.auth.models.user import User
# Import all models to ensure relationships are loaded correctly
from src.models import *
logger = get_logger(__name__)
def get_settings_data():
"""Generate comprehensive system settings data"""
return [
# Company Settings
{
'key': 'company_name',
'value': 'Luxury Hotel & Resort',
'description': 'The official name of the hotel/company'
},
{
'key': 'company_tagline',
'value': 'Experience Unparalleled Elegance and Comfort',
'description': 'Company tagline or slogan'
},
{
'key': 'company_logo_url',
'value': 'https://ui-avatars.com/api/?name=Luxury+Hotel&background=d4af37&color=fff&size=400&bold=true&font-size=0.5',
'description': 'URL to the company logo image'
},
{
'key': 'company_favicon_url',
'value': 'https://ui-avatars.com/api/?name=LH&background=d4af37&color=fff&size=64&bold=true',
'description': 'URL to the company favicon image'
},
{
'key': 'company_phone',
'value': '+1 (555) 123-4567',
'description': 'Primary company phone number'
},
{
'key': 'company_email',
'value': 'info@luxuryhotel.com',
'description': 'Primary company email address'
},
{
'key': 'company_address',
'value': '123 Luxury Avenue, Premium City, PC 12345, United States',
'description': 'Company physical address'
},
{
'key': 'tax_rate',
'value': '10.0',
'description': 'Default tax rate percentage (e.g., 10.0 for 10%)'
},
{
'key': 'chat_working_hours_start',
'value': '9',
'description': 'Chat support working hours start (24-hour format, e.g., 9 for 9 AM)'
},
{
'key': 'chat_working_hours_end',
'value': '18',
'description': 'Chat support working hours end (24-hour format, e.g., 18 for 6 PM)'
},
# Platform Settings
{
'key': 'platform_currency',
'value': 'USD',
'description': 'Default platform currency code (ISO 4217 format, e.g., USD, EUR, GBP)'
},
# Payment Gateway Settings (Placeholder values - should be configured in production)
{
'key': 'stripe_secret_key',
'value': '',
'description': 'Stripe secret API key (configure in production)'
},
{
'key': 'stripe_publishable_key',
'value': '',
'description': 'Stripe publishable API key (configure in production)'
},
{
'key': 'stripe_webhook_secret',
'value': '',
'description': 'Stripe webhook secret for verifying webhook events (configure in production)'
},
{
'key': 'paypal_client_id',
'value': '',
'description': 'PayPal client ID (configure in production)'
},
{
'key': 'paypal_client_secret',
'value': '',
'description': 'PayPal client secret (configure in production)'
},
{
'key': 'paypal_mode',
'value': 'sandbox',
'description': 'PayPal mode: "sandbox" for testing, "live" for production'
},
{
'key': 'borica_terminal_id',
'value': '',
'description': 'Borica terminal ID (configure if using Borica payment gateway)'
},
{
'key': 'borica_merchant_id',
'value': '',
'description': 'Borica merchant ID (configure if using Borica payment gateway)'
},
{
'key': 'borica_private_key_path',
'value': '',
'description': 'Path to Borica private key file (configure if using Borica)'
},
{
'key': 'borica_certificate_path',
'value': '',
'description': 'Path to Borica certificate file (configure if using Borica)'
},
{
'key': 'borica_gateway_url',
'value': '',
'description': 'Borica gateway URL (configure if using Borica payment gateway)'
},
{
'key': 'borica_mode',
'value': 'test',
'description': 'Borica mode: "test" for testing, "production" for live transactions'
},
# SMTP Settings (Placeholder values - should be configured in production)
{
'key': 'smtp_host',
'value': '',
'description': 'SMTP server hostname (e.g., smtp.gmail.com, smtp.sendgrid.net)'
},
{
'key': 'smtp_port',
'value': '587',
'description': 'SMTP server port (587 for STARTTLS, 465 for SSL)'
},
{
'key': 'smtp_user',
'value': '',
'description': 'SMTP authentication username/email'
},
{
'key': 'smtp_password',
'value': '',
'description': 'SMTP authentication password (stored securely)'
},
{
'key': 'smtp_from_email',
'value': 'noreply@luxuryhotel.com',
'description': 'Default "From" email address for outgoing emails'
},
{
'key': 'smtp_from_name',
'value': 'Luxury Hotel & Resort',
'description': 'Default "From" name for outgoing emails'
},
{
'key': 'smtp_use_tls',
'value': 'true',
'description': 'Use TLS/SSL for SMTP connection (true for port 465, false for port 587 with STARTTLS)'
},
# Security Settings
{
'key': 'recaptcha_site_key',
'value': '',
'description': 'Google reCAPTCHA site key (configure if using reCAPTCHA)'
},
{
'key': 'recaptcha_secret_key',
'value': '',
'description': 'Google reCAPTCHA secret key (configure if using reCAPTCHA)'
},
{
'key': 'recaptcha_enabled',
'value': 'false',
'description': 'Enable/disable reCAPTCHA verification (true/false)'
},
# Additional Settings
{
'key': 'booking_confirmation_email_enabled',
'value': 'true',
'description': 'Enable automatic booking confirmation emails (true/false)'
},
{
'key': 'booking_cancellation_email_enabled',
'value': 'true',
'description': 'Enable automatic booking cancellation emails (true/false)'
},
{
'key': 'newsletter_enabled',
'value': 'true',
'description': 'Enable newsletter subscription feature (true/false)'
},
{
'key': 'maintenance_mode',
'value': 'false',
'description': 'Enable maintenance mode (true/false)'
},
{
'key': 'maintenance_message',
'value': 'We are currently performing scheduled maintenance. Please check back soon.',
'description': 'Message to display when maintenance mode is enabled'
},
{
'key': 'default_checkin_time',
'value': '15:00',
'description': 'Default check-in time (24-hour format, e.g., 15:00 for 3 PM)'
},
{
'key': 'default_checkout_time',
'value': '11:00',
'description': 'Default check-out time (24-hour format, e.g., 11:00 for 11 AM)'
},
{
'key': 'cancellation_hours',
'value': '24',
'description': 'Number of hours before check-in that cancellation is allowed without penalty'
},
{
'key': 'max_guests_per_room',
'value': '4',
'description': 'Maximum number of guests allowed per room'
},
{
'key': 'min_booking_advance_days',
'value': '0',
'description': 'Minimum number of days in advance required for booking (0 = same day allowed)'
},
{
'key': 'max_booking_advance_days',
'value': '365',
'description': 'Maximum number of days in advance bookings can be made'
}
]
def seed_settings(db: Session, clear_existing: bool = False, admin_user_id: int = None):
"""Seed system settings into the database"""
try:
if clear_existing:
logger.info('Clearing existing system settings...')
db.query(SystemSettings).delete()
db.commit()
logger.info('Existing system settings cleared.')
# Get admin user if not provided
if admin_user_id is None:
admin_user = db.query(User).filter(User.email == 'admin@hotel.com').first()
if admin_user:
admin_user_id = admin_user.id
else:
logger.warning('Admin user not found. Settings will be created without updated_by_id.')
settings_data = get_settings_data()
now = datetime.now(timezone.utc)
created_count = 0
updated_count = 0
for setting_data in settings_data:
existing = db.query(SystemSettings).filter(SystemSettings.key == setting_data['key']).first()
if existing:
logger.debug(f"Setting '{setting_data['key']}' already exists. Updating...")
existing.value = setting_data['value']
existing.description = setting_data['description']
if admin_user_id:
existing.updated_by_id = admin_user_id
existing.updated_at = now
updated_count += 1
else:
logger.debug(f"Creating setting: {setting_data['key']}")
setting = SystemSettings(
key=setting_data['key'],
value=setting_data['value'],
description=setting_data['description'],
updated_by_id=admin_user_id,
updated_at=now
)
db.add(setting)
created_count += 1
db.commit()
logger.info(f'Successfully seeded system settings! Created: {created_count}, Updated: {updated_count}, Total: {len(settings_data)}')
except Exception as e:
db.rollback()
logger.error(f'Error seeding system settings: {str(e)}', exc_info=True)
raise
def main():
import argparse
parser = argparse.ArgumentParser(description='Seed system settings')
parser.add_argument(
'--clear',
action='store_true',
help='Clear existing settings before seeding'
)
args = parser.parse_args()
db = SessionLocal()
try:
seed_settings(db, clear_existing=args.clear)
except Exception as e:
logger.error(f'Failed to seed system settings: {str(e)}', exc_info=True)
sys.exit(1)
finally:
db.close()
if __name__ == '__main__':
main()