from fastapi import APIRouter, Depends, HTTPException, status from sqlmodel import Session, select from app.core.db import get_session from app.core.auth import require_any_access, require_write_access, require_admin from app.schemas.models import Transaction_details, Partner, Product from app.schemas.schemas import ( TransactionDetailsCreate, TransactionDetailsUpdate, TransactionDetailsResponse, UserResponse ) from typing import List router = APIRouter(prefix="/transaction-details", tags=["transaction-details"]) # Create Transaction Details @router.post("/", response_model=TransactionDetailsResponse, status_code=status.HTTP_201_CREATED) def create_transaction_details( transaction_details: TransactionDetailsCreate, session: Session = Depends(get_session), current_user: UserResponse = Depends(require_write_access) ): """Create new transaction details (requires write access).""" # Validate partner exists partner = session.get(Partner, transaction_details.partner_id) if not partner: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Partner not found" ) # Validate product exists product = session.get(Product, transaction_details.product_id) if not product: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Product not found" ) # Create transaction details with audit fields transaction_details_data = transaction_details.model_dump() transaction_details_data["created_by"] = current_user.id transaction_details_data["updated_by"] = current_user.id db_transaction_details = Transaction_details(**transaction_details_data) session.add(db_transaction_details) session.commit() session.refresh(db_transaction_details) return db_transaction_details # Read all Transaction Details @router.get("/", response_model=List[TransactionDetailsResponse]) def read_transaction_details( skip: int = 0, limit: int = 100, session: Session = Depends(get_session), current_user: UserResponse = Depends(require_any_access) ): """Get all transaction details (requires authentication).""" transaction_details = session.exec( select(Transaction_details).offset(skip).limit(limit) ).all() return transaction_details # Read Transaction Details by partner @router.get("/partner/{partner_id}", response_model=List[TransactionDetailsResponse]) def read_transaction_details_by_partner( partner_id: int, skip: int = 0, limit: int = 100, session: Session = Depends(get_session), current_user: UserResponse = Depends(require_any_access) ): """Get transaction details for a specific partner (requires authentication).""" # Validate partner exists partner = session.get(Partner, partner_id) if not partner: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Partner not found" ) statement = select(Transaction_details).where( Transaction_details.partner_id == partner_id ).offset(skip).limit(limit) transaction_details = session.exec(statement).all() return transaction_details # Read Transaction Details by product @router.get("/product/{product_id}", response_model=List[TransactionDetailsResponse]) def read_transaction_details_by_product( product_id: int, skip: int = 0, limit: int = 100, session: Session = Depends(get_session), current_user: UserResponse = Depends(require_any_access) ): """Get transaction details for a specific product (requires authentication).""" # Validate product exists product = session.get(Product, product_id) if not product: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Product not found" ) statement = select(Transaction_details).where( Transaction_details.product_id == product_id ).offset(skip).limit(limit) transaction_details = session.exec(statement).all() return transaction_details # Read single Transaction Details by ID @router.get("/{transaction_details_id}", response_model=TransactionDetailsResponse) def read_transaction_details_by_id( transaction_details_id: int, session: Session = Depends(get_session), current_user: UserResponse = Depends(require_any_access) ): """Get specific transaction details by ID (requires authentication).""" transaction_details = session.get(Transaction_details, transaction_details_id) if not transaction_details: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Transaction details not found" ) return transaction_details # Update Transaction Details @router.put("/{transaction_details_id}", response_model=TransactionDetailsResponse) def update_transaction_details( transaction_details_id: int, transaction_details: TransactionDetailsUpdate, session: Session = Depends(get_session), current_user: UserResponse = Depends(require_write_access) ): """Update specific transaction details (requires write access).""" db_transaction_details = session.get(Transaction_details, transaction_details_id) if not db_transaction_details: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Transaction details not found" ) update_data = transaction_details.model_dump(exclude_unset=True) # Validate partner if being updated if "partner_id" in update_data: partner = session.get(Partner, update_data["partner_id"]) if not partner: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Partner not found" ) # Validate product if being updated if "product_id" in update_data: product = session.get(Product, update_data["product_id"]) if not product: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Product not found" ) # Track who updated update_data["updated_by"] = current_user.id # Update transaction details for key, value in update_data.items(): setattr(db_transaction_details, key, value) session.add(db_transaction_details) session.commit() session.refresh(db_transaction_details) return db_transaction_details # Delete Transaction Details @router.delete("/{transaction_details_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_transaction_details( transaction_details_id: int, session: Session = Depends(get_session), current_user: UserResponse = Depends(require_admin) ): """Delete specific transaction details (admin only).""" transaction_details = session.get(Transaction_details, transaction_details_id) if not transaction_details: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Transaction details not found" ) session.delete(transaction_details) session.commit() return None