""" Subscription model - Tracks therapist billing and student limits """ from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey, Boolean, Enum from sqlalchemy.orm import relationship from sqlalchemy.sql import func from config.database import Base import enum class PlanType(enum.Enum): FREE = "free" BASIC = "basic" # e.g., $29/month - up to 5 students PROFESSIONAL = "professional" # e.g., $79/month - up to 20 students ENTERPRISE = "enterprise" # Custom pricing - unlimited students class BillingPeriod(enum.Enum): MONTHLY = "monthly" YEARLY = "yearly" class Subscription(Base): __tablename__ = "subscriptions" id = Column(Integer, primary_key=True, index=True) therapist_id = Column(Integer, ForeignKey("therapists.id"), unique=True, nullable=False) # Plan details plan_type = Column(Enum(PlanType), nullable=False, default=PlanType.FREE) billing_period = Column(Enum(BillingPeriod), nullable=True) # Pricing base_price = Column(Float, default=0.0) # Base monthly price per_student_price = Column(Float, default=0.0) # Additional cost per student over limit # Limits included_students = Column(Integer, default=1) # Students included in base price max_students = Column(Integer, nullable=True) # Hard limit (null = unlimited) current_student_count = Column(Integer, default=0) # Active students # Billing stripe_customer_id = Column(String, nullable=True) stripe_subscription_id = Column(String, nullable=True) # Status is_active = Column(Boolean, default=True) trial_ends_at = Column(DateTime(timezone=True), nullable=True) current_period_start = Column(DateTime(timezone=True), nullable=True) current_period_end = Column(DateTime(timezone=True), nullable=True) # Timestamps created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now()) canceled_at = Column(DateTime(timezone=True), nullable=True) # Relationships therapist = relationship("Therapist", backref="subscription") def calculate_monthly_cost(self): """Calculate total monthly cost based on current student count""" base = self.base_price # If yearly billing, calculate monthly equivalent if self.billing_period == BillingPeriod.YEARLY: base = base / 12 # Calculate overage if exceeding included students if self.current_student_count > self.included_students: overage = self.current_student_count - self.included_students additional = overage * self.per_student_price return base + additional return base def can_add_student(self): """Check if therapist can add another student""" if self.max_students is None: return True return self.current_student_count < self.max_students def __repr__(self): return f""