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