# app/api/v1/public/vendors/orders.py """ Customer order endpoints (public-facing). """ import logging from typing import Optional from fastapi import APIRouter, Depends, Path, Query from sqlalchemy.orm import Session from app.core.database import get_db from app.services.order_service import order_service from app.services.customer_service import customer_service from models.schema.order import ( OrderCreate, OrderResponse, OrderDetailResponse, OrderListResponse ) from models.database.vendor import Vendor from models.database.customer import Customer router = APIRouter() logger = logging.getLogger(__name__) def get_current_customer( vendor_id: int, customer_id: int, db: Session ) -> Customer: """Helper to get and verify customer.""" customer = customer_service.get_customer( db=db, vendor_id=vendor_id, customer_id=customer_id ) return customer @router.post("/{vendor_id}/orders", response_model=OrderResponse) def place_order( vendor_id: int = Path(..., description="Vendor ID"), order_data: OrderCreate = ..., db: Session = Depends(get_db), ): """ Place a new order. Customer must be authenticated to place an order. This endpoint creates an order from the customer's cart. """ # Verify vendor exists and is active vendor = db.query(Vendor).filter( Vendor.id == vendor_id, Vendor.is_active == True ).first() if not vendor: from app.exceptions import VendorNotFoundException raise VendorNotFoundException(str(vendor_id), identifier_type="id") # Create order order = order_service.create_order( db=db, vendor_id=vendor_id, order_data=order_data ) logger.info( f"Order {order.order_number} placed for vendor {vendor.vendor_code}, " f"total: €{order.total_amount:.2f}" ) # TODO: Update customer stats # TODO: Clear cart # TODO: Send order confirmation email return OrderResponse.model_validate(order) @router.get("/{vendor_id}/customers/{customer_id}/orders", response_model=OrderListResponse) def get_customer_orders( vendor_id: int = Path(..., description="Vendor ID"), customer_id: int = Path(..., description="Customer ID"), skip: int = Query(0, ge=0), limit: int = Query(50, ge=1, le=100), db: Session = Depends(get_db), ): """ Get order history for customer. Returns all orders placed by the authenticated customer. """ # Verify vendor vendor = db.query(Vendor).filter( Vendor.id == vendor_id, Vendor.is_active == True ).first() if not vendor: from app.exceptions import VendorNotFoundException raise VendorNotFoundException(str(vendor_id), identifier_type="id") # Verify customer belongs to vendor customer = get_current_customer(vendor_id, customer_id, db) # Get orders orders, total = order_service.get_customer_orders( db=db, vendor_id=vendor_id, customer_id=customer_id, skip=skip, limit=limit ) return OrderListResponse( orders=[OrderResponse.model_validate(o) for o in orders], total=total, skip=skip, limit=limit ) @router.get("/{vendor_id}/customers/{customer_id}/orders/{order_id}", response_model=OrderDetailResponse) def get_customer_order_details( vendor_id: int = Path(..., description="Vendor ID"), customer_id: int = Path(..., description="Customer ID"), order_id: int = Path(..., description="Order ID"), db: Session = Depends(get_db), ): """ Get detailed order information for customer. Customer can only view their own orders. """ # Verify vendor vendor = db.query(Vendor).filter( Vendor.id == vendor_id, Vendor.is_active == True ).first() if not vendor: from app.exceptions import VendorNotFoundException raise VendorNotFoundException(str(vendor_id), identifier_type="id") # Verify customer customer = get_current_customer(vendor_id, customer_id, db) # Get order order = order_service.get_order( db=db, vendor_id=vendor_id, order_id=order_id ) # Verify order belongs to customer if order.customer_id != customer_id: from app.exceptions import OrderNotFoundException raise OrderNotFoundException(str(order_id)) return OrderDetailResponse.model_validate(order)