diff --git a/app/backend/main.py b/app/backend/main.py index f903ab4ffff2e2da8315caf0b43cdd4cb80f770e..dfca6ef8856c50598f0224c007e0065f35ba2be7 100644 --- a/app/backend/main.py +++ b/app/backend/main.py @@ -4,7 +4,7 @@ import os sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from fastapi import FastAPI -from backend.routes import auth, shop, product, category +from backend.routes import auth, shop, product, category, order, orderitem from backend.database import init_db from core.config import settings @@ -18,7 +18,8 @@ app.include_router(auth.router, prefix="/auth", tags=["auth"]) app.include_router(shop.router, prefix="/shops", tags=["shops"]) app.include_router(product.router, prefix="/product", tags=["product"]) app.include_router(category.router, prefix="/category", tags=["category"]) - +app.include_router(order.router, prefix="/order", tags=["order"]) +app.include_router(orderitem.router, prefix="/orderitem", tags=["orderitem"]) @app.get("/") diff --git a/app/backend/routes/order.py b/app/backend/routes/order.py new file mode 100644 index 0000000000000000000000000000000000000000..388a0c1fd47afaede3d88c13b1ccd24cd28d8d36 --- /dev/null +++ b/app/backend/routes/order.py @@ -0,0 +1,68 @@ +from fastapi import APIRouter, Depends, HTTPException +from sqlmodel import Session, select +from datetime import datetime +from backend.models.models import Order, OrderItem +from backend.schemas.order import OrderRead, OrderCreate, OrderUpdate, OrderList, OrderWithItems +from backend.database import get_session + +router = APIRouter() + +@router.post("/", response_model=OrderRead) +def create_order(order: OrderCreate, session: Session = Depends(get_session)): + new_order = Order( + user_id=1, # Cần cập nhật logic lấy user từ authentication + shop_id=order.shop_id, + total_price=order.total_price, + status="pending", + created_at=datetime.utcnow(), + ) + session.add(new_order) + session.commit() + session.refresh(new_order) + return new_order + +@router.get("/{order_id}", response_model=OrderWithItems) +def read_order(order_id: int, session: Session = Depends(get_session)): + order = session.get(Order, order_id) + if not order: + raise HTTPException(status_code=404, detail="Order not found") + return order + +@router.get("/user/{user_id}", response_model=OrderList) +def list_user_orders(user_id: int, session: Session = Depends(get_session)): + orders = session.exec(select(Order).where(Order.user_id == user_id)).all() + return {"orders": orders} + +@router.get("/", response_model=OrderList) +def list_all_orders(session: Session = Depends(get_session)): + orders = session.exec(select(Order)).all() + return {"orders": orders} + +@router.get("/{order_id}/calculate-total", response_model=float) +def calculate_total_price(order_id: int, session: Session = Depends(get_session)): + order_items = session.exec(select(OrderItem).where(OrderItem.order_id == order_id)).all() + total_price = sum(item.price * item.quantity for item in order_items) + return total_price + +@router.put("/{order_id}", response_model=OrderRead) +def update_order(order_id: int, order_update: OrderUpdate, session: Session = Depends(get_session)): + order = session.get(Order, order_id) + if not order: + raise HTTPException(status_code=404, detail="Order not found") + + for key, value in order_update.dict(exclude_unset=True).items(): + setattr(order, key, value) + + session.add(order) + session.commit() + session.refresh(order) + return order + +@router.delete("/{order_id}") +def delete_order(order_id: int, session: Session = Depends(get_session)): + order = session.get(Order, order_id) + if not order: + raise HTTPException(status_code=404, detail="Order not found") + session.delete(order) + session.commit() + return {"message": "Order deleted successfully"} diff --git a/app/backend/routes/orderitem.py b/app/backend/routes/orderitem.py new file mode 100644 index 0000000000000000000000000000000000000000..e76ccacd4416e69e3c8ca9be7709c165d11d1916 --- /dev/null +++ b/app/backend/routes/orderitem.py @@ -0,0 +1,57 @@ +from fastapi import APIRouter, Depends, HTTPException +from sqlmodel import Session, select +from backend.models.models import OrderItem +from backend.schemas.orderitem import OrderItemRead, OrderItemCreate, OrderItemUpdate, OrderItemList +from backend.database import get_session + +router = APIRouter() + +@router.post("/", response_model=OrderItemRead) +def create_order_item(order_item: OrderItemCreate, session: Session = Depends(get_session)): + new_order_item = OrderItem(**order_item.dict()) + session.add(new_order_item) + session.commit() + session.refresh(new_order_item) + return new_order_item + +@router.get("/{order_item_id}", response_model=OrderItemRead) +def read_order_item(order_item_id: int, session: Session = Depends(get_session)): + order_item = session.get(OrderItem, order_item_id) + if not order_item: + raise HTTPException(status_code=404, detail="Order item not found") + return order_item + +@router.get("/order/{order_id}", response_model=OrderItemList) +def list_order_items(order_id: int, session: Session = Depends(get_session)): + items = session.exec(select(OrderItem).where(OrderItem.order_id == order_id)).all() + return {"items": items} + +@router.get("/{order_item_id}/subtotal", response_model=float) +def calculate_item_subtotal(order_item_id: int, session: Session = Depends(get_session)): + order_item = session.get(OrderItem, order_item_id) + if not order_item: + raise HTTPException(status_code=404, detail="Order item not found") + return order_item.price * order_item.quantity + +@router.put("/{order_item_id}", response_model=OrderItemRead) +def update_order_item(order_item_id: int, order_item_update: OrderItemUpdate, session: Session = Depends(get_session)): + order_item = session.get(OrderItem, order_item_id) + if not order_item: + raise HTTPException(status_code=404, detail="Order item not found") + + for key, value in order_item_update.dict(exclude_unset=True).items(): + setattr(order_item, key, value) + + session.add(order_item) + session.commit() + session.refresh(order_item) + return order_item + +@router.delete("/{order_item_id}") +def delete_order_item(order_item_id: int, session: Session = Depends(get_session)): + order_item = session.get(OrderItem, order_item_id) + if not order_item: + raise HTTPException(status_code=404, detail="Order item not found") + session.delete(order_item) + session.commit() + return {"message": "Order item deleted successfully"} diff --git a/app/backend/schemas/order.py b/app/backend/schemas/order.py new file mode 100644 index 0000000000000000000000000000000000000000..e8b6940e2e443d5b1e2063de2ef76d033d64c1a2 --- /dev/null +++ b/app/backend/schemas/order.py @@ -0,0 +1,31 @@ +from pydantic import BaseModel +from typing import Optional, List +from datetime import datetime +from .orderitem import OrderItemRead + +class OrderBase(BaseModel): + shop_id: int + total_price: float + status: Optional[str] = "pending" + +class OrderCreate(OrderBase): + pass + +class OrderRead(OrderBase): + id: int + user_id: int + created_at: datetime + + class Config: + orm_mode = True + +class OrderUpdate(BaseModel): + shop_id: Optional[int] = None + total_price: Optional[float] = None + status: Optional[str] = None + +class OrderList(BaseModel): + orders: List[OrderRead] + +class OrderWithItems(OrderRead): + order_items: List[OrderItemRead] = [] diff --git a/app/backend/schemas/orderitem.py b/app/backend/schemas/orderitem.py new file mode 100644 index 0000000000000000000000000000000000000000..591784ed298205ca8c94436d8f99c87363c5a07a --- /dev/null +++ b/app/backend/schemas/orderitem.py @@ -0,0 +1,26 @@ +from pydantic import BaseModel +from typing import Optional, List + +class OrderItemBase(BaseModel): + order_id: int + product_id: int + quantity: int + price: float + +class OrderItemCreate(OrderItemBase): + pass + +class OrderItemRead(OrderItemBase): + id: int + + class Config: + orm_mode = True + +class OrderItemUpdate(BaseModel): + order_id: Optional[int] = None + product_id: Optional[int] = None + quantity: Optional[int] = None + price: Optional[float] = None + +class OrderItemList(BaseModel): + items: List[OrderItemRead]