76 lines
3.1 KiB
Python

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"<Order {self.order_number}>"
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"<OrderItem {self.id} for Order {self.order_id}>"