198 lines
5.4 KiB
Python
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 |