
- 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
113 lines
4.1 KiB
Python
113 lines
4.1 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
|
|
from app.models.inventory_transaction import TransactionType
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/transactions/", response_model=List[schemas.InventoryTransaction])
|
|
def read_inventory_transactions(
|
|
db: Session = Depends(deps.get_db),
|
|
skip: int = 0,
|
|
limit: int = 100,
|
|
product_id: Optional[int] = None,
|
|
user_id: Optional[int] = None,
|
|
transaction_type: Optional[TransactionType] = None,
|
|
current_user: models.User = Depends(deps.get_current_active_user),
|
|
) -> Any:
|
|
"""
|
|
Retrieve inventory transactions.
|
|
"""
|
|
if product_id:
|
|
transactions = crud.inventory_transaction.get_by_product(
|
|
db, product_id=product_id, skip=skip, limit=limit
|
|
)
|
|
elif user_id:
|
|
if user_id != current_user.id and not crud.user.is_superuser(current_user):
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail="The user doesn't have enough privileges to access other users' transactions"
|
|
)
|
|
transactions = crud.inventory_transaction.get_by_user(
|
|
db, user_id=user_id, skip=skip, limit=limit
|
|
)
|
|
elif transaction_type:
|
|
transactions = crud.inventory_transaction.get_by_type(
|
|
db, transaction_type=transaction_type, skip=skip, limit=limit
|
|
)
|
|
else:
|
|
transactions = crud.inventory_transaction.get_multi(db, skip=skip, limit=limit)
|
|
return transactions
|
|
|
|
|
|
@router.post("/transactions/", response_model=schemas.InventoryTransaction)
|
|
def create_inventory_transaction(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
transaction_in: schemas.InventoryTransactionCreate,
|
|
current_user: models.User = Depends(deps.get_current_active_user),
|
|
) -> Any:
|
|
"""
|
|
Create new inventory transaction.
|
|
"""
|
|
# Check if the product exists
|
|
product = crud.product.get(db, id=transaction_in.product_id)
|
|
if not product:
|
|
raise HTTPException(
|
|
status_code=404,
|
|
detail="The product does not exist in the system.",
|
|
)
|
|
|
|
# For sales, check if there's enough quantity
|
|
if (transaction_in.transaction_type == TransactionType.SALE and
|
|
transaction_in.quantity > product.quantity):
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail=f"Not enough inventory. Current stock: {product.quantity}",
|
|
)
|
|
|
|
# Create the transaction and update the product quantity
|
|
transaction = crud.inventory_transaction.create_with_product_update(
|
|
db, obj_in=transaction_in, current_user_id=current_user.id
|
|
)
|
|
return transaction
|
|
|
|
|
|
@router.get("/transactions/{transaction_id}", response_model=schemas.InventoryTransaction)
|
|
def read_inventory_transaction(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
transaction_id: int,
|
|
current_user: models.User = Depends(deps.get_current_active_user),
|
|
) -> Any:
|
|
"""
|
|
Get inventory transaction by ID.
|
|
"""
|
|
transaction = crud.inventory_transaction.get(db, id=transaction_id)
|
|
if not transaction:
|
|
raise HTTPException(status_code=404, detail="Inventory transaction not found")
|
|
return transaction
|
|
|
|
|
|
@router.delete("/transactions/{transaction_id}", response_model=schemas.InventoryTransaction)
|
|
def delete_inventory_transaction(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
transaction_id: int,
|
|
current_user: models.User = Depends(deps.get_current_active_superuser),
|
|
) -> Any:
|
|
"""
|
|
Delete an inventory transaction (admin only).
|
|
"""
|
|
transaction = crud.inventory_transaction.get(db, id=transaction_id)
|
|
if not transaction:
|
|
raise HTTPException(status_code=404, detail="Inventory transaction not found")
|
|
|
|
# This is a simplified approach - a proper implementation would include logic
|
|
# to reverse the product quantity change that occurred when the transaction was created
|
|
# For now, we'll just delete the transaction
|
|
transaction = crud.inventory_transaction.remove(db, id=transaction_id)
|
|
return transaction |