2025-06-01 10:05:16 +00:00

198 lines
5.4 KiB
Python

from typing import Any, List, Optional
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from app.api.deps import get_current_user
from app.crud import category, item
from app.db.utils import get_db
from app.models.user import User
from app.schemas.item import Item, ItemCreate, ItemUpdate
router = APIRouter()
@router.get("/", response_model=List[Item])
def read_items(
db: Session = Depends(get_db),
skip: int = 0,
limit: int = 100,
category_id: Optional[int] = None,
low_stock: Optional[bool] = False,
name: Optional[str] = None,
current_user: User = Depends(get_current_user),
) -> Any:
"""
Retrieve items.
- Optional filter by category_id
- Optional filter for low stock items
- Optional search by name
"""
if low_stock:
items = item.get_low_stock_items(db, skip=skip, limit=limit)
elif category_id:
items = item.get_by_category_id(
db, category_id=category_id, skip=skip, limit=limit
)
elif name:
items = item.get_by_name(db, name=name)
else:
items = item.get_multi(db, skip=skip, limit=limit)
return items
@router.post("/", response_model=Item)
def create_item(
*,
db: Session = Depends(get_db),
item_in: ItemCreate,
current_user: User = Depends(get_current_user),
) -> Any:
"""
Create new item.
"""
# Check if SKU already exists
if item.get_by_sku(db, sku=item_in.sku):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="An item with this SKU already exists.",
)
# Check if category exists if provided
if item_in.category_id is not None:
db_category = category.get(db, id=item_in.category_id)
if not db_category:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Category not found",
)
# Create item with current user as owner
return item.create_with_owner(db, obj_in=item_in, owner_id=current_user.id)
@router.get("/{id}", response_model=Item)
def read_item(
*,
db: Session = Depends(get_db),
id: int,
current_user: User = Depends(get_current_user),
) -> Any:
"""
Get item by ID.
"""
db_item = item.get(db, id=id)
if not db_item:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Item not found",
)
return db_item
@router.put("/{id}", response_model=Item)
def update_item(
*,
db: Session = Depends(get_db),
id: int,
item_in: ItemUpdate,
current_user: User = Depends(get_current_user),
) -> Any:
"""
Update an item.
"""
db_item = item.get(db, id=id)
if not db_item:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Item not found",
)
# Check if SKU is being updated and ensure it doesn't conflict
if item_in.sku and item_in.sku != db_item.sku:
existing_item = item.get_by_sku(db, sku=item_in.sku)
if existing_item:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="An item with this SKU already exists.",
)
# Check if category exists if provided
if item_in.category_id is not None:
db_category = category.get(db, id=item_in.category_id)
if not db_category:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Category not found",
)
# Only superusers or the owner can update items
if not current_user.is_superuser and db_item.owner_id != current_user.id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Not enough permissions",
)
return item.update(db, db_obj=db_item, obj_in=item_in)
@router.delete("/{id}", response_model=Item)
def delete_item(
*,
db: Session = Depends(get_db),
id: int,
current_user: User = Depends(get_current_user),
) -> Any:
"""
Delete an item.
"""
db_item = item.get(db, id=id)
if not db_item:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Item not found",
)
# Only superusers or the owner can delete items
if not current_user.is_superuser and db_item.owner_id != current_user.id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Not enough permissions",
)
return item.remove(db, id=id)
@router.get("/by-sku/{sku}", response_model=Item)
def read_item_by_sku(
*,
db: Session = Depends(get_db),
sku: str,
current_user: User = Depends(get_current_user),
) -> Any:
"""
Get item by SKU.
"""
db_item = item.get_by_sku(db, sku=sku)
if not db_item:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Item not found",
)
return db_item
@router.get("/low-stock/", response_model=List[Item])
def read_low_stock_items(
db: Session = Depends(get_db),
skip: int = 0,
limit: int = 100,
current_user: User = Depends(get_current_user),
) -> Any:
"""
Retrieve items with stock below reorder level.
"""
items = item.get_low_stock_items(db, skip=skip, limit=limit)
return items