
Create a complete e-commerce application with the following features: - User authentication and authorization - Product and category management - Shopping cart functionality - Order processing - Database migrations with Alembic - Comprehensive documentation
94 lines
2.7 KiB
Python
94 lines
2.7 KiB
Python
import uuid
|
|
from typing import List, Optional
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.models.order import Order, OrderStatus
|
|
from app.models.order_item import OrderItem
|
|
from app.models.product import Product
|
|
from app.schemas.order import OrderCreate, OrderUpdate, OrderItemCreate
|
|
|
|
|
|
def get_by_id(db: Session, order_id: str) -> Optional[Order]:
|
|
return db.query(Order).filter(Order.id == order_id).first()
|
|
|
|
|
|
def get_by_user_id(db: Session, user_id: str, skip: int = 0, limit: int = 100) -> List[Order]:
|
|
return db.query(Order).filter(Order.user_id == user_id).order_by(Order.created_at.desc()).offset(skip).limit(limit).all()
|
|
|
|
|
|
def get_order_items(db: Session, order_id: str) -> List[OrderItem]:
|
|
return db.query(OrderItem).filter(OrderItem.order_id == order_id).all()
|
|
|
|
|
|
def create(db: Session, *, obj_in: OrderCreate, items: List[OrderItemCreate]) -> Order:
|
|
# Calculate total amount
|
|
total_amount = 0.0
|
|
for item in items:
|
|
total_amount += item.price * item.quantity
|
|
|
|
# Create order
|
|
db_obj = Order(
|
|
id=str(uuid.uuid4()),
|
|
user_id=obj_in.user_id,
|
|
status=OrderStatus.PENDING,
|
|
total_amount=total_amount,
|
|
shipping_address=obj_in.shipping_address,
|
|
)
|
|
db.add(db_obj)
|
|
db.commit()
|
|
db.refresh(db_obj)
|
|
|
|
# Create order items
|
|
for item in items:
|
|
order_item = OrderItem(
|
|
id=str(uuid.uuid4()),
|
|
order_id=db_obj.id,
|
|
product_id=item.product_id,
|
|
quantity=item.quantity,
|
|
price=item.price,
|
|
)
|
|
db.add(order_item)
|
|
|
|
# Update product stock
|
|
product = db.query(Product).filter(Product.id == item.product_id).first()
|
|
if product:
|
|
product.stock -= item.quantity
|
|
db.add(product)
|
|
|
|
db.commit()
|
|
return db_obj
|
|
|
|
|
|
def update(db: Session, *, db_obj: Order, obj_in: OrderUpdate) -> Order:
|
|
update_data = obj_in.dict(exclude_unset=True)
|
|
|
|
for field, value in update_data.items():
|
|
setattr(db_obj, field, value)
|
|
|
|
db.add(db_obj)
|
|
db.commit()
|
|
db.refresh(db_obj)
|
|
return db_obj
|
|
|
|
|
|
def cancel_order(db: Session, *, order_id: str) -> Order:
|
|
order = get_by_id(db, order_id=order_id)
|
|
if not order or order.status != OrderStatus.PENDING:
|
|
return None
|
|
|
|
# Update order status
|
|
order.status = OrderStatus.CANCELLED
|
|
db.add(order)
|
|
|
|
# Restore product stock
|
|
order_items = get_order_items(db, order_id=order.id)
|
|
for item in order_items:
|
|
product = db.query(Product).filter(Product.id == item.product_id).first()
|
|
if product:
|
|
product.stock += item.quantity
|
|
db.add(product)
|
|
|
|
db.commit()
|
|
db.refresh(order)
|
|
return order |