# -*- coding: utf-8 -*- """API-Routen für Abwesenheiten, Kontingente und Genehmigungen.""" import datetime from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from ..database import get_db from ..core.schemas import ( AbsenceCreate, AbsenceUpdate, AbsenceRead, BalanceRead, BalanceAdjust, ApprovalDecision, ) from ..core.enums import EmployeeRole from ..core.models import Employee from ..absences.service import AbsenceService from ..absences.rules import RuleViolation from .auth import get_current_user, require_role router = APIRouter(prefix="/absences", tags=["Abwesenheiten"]) @router.get("/", response_model=list[AbsenceRead]) def list_absences( year: Optional[int] = None, employee_id: Optional[str] = None, start: Optional[datetime.date] = None, end: Optional[datetime.date] = None, db: Session = Depends(get_db), _user: Employee = Depends(get_current_user), ): svc = AbsenceService(db) if employee_id: return svc.get_absences_for_employee(employee_id, year) if start and end: return svc.get_absences_for_period(start, end) return svc.get_all_absences(year) @router.post("/", response_model=AbsenceRead, status_code=201) def create_absence( data: AbsenceCreate, db: Session = Depends(get_db), user: Employee = Depends(get_current_user), ): svc = AbsenceService(db) try: return svc.create_absence(data) except RuleViolation as e: raise HTTPException(422, detail={"rule": e.rule, "message": e.message}) except ValueError as e: raise HTTPException(400, str(e)) @router.patch("/{absence_id}", response_model=AbsenceRead) def update_absence( absence_id: str, data: AbsenceUpdate, db: Session = Depends(get_db), _user: Employee = Depends(get_current_user), ): svc = AbsenceService(db) try: result = svc.update_absence(absence_id, data) except RuleViolation as e: raise HTTPException(422, detail={"rule": e.rule, "message": e.message}) if not result: raise HTTPException(404, "Abwesenheit nicht gefunden") return result @router.delete("/{absence_id}", status_code=204) def delete_absence( absence_id: str, db: Session = Depends(get_db), _user: Employee = Depends(get_current_user), ): svc = AbsenceService(db) if not svc.delete_absence(absence_id): raise HTTPException(404, "Abwesenheit nicht gefunden") @router.post("/approve", response_model=AbsenceRead) def approve_absence( decision: ApprovalDecision, db: Session = Depends(get_db), _user: Employee = Depends(require_role(EmployeeRole.ADMIN, EmployeeRole.MANAGER)), ): svc = AbsenceService(db) try: return svc.approve(decision) except ValueError as e: raise HTTPException(400, str(e)) # ── Kontingent / Balance ──────────────────────────────────── balance_router = APIRouter(prefix="/balance", tags=["Ferientage-Kontingent"]) @balance_router.get("/{employee_id}/{year}", response_model=BalanceRead) def get_balance( employee_id: str, year: int, db: Session = Depends(get_db), _user: Employee = Depends(get_current_user), ): svc = AbsenceService(db) try: return svc.get_balance(employee_id, year) except ValueError as e: raise HTTPException(404, str(e)) @balance_router.patch("/{employee_id}/{year}", response_model=BalanceRead) def adjust_balance( employee_id: str, year: int, data: BalanceAdjust, db: Session = Depends(get_db), _user: Employee = Depends(require_role(EmployeeRole.ADMIN, EmployeeRole.MANAGER)), ): svc = AbsenceService(db) try: return svc.adjust_balance(employee_id, year, data) except ValueError as e: raise HTTPException(404, str(e))