from sqlalchemy import Column, Integer, String, Float, DateTime, Boolean, Text, ForeignKey, JSON, DECIMAL from sqlalchemy.orm import relationship from datetime import datetime from app.database.database import Base class Product(Base): __tablename__ = "product" id = Column(Integer, primary_key=True, index=True) name = Column(String, index=True) slug = Column(String, unique=True, index=True, nullable=True) description = Column(Text) price = Column(Float, nullable=True) # Nullable - can inherit from model discount_price = Column(Float, nullable=True) category_id = Column(Integer, ForeignKey("category.id")) model_id = Column(Integer, ForeignKey("model.id", ondelete="SET NULL"), nullable=True) gender = Column(String, default='Unisex') # men, women, unisex brand = Column(String) sizes = Column(JSON) # ["S", "M", "L", "XL", ...] colors = Column(JSON) # ["Red", "Blue", ...] stock = Column(Integer, nullable=True, default=None) images = Column(JSON) # Array of image URLs main_image_url = Column(Text, nullable=True) # Main image for product listings rating_average = Column(DECIMAL(2, 1), default=0.0) # Average rating (0.0-5.0) rating_count = Column(Integer, default=0) # Number of ratings is_featured = Column(Boolean, default=False) is_on_sale = Column(Boolean, default=False) override_price = Column(DECIMAL(10, 2), nullable=True) override_sizes = Column(JSON, nullable=True) created_at = Column(DateTime, default=datetime.utcnow) category = relationship("Category") model = relationship("Model", back_populates="products") cart_items = relationship("CartItem", back_populates="product") order_items = relationship("OrderItem", back_populates="product") def get_effective_price(self) -> float: """Get the effective price - either product's own price or model's base_price""" if self.price is not None: return float(self.price) elif self.model and self.model.base_price is not None: return float(self.model.base_price) else: return 0.0 # Default fallback @property def category_name(self): """Return the name of the associated category, or None if not set.""" return self.category.name if self.category else None