from datetime import datetime from fastapi import APIRouter, Depends, HTTPException, Path from sqlmodel import Session, col, select from app.auth import get_current_user from app.db import get_session from app.models.models import ( SavingsAccrual, SavingsAccrualCreate, SavingsAccrualRead, SavingsAccrualUpdate, ) router = APIRouter(prefix="/savings-accrual", tags=["savings-accrual"]) @router.get("/", response_model=list[SavingsAccrualRead]) def list_accruals( session: Session = Depends(get_session), _user: str = Depends(get_current_user), ): query = select(SavingsAccrual).order_by( col(SavingsAccrual.year).desc(), col(SavingsAccrual.month).desc() ) return session.exec(query).all() @router.post("/", response_model=SavingsAccrualRead, status_code=201) def create_accrual( data: SavingsAccrualCreate, session: Session = Depends(get_session), _user: str = Depends(get_current_user), ): existing = session.exec( select(SavingsAccrual).where( SavingsAccrual.year == data.year, SavingsAccrual.month == data.month, ) ).first() if existing: raise HTTPException( status_code=409, detail=f"Accrual for {data.year}-{data.month:02d} already exists (id={existing.id})", ) accrual = SavingsAccrual.model_validate(data) accrual.applied_at = datetime.utcnow() session.add(accrual) session.commit() session.refresh(accrual) return accrual @router.patch("/{accrual_id}", response_model=SavingsAccrualRead) def update_accrual( accrual_id: int, data: SavingsAccrualUpdate, session: Session = Depends(get_session), _user: str = Depends(get_current_user), ): accrual = session.get(SavingsAccrual, accrual_id) if not accrual: raise HTTPException(status_code=404, detail="Accrual not found") update_data = data.model_dump(exclude_unset=True) for key, value in update_data.items(): setattr(accrual, key, value) session.add(accrual) session.commit() session.refresh(accrual) return accrual @router.delete("/{accrual_id}", status_code=204) def delete_accrual( accrual_id: int = Path(...), session: Session = Depends(get_session), _user: str = Depends(get_current_user), ): accrual = session.get(SavingsAccrual, accrual_id) if not accrual: raise HTTPException(status_code=404, detail="Accrual not found") session.delete(accrual) session.commit()