# app/api/v1/vendor/inventory.py """ Vendor inventory management endpoints. Vendor Context: Uses token_vendor_id from JWT token (authenticated vendor API pattern) """ import logging from fastapi import APIRouter, Depends, Query from sqlalchemy.orm import Session from app.api.deps import get_current_vendor_api from app.core.database import get_db from app.exceptions import InvalidTokenException from app.services.inventory_service import inventory_service from models.database.user import User from models.schema.inventory import ( InventoryAdjust, InventoryCreate, InventoryListResponse, InventoryReserve, InventoryResponse, InventoryUpdate, ProductInventorySummary, ) router = APIRouter() logger = logging.getLogger(__name__) def _get_vendor_id_from_token(current_user: User) -> int: """Helper to get vendor_id from JWT token.""" if not hasattr(current_user, "token_vendor_id"): raise InvalidTokenException("Token missing vendor information. Please login again.") return current_user.token_vendor_id @router.post("/inventory/set", response_model=InventoryResponse) def set_inventory( inventory: InventoryCreate, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """Set exact inventory quantity (replaces existing).""" vendor_id = _get_vendor_id_from_token(current_user) return inventory_service.set_inventory(db, vendor_id, inventory) @router.post("/inventory/adjust", response_model=InventoryResponse) def adjust_inventory( adjustment: InventoryAdjust, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """Adjust inventory (positive to add, negative to remove).""" vendor_id = _get_vendor_id_from_token(current_user) return inventory_service.adjust_inventory(db, vendor_id, adjustment) @router.post("/inventory/reserve", response_model=InventoryResponse) def reserve_inventory( reservation: InventoryReserve, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """Reserve inventory for an order.""" vendor_id = _get_vendor_id_from_token(current_user) return inventory_service.reserve_inventory(db, vendor_id, reservation) @router.post("/inventory/release", response_model=InventoryResponse) def release_reservation( reservation: InventoryReserve, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """Release reserved inventory (cancel order).""" vendor_id = _get_vendor_id_from_token(current_user) return inventory_service.release_reservation(db, vendor_id, reservation) @router.post("/inventory/fulfill", response_model=InventoryResponse) def fulfill_reservation( reservation: InventoryReserve, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """Fulfill reservation (complete order, remove from stock).""" vendor_id = _get_vendor_id_from_token(current_user) return inventory_service.fulfill_reservation(db, vendor_id, reservation) @router.get("/inventory/product/{product_id}", response_model=ProductInventorySummary) def get_product_inventory( product_id: int, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """Get inventory summary for a product.""" vendor_id = _get_vendor_id_from_token(current_user) return inventory_service.get_product_inventory(db, vendor_id, product_id) @router.get("/inventory", response_model=InventoryListResponse) def get_vendor_inventory( skip: int = Query(0, ge=0), limit: int = Query(100, ge=1, le=1000), location: str | None = Query(None), low_stock: int | None = Query(None, ge=0), current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """Get all inventory for vendor.""" vendor_id = _get_vendor_id_from_token(current_user) inventories = inventory_service.get_vendor_inventory( db, vendor_id, skip, limit, location, low_stock ) # Get total count total = len(inventories) # You might want a separate count query for large datasets return InventoryListResponse( inventories=inventories, total=total, skip=skip, limit=limit ) @router.put("/inventory/{inventory_id}", response_model=InventoryResponse) def update_inventory( inventory_id: int, inventory_update: InventoryUpdate, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """Update inventory entry.""" vendor_id = _get_vendor_id_from_token(current_user) return inventory_service.update_inventory( db, vendor_id, inventory_id, inventory_update ) @router.delete("/inventory/{inventory_id}") def delete_inventory( inventory_id: int, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """Delete inventory entry.""" vendor_id = _get_vendor_id_from_token(current_user) inventory_service.delete_inventory(db, vendor_id, inventory_id) return {"message": "Inventory deleted successfully"}