This commit is contained in:
Iliyan Angelov
2025-11-23 18:59:18 +02:00
parent be07802066
commit 627959f52b
1840 changed files with 236564 additions and 3475 deletions

View File

@@ -0,0 +1,107 @@
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')