Automated Action b8143c43e4 Implement ecommerce authentication and inventory API
- Set up project structure and FastAPI application
- Create database models for users, products, and inventory
- Configure SQLAlchemy and Alembic for database management
- Implement JWT authentication
- Create API endpoints for user, product, and inventory management
- Add admin-only routes and authorization middleware
- Add health check endpoint
- Update README with documentation
- Lint and fix code issues
2025-06-08 21:40:55 +00:00

226 lines
7.2 KiB
Python

from typing import Any, List, Optional
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from app import crud, models, schemas
from app.api import deps
from app.models.inventory import InventoryStatus
router = APIRouter()
# Inventory Item endpoints
@router.get("/items/", response_model=List[schemas.InventoryItemWithProduct])
def read_inventory_items(
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
status: Optional[InventoryStatus] = None,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Retrieve inventory items with optional filtering.
"""
items = crud.inventory.get_all_inventory_items(
db,
skip=skip,
limit=limit,
status=status
)
return items
@router.post("/items/", response_model=schemas.InventoryItem)
def create_inventory_item(
*,
db: Session = Depends(deps.get_db),
item_in: schemas.InventoryItemCreate,
current_user: models.User = Depends(deps.get_current_admin_user),
) -> Any:
"""
Create new inventory item. Admin only.
"""
# Check if product exists
product = crud.product.get_product_by_id(db, product_id=item_in.product_id)
if not product:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Product not found",
)
# Check if inventory item for this product already exists
existing_item = crud.inventory.get_inventory_item_by_product_id(db, product_id=item_in.product_id)
if existing_item:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Inventory item for this product already exists",
)
# Create inventory item
item = crud.inventory.create_inventory_item(db, obj_in=item_in)
# Create initial inventory transaction
if item_in.quantity > 0:
transaction_in = schemas.InventoryTransactionCreate(
product_id=item_in.product_id,
quantity_change=item_in.quantity,
notes="Initial inventory",
transaction_by=current_user.id
)
crud.inventory.create_transaction(db, obj_in=transaction_in)
return item
@router.get("/items/{item_id}", response_model=schemas.InventoryItemWithProduct)
def read_inventory_item(
*,
db: Session = Depends(deps.get_db),
item_id: str,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get inventory item by ID.
"""
item = crud.inventory.get_inventory_item_by_id(db, item_id=item_id)
if not item:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Inventory item not found",
)
return item
@router.put("/items/{item_id}", response_model=schemas.InventoryItem)
def update_inventory_item(
*,
db: Session = Depends(deps.get_db),
item_id: str,
item_in: schemas.InventoryItemUpdate,
current_user: models.User = Depends(deps.get_current_admin_user),
) -> Any:
"""
Update an inventory item. Admin only.
"""
item = crud.inventory.get_inventory_item_by_id(db, item_id=item_id)
if not item:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Inventory item not found",
)
# Create transaction if quantity is being updated
if item_in.quantity is not None and item_in.quantity != item.quantity:
quantity_change = item_in.quantity - item.quantity
transaction_in = schemas.InventoryTransactionCreate(
product_id=item.product_id,
quantity_change=quantity_change,
notes=f"Manual inventory adjustment from {item.quantity} to {item_in.quantity}",
transaction_by=current_user.id
)
crud.inventory.create_transaction(db, obj_in=transaction_in)
item = crud.inventory.update_inventory_item(db, db_obj=item, obj_in=item_in)
return item
@router.delete("/items/{item_id}", response_model=schemas.InventoryItem, status_code=status.HTTP_200_OK)
def delete_inventory_item(
*,
db: Session = Depends(deps.get_db),
item_id: str,
current_user: models.User = Depends(deps.get_current_admin_user),
) -> Any:
"""
Delete an inventory item. Admin only.
"""
item = crud.inventory.get_inventory_item_by_id(db, item_id=item_id)
if not item:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Inventory item not found",
)
item = crud.inventory.delete_inventory_item(db, item_id=item_id)
return item
# Inventory Transaction endpoints
@router.get("/transactions/", response_model=List[schemas.InventoryTransaction])
def read_transactions(
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
product_id: Optional[str] = None,
current_user: models.User = Depends(deps.get_current_admin_user),
) -> Any:
"""
Retrieve inventory transactions. Admin only.
"""
if product_id:
transactions = crud.inventory.get_transactions_by_product_id(
db,
product_id=product_id,
skip=skip,
limit=limit
)
else:
# Get all transactions - would need to add a method for this
# For now, we'll just return an empty list
transactions = []
return transactions
@router.post("/transactions/", response_model=schemas.InventoryTransaction)
def create_transaction(
*,
db: Session = Depends(deps.get_db),
transaction_in: schemas.InventoryTransactionCreate,
current_user: models.User = Depends(deps.get_current_admin_user),
) -> Any:
"""
Create new inventory transaction. Admin only.
"""
# Check if product exists
product = crud.product.get_product_by_id(db, product_id=transaction_in.product_id)
if not product:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Product not found",
)
# Check if inventory item exists for this product
inventory_item = crud.inventory.get_inventory_item_by_product_id(db, product_id=transaction_in.product_id)
if not inventory_item:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="No inventory item found for this product",
)
# Set the current user as the transaction creator if not specified
if transaction_in.transaction_by is None:
transaction_in.transaction_by = current_user.id
transaction = crud.inventory.create_transaction(db, obj_in=transaction_in)
return transaction
@router.get("/transactions/{transaction_id}", response_model=schemas.InventoryTransaction)
def read_transaction(
*,
db: Session = Depends(deps.get_db),
transaction_id: str,
current_user: models.User = Depends(deps.get_current_admin_user),
) -> Any:
"""
Get transaction by ID. Admin only.
"""
transaction = crud.inventory.get_transaction_by_id(db, transaction_id=transaction_id)
if not transaction:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Transaction not found",
)
return transaction