from datetime import datetime, timezone from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey, Boolean from sqlalchemy.orm import relationship from app.db.base import Base class Coupon(Base): __tablename__ = "coupons" id = Column(Integer, primary_key=True, autoincrement=True) code = Column(String(50), unique=True, index=True, nullable=False) discount_percent = Column(Float, nullable=False) is_active = Column(Boolean, default=True, nullable=False) expires_at = Column(DateTime, nullable=True) created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), nullable=False) carts = relationship("Cart", back_populates="coupon") class Cart(Base): __tablename__ = "carts" id = Column(Integer, primary_key=True, autoincrement=True) user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=True) session_id = Column(String(255), unique=True, index=True, nullable=True) coupon_id = Column(Integer, ForeignKey("coupons.id", ondelete="SET NULL"), nullable=True) created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), nullable=False) updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc), nullable=False) user = relationship("User", backref="cart") coupon = relationship("Coupon", back_populates="carts") items = relationship("CartItem", back_populates="cart", cascade="all, delete-orphan") class CartItem(Base): __tablename__ = "cart_items" id = Column(Integer, primary_key=True, autoincrement=True) cart_id = Column(Integer, ForeignKey("carts.id", ondelete="CASCADE"), nullable=False) product_id = Column(Integer, ForeignKey("products.id", ondelete="CASCADE"), nullable=False) variant_label = Column(String(100), nullable=True) # Store variant name (e.g. "Space Gray / 128GB") variant_id = Column(String(50), nullable=True) # Store variant ID for easier matching quantity = Column(Integer, default=1, nullable=False) unit_price = Column(Float, nullable=False) # snapshot of price when added/updated created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), nullable=False) updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc), nullable=False) cart = relationship("Cart", back_populates="items") product = relationship("Product")