Files
Hotel-Booking/Backend/src/models/rate_plan.py
Iliyan Angelov 627959f52b updates
2025-11-23 18:59:18 +02:00

108 lines
4.8 KiB
Python

from sqlalchemy import Column, Integer, String, Numeric, Boolean, Text, JSON, Enum, ForeignKey, DateTime, Date
from sqlalchemy.orm import relationship
from datetime import datetime, date
import enum
from ..config.database import Base
class RatePlanType(str, enum.Enum):
BAR = 'BAR' # Best Available Rate
non_refundable = 'non_refundable'
advance_purchase = 'advance_purchase'
corporate = 'corporate'
government = 'government'
military = 'military'
long_stay = 'long_stay'
package = 'package'
class RatePlanStatus(str, enum.Enum):
active = 'active'
inactive = 'inactive'
scheduled = 'scheduled'
expired = 'expired'
class RatePlan(Base):
__tablename__ = 'rate_plans'
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
name = Column(String(100), nullable=False, index=True)
code = Column(String(50), unique=True, nullable=False, index=True)
description = Column(Text, nullable=True)
plan_type = Column(Enum(RatePlanType), nullable=False, default=RatePlanType.BAR)
status = Column(Enum(RatePlanStatus), nullable=False, default=RatePlanStatus.active)
# Pricing
base_price_modifier = Column(Numeric(5, 2), nullable=False, default=1.0) # Multiplier (1.0 = 100%, 0.9 = 90%)
discount_percentage = Column(Numeric(5, 2), nullable=True, default=0) # Percentage discount
fixed_discount = Column(Numeric(10, 2), nullable=True, default=0) # Fixed amount discount
# Applicability
room_type_id = Column(Integer, ForeignKey('room_types.id'), nullable=True) # None = all room types
min_nights = Column(Integer, nullable=True) # Minimum nights required
max_nights = Column(Integer, nullable=True) # Maximum nights allowed
advance_days_required = Column(Integer, nullable=True) # Days in advance required for booking
# Date range
valid_from = Column(Date, nullable=True)
valid_to = Column(Date, nullable=True)
# Restrictions
is_refundable = Column(Boolean, nullable=False, default=True)
requires_deposit = Column(Boolean, nullable=False, default=False)
deposit_percentage = Column(Numeric(5, 2), nullable=True, default=0)
cancellation_hours = Column(Integer, nullable=True) # Hours before check-in for free cancellation
# Corporate/Government specific
corporate_code = Column(String(50), nullable=True, index=True)
requires_verification = Column(Boolean, nullable=False, default=False)
verification_type = Column(String(50), nullable=True) # 'corporate_id', 'government_id', 'military_id'
# Long-stay specific
long_stay_nights = Column(Integer, nullable=True) # Nights required for long-stay discount
# Package specific
is_package = Column(Boolean, nullable=False, default=False)
package_id = Column(Integer, ForeignKey('packages.id'), nullable=True)
# Priority (lower number = higher priority)
priority = Column(Integer, nullable=False, default=100)
# Additional data (metadata is reserved by SQLAlchemy)
extra_data = Column(JSON, nullable=True) # Additional flexible data
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
# Relationships
room_type = relationship('RoomType', back_populates='rate_plans')
package = relationship('Package', back_populates='rate_plans')
rules = relationship('RatePlanRule', back_populates='rate_plan', cascade='all, delete-orphan')
bookings = relationship('Booking', back_populates='rate_plan')
class RatePlanRule(Base):
__tablename__ = 'rate_plan_rules'
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
rate_plan_id = Column(Integer, ForeignKey('rate_plans.id'), nullable=False, index=True)
# Rule type
rule_type = Column(String(50), nullable=False) # 'day_of_week', 'season', 'occupancy', 'date_range', etc.
rule_key = Column(String(100), nullable=False) # e.g., 'monday', 'summer', '2_guests', '2024-12-01_to_2024-12-31'
rule_value = Column(JSON, nullable=True) # Flexible value storage
# Price adjustment
price_modifier = Column(Numeric(5, 2), nullable=True, default=1.0)
discount_percentage = Column(Numeric(5, 2), nullable=True, default=0)
fixed_adjustment = Column(Numeric(10, 2), nullable=True, default=0)
# Priority within the rate plan
priority = Column(Integer, nullable=False, default=100)
# Additional data
extra_data = Column(JSON, nullable=True)
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
# Relationships
rate_plan = relationship('RatePlan', back_populates='rules')