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 Partner from app.schemas.schemas import ( PartnerCreate, PartnerUpdate, PartnerResponse, UserResponse ) from typing import List router = APIRouter(prefix="/partners", tags=["partners"]) # Create Partner @router.post("/", response_model=PartnerResponse, status_code=status.HTTP_201_CREATED) def create_partner( partner: PartnerCreate, session: Session = Depends(get_session), current_user: UserResponse = Depends(require_write_access) ): """Create a new partner (requires write access).""" # Check if TIN number already exists statement = select(Partner).where(Partner.tin_number == partner.tin_number) existing_partner = session.exec(statement).first() if existing_partner: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Partner with this TIN number already exists" ) # Create new partner partner_data = partner.model_dump() db_partner = Partner(**partner_data) session.add(db_partner) session.commit() session.refresh(db_partner) return db_partner # Read all Partners @router.get("/", response_model=List[PartnerResponse]) def read_partners( skip: int = 0, limit: int = 100, session: Session = Depends(get_session), current_user: UserResponse = Depends(require_any_access) ): """Get all partners (requires authentication).""" partners = session.exec(select(Partner).offset(skip).limit(limit)).all() return partners # Read single Partner by ID @router.get("/{partner_id}", response_model=PartnerResponse) def read_partner( partner_id: int, session: Session = Depends(get_session), current_user: UserResponse = Depends(require_any_access) ): """Get specific partner by ID (requires authentication).""" partner = session.get(Partner, partner_id) if not partner: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Partner not found" ) return partner # Update Partner @router.put("/{partner_id}", response_model=PartnerResponse) def update_partner( partner_id: int, partner: PartnerUpdate, session: Session = Depends(get_session), current_user: UserResponse = Depends(require_write_access) ): """Update specific partner (requires write access).""" db_partner = session.get(Partner, partner_id) if not db_partner: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Partner not found" ) # Check for TIN number conflicts if updating TIN update_data = partner.model_dump(exclude_unset=True) if "tin_number" in update_data: statement = select(Partner).where( Partner.tin_number == update_data["tin_number"], Partner.id != partner_id ) existing_partner = session.exec(statement).first() if existing_partner: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Partner with this TIN number already exists" ) # Update partner for key, value in update_data.items(): setattr(db_partner, key, value) session.add(db_partner) session.commit() session.refresh(db_partner) return db_partner # Delete Partner @router.delete("/{partner_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_partner( partner_id: int, session: Session = Depends(get_session), current_user: UserResponse = Depends(require_admin) ): """Delete specific partner (admin only).""" partner = session.get(Partner, partner_id) if not partner: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Partner not found" ) session.delete(partner) session.commit() return None