from sqlalchemy import Column, String, Integer, Float, ForeignKey, Enum, Text, DateTime from sqlalchemy.orm import relationship import enum from app.models.base import BaseModel, TimestampMixin class OrderStatus(str, enum.Enum): """Enum for order status.""" PENDING = "pending" PAID = "paid" PROCESSING = "processing" SHIPPED = "shipped" DELIVERED = "delivered" CANCELLED = "cancelled" REFUNDED = "refunded" class PaymentMethod(str, enum.Enum): """Enum for payment methods.""" CREDIT_CARD = "credit_card" DEBIT_CARD = "debit_card" PAYPAL = "paypal" BANK_TRANSFER = "bank_transfer" CASH_ON_DELIVERY = "cash_on_delivery" class Order(BaseModel, TimestampMixin): """Order model for completed purchases.""" user_id = Column(Integer, ForeignKey("user.id"), nullable=False) status = Column( Enum(OrderStatus), default=OrderStatus.PENDING, nullable=False ) total_amount = Column(Float, nullable=False) shipping_address = Column(Text, nullable=False) tracking_number = Column(String, nullable=True) payment_method = Column( Enum(PaymentMethod), nullable=False ) payment_id = Column(String, nullable=True) # ID from payment processor paid_at = Column(DateTime, nullable=True) notes = Column(Text, nullable=True) # Relationships user = relationship("User", back_populates="orders") items = relationship("OrderItem", back_populates="order", cascade="all, delete-orphan") class OrderItem(BaseModel, TimestampMixin): """Order item model for items in an order.""" order_id = Column(Integer, ForeignKey("order.id"), nullable=False) product_id = Column(Integer, ForeignKey("product.id"), nullable=False) quantity = Column(Integer, nullable=False) unit_price = Column(Float, nullable=False) # Price at the time of order # Relationships order = relationship("Order", back_populates="items") product = relationship("Product", back_populates="order_items") @property def subtotal(self): """Calculate the subtotal for this order item.""" return self.quantity * self.unit_price