
- Create project structure with FastAPI and SQLAlchemy - Implement database models for items, categories, suppliers, and stock movements - Add CRUD operations for all models - Configure Alembic for database migrations - Create RESTful API endpoints for inventory management - Add health endpoint for system monitoring - Update README with setup and usage instructions generated with BackendIM... (backend.im)
54 lines
2.0 KiB
Python
54 lines
2.0 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, status, Query
|
|
from sqlalchemy.orm import Session
|
|
from typing import List, Optional
|
|
from app.database import get_db
|
|
from app.schemas.stock_movement import StockMovementCreate, StockMovementResponse, StockMovementDetailResponse
|
|
from app.crud import stock_movement as stock_crud
|
|
|
|
router = APIRouter(
|
|
prefix="/stock",
|
|
tags=["Stock Management"]
|
|
)
|
|
|
|
@router.get("/movements", response_model=List[StockMovementResponse])
|
|
def get_stock_movements(
|
|
skip: int = 0,
|
|
limit: int = 100,
|
|
item_id: Optional[int] = None,
|
|
db: Session = Depends(get_db)
|
|
):
|
|
return stock_crud.get_stock_movements(db, skip=skip, limit=limit, item_id=item_id)
|
|
|
|
@router.get("/movements/{movement_id}", response_model=StockMovementDetailResponse)
|
|
def get_stock_movement(movement_id: int, db: Session = Depends(get_db)):
|
|
db_movement = stock_crud.get_stock_movement(db, movement_id=movement_id)
|
|
if db_movement is None:
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Stock movement not found")
|
|
|
|
# Convert related objects to dict for response
|
|
response = StockMovementDetailResponse.model_validate(db_movement)
|
|
|
|
if db_movement.item:
|
|
response.item = {
|
|
"id": db_movement.item.id,
|
|
"name": db_movement.item.name,
|
|
"sku": db_movement.item.sku
|
|
}
|
|
|
|
return response
|
|
|
|
@router.post("/movements", response_model=StockMovementResponse, status_code=status.HTTP_201_CREATED)
|
|
def create_stock_movement(movement: StockMovementCreate, db: Session = Depends(get_db)):
|
|
return stock_crud.create_stock_movement(db=db, movement=movement)
|
|
|
|
@router.get("/low-stock", response_model=List[ItemResponse])
|
|
def get_low_stock_items(db: Session = Depends(get_db)):
|
|
"""Get items where quantity is less than or equal to reorder level"""
|
|
from app.models.item import Item
|
|
|
|
low_stock_items = db.query(Item).filter(
|
|
Item.quantity <= Item.reorder_level,
|
|
Item.is_active == True
|
|
).all()
|
|
|
|
return low_stock_items |