Files
2025-10-17 18:14:28 +02:00

65 lines
2.7 KiB
Python

"""
SQLAlchemy models for coupon system
"""
from datetime import datetime
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, JSON, Index
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
import uuid
from shared.database import Base
class CouponModel(Base):
"""Coupon configuration table"""
__tablename__ = "coupons"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
code = Column(String(50), unique=True, nullable=False, index=True)
discount_type = Column(String(20), nullable=False) # trial_extension, percentage, fixed_amount
discount_value = Column(Integer, nullable=False) # Days/percentage/cents depending on type
max_redemptions = Column(Integer, nullable=True) # None = unlimited
current_redemptions = Column(Integer, nullable=False, default=0)
valid_from = Column(DateTime(timezone=True), nullable=False)
valid_until = Column(DateTime(timezone=True), nullable=True) # None = no expiry
active = Column(Boolean, nullable=False, default=True)
created_at = Column(DateTime(timezone=True), nullable=False, default=datetime.utcnow)
extra_data = Column(JSON, nullable=True) # Renamed from metadata to avoid SQLAlchemy reserved name
# Relationships
redemptions = relationship("CouponRedemptionModel", back_populates="coupon")
# Indexes for performance
__table_args__ = (
Index('idx_coupon_code_active', 'code', 'active'),
Index('idx_coupon_valid_dates', 'valid_from', 'valid_until'),
)
def __repr__(self):
return f"<Coupon(code='{self.code}', type='{self.discount_type}', value={self.discount_value})>"
class CouponRedemptionModel(Base):
"""Coupon redemption history table"""
__tablename__ = "coupon_redemptions"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
tenant_id = Column(String(255), nullable=False, index=True)
coupon_code = Column(String(50), ForeignKey('coupons.code'), nullable=False)
redeemed_at = Column(DateTime(timezone=True), nullable=False, default=datetime.utcnow)
discount_applied = Column(JSON, nullable=False) # Details of discount applied
extra_data = Column(JSON, nullable=True) # Renamed from metadata to avoid SQLAlchemy reserved name
# Relationships
coupon = relationship("CouponModel", back_populates="redemptions")
# Constraints
__table_args__ = (
Index('idx_redemption_tenant', 'tenant_id'),
Index('idx_redemption_coupon', 'coupon_code'),
Index('idx_redemption_tenant_coupon', 'tenant_id', 'coupon_code'), # Prevent duplicate redemptions
)
def __repr__(self):
return f"<CouponRedemption(tenant_id='{self.tenant_id}', code='{self.coupon_code}')>"