Automated Action 4aac37bc90 Implement inventory management system with FastAPI and SQLite
- Setup project structure with FastAPI application
- Create database models with SQLAlchemy
- Configure Alembic for database migrations
- Implement CRUD operations for products, categories, suppliers
- Add inventory transaction functionality
- Implement user authentication with JWT
- Add health check endpoint
- Create comprehensive documentation
2025-06-05 11:43:07 +00:00

206 lines
6.6 KiB
Python

from typing import Any, List, Optional
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app import crud, models, schemas
from app.api import deps
router = APIRouter()
@router.get("/", response_model=List[schemas.Product])
def read_products(
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
category_id: Optional[int] = None,
supplier_id: Optional[int] = None,
low_stock: bool = False,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Retrieve products.
"""
if category_id:
products = crud.product.get_by_category(
db, category_id=category_id, skip=skip, limit=limit
)
elif supplier_id:
products = crud.product.get_by_supplier(
db, supplier_id=supplier_id, skip=skip, limit=limit
)
elif low_stock:
products = crud.product.get_low_stock_products(db, skip=skip, limit=limit)
else:
products = crud.product.get_multi(db, skip=skip, limit=limit)
return products
@router.post("/", response_model=schemas.Product)
def create_product(
*,
db: Session = Depends(deps.get_db),
product_in: schemas.ProductCreate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Create new product.
"""
# Check if SKU already exists
product = crud.product.get_by_sku(db, sku=product_in.sku)
if product:
raise HTTPException(
status_code=400,
detail="The product with this SKU already exists in the system.",
)
# Check if barcode already exists if provided
if product_in.barcode:
product = crud.product.get_by_barcode(db, barcode=product_in.barcode)
if product:
raise HTTPException(
status_code=400,
detail="The product with this barcode already exists in the system.",
)
# Check if category exists if provided
if product_in.category_id:
category = crud.category.get(db, id=product_in.category_id)
if not category:
raise HTTPException(
status_code=404,
detail="The category does not exist in the system.",
)
# Check if supplier exists if provided
if product_in.supplier_id:
supplier = crud.supplier.get(db, id=product_in.supplier_id)
if not supplier:
raise HTTPException(
status_code=404,
detail="The supplier does not exist in the system.",
)
product = crud.product.create(db, obj_in=product_in)
return product
@router.get("/{product_id}", response_model=schemas.Product)
def read_product(
*,
db: Session = Depends(deps.get_db),
product_id: int,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get product by ID.
"""
product = crud.product.get(db, id=product_id)
if not product:
raise HTTPException(status_code=404, detail="Product not found")
return product
@router.put("/{product_id}", response_model=schemas.Product)
def update_product(
*,
db: Session = Depends(deps.get_db),
product_id: int,
product_in: schemas.ProductUpdate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update a product.
"""
product = crud.product.get(db, id=product_id)
if not product:
raise HTTPException(status_code=404, detail="Product not found")
# If SKU is being updated, check for duplicates
if product_in.sku and product_in.sku != product.sku:
existing_product = crud.product.get_by_sku(db, sku=product_in.sku)
if existing_product:
raise HTTPException(
status_code=400,
detail="The product with this SKU already exists in the system.",
)
# If barcode is being updated, check for duplicates
if product_in.barcode and product_in.barcode != product.barcode:
existing_product = crud.product.get_by_barcode(db, barcode=product_in.barcode)
if existing_product:
raise HTTPException(
status_code=400,
detail="The product with this barcode already exists in the system.",
)
# Check if category exists if provided
if product_in.category_id:
category = crud.category.get(db, id=product_in.category_id)
if not category:
raise HTTPException(
status_code=404,
detail="The category does not exist in the system.",
)
# Check if supplier exists if provided
if product_in.supplier_id:
supplier = crud.supplier.get(db, id=product_in.supplier_id)
if not supplier:
raise HTTPException(
status_code=404,
detail="The supplier does not exist in the system.",
)
product = crud.product.update(db, db_obj=product, obj_in=product_in)
return product
@router.delete("/{product_id}", response_model=schemas.Product)
def delete_product(
*,
db: Session = Depends(deps.get_db),
product_id: int,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Delete a product.
"""
product = crud.product.get(db, id=product_id)
if not product:
raise HTTPException(status_code=404, detail="Product not found")
product = crud.product.remove(db, id=product_id)
return product
@router.post("/{product_id}/adjust", response_model=schemas.Product)
def adjust_product_quantity(
*,
db: Session = Depends(deps.get_db),
product_id: int,
adjustment: schemas.ProductAdjustment,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Adjust product quantity and create an inventory transaction.
"""
product = crud.product.get(db, id=product_id)
if not product:
raise HTTPException(status_code=404, detail="Product not found")
# Create an inventory adjustment transaction
transaction_in = schemas.InventoryTransactionCreate(
transaction_type=models.inventory_transaction.TransactionType.ADJUSTMENT,
quantity=adjustment.quantity,
unit_price=product.unit_price,
notes=adjustment.notes,
product_id=product_id,
)
# Create the transaction and update the product quantity
crud.inventory_transaction.create_with_product_update(
db, obj_in=transaction_in, current_user_id=current_user.id
)
# Return the updated product
db.refresh(product)
return product