import enum from uuid import uuid4 from sqlalchemy import JSON, Column, DateTime, Enum, Float, ForeignKey, Integer, String, Text from sqlalchemy.orm import relationship from sqlalchemy.sql import func from app.core.database import Base class OrderStatus(enum.Enum): PENDING = "pending" PROCESSING = "processing" SHIPPED = "shipped" DELIVERED = "delivered" CANCELLED = "cancelled" REFUNDED = "refunded" class ShippingMethod(enum.Enum): STANDARD = "standard" EXPRESS = "express" OVERNIGHT = "overnight" PICKUP = "pickup" DIGITAL = "digital" class Order(Base): __tablename__ = "orders" id = Column(String(36), primary_key=True, default=lambda: str(uuid4())) user_id = Column(String(36), ForeignKey("users.id"), nullable=False) order_number = Column(String(50), nullable=False, unique=True, index=True) status = Column(Enum(OrderStatus), default=OrderStatus.PENDING) total_amount = Column(Float, nullable=False) subtotal = Column(Float, nullable=False) tax_amount = Column(Float, nullable=False) shipping_amount = Column(Float, nullable=False) discount_amount = Column(Float, default=0.0) shipping_method = Column(Enum(ShippingMethod), nullable=True) tracking_number = Column(String(100), nullable=True) notes = Column(Text, nullable=True) shipping_address = Column(JSON, nullable=True) # JSON containing shipping address billing_address = Column(JSON, nullable=True) # JSON containing billing address created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now()) # Relationships user = relationship("User", back_populates="orders") items = relationship("OrderItem", back_populates="order", cascade="all, delete-orphan") payments = relationship("Payment", back_populates="order", cascade="all, delete-orphan") def __repr__(self): return f"" class OrderItem(Base): __tablename__ = "order_items" id = Column(String(36), primary_key=True, default=lambda: str(uuid4())) order_id = Column(String(36), ForeignKey("orders.id", ondelete="CASCADE"), nullable=False) product_id = Column(String(36), ForeignKey("products.id"), nullable=False) quantity = Column(Integer, default=1, nullable=False) unit_price = Column(Float, nullable=False) # Price at the time of purchase subtotal = Column(Float, nullable=False) # unit_price * quantity discount = Column(Float, default=0.0) tax_amount = Column(Float, default=0.0) product_name = Column(String(255), nullable=False) # Store name in case product is deleted product_sku = Column(String(100), nullable=True) product_options = Column(JSON, nullable=True) # JSON containing selected options created_at = Column(DateTime(timezone=True), server_default=func.now()) # Relationships order = relationship("Order", back_populates="items") product = relationship("Product", back_populates="order_items") def __repr__(self): return f""