from typing import List, Optional from fastapi import APIRouter, Depends from pydantic import BaseModel, ConfigDict, field_validator from sqlalchemy.orm import Session from models.capex import Capex from models.opex import Opex from routes.dependencies import get_db router = APIRouter(prefix="/api/costs", tags=["Costs"]) # Pydantic schemas for CAPEX and OPEX class _CostBase(BaseModel): scenario_id: int amount: float description: Optional[str] = None currency_code: str = "USD" @field_validator("currency_code") @classmethod def _normalize_currency(cls, value: Optional[str]) -> str: code = (value or "USD").strip().upper() return code[:3] if len(code) > 3 else code class CapexCreate(_CostBase): pass class CapexRead(_CostBase): id: int model_config = ConfigDict(from_attributes=True) class OpexCreate(_CostBase): pass class OpexRead(_CostBase): id: int model_config = ConfigDict(from_attributes=True) # Capex endpoints @router.post("/capex", response_model=CapexRead) def create_capex(item: CapexCreate, db: Session = Depends(get_db)): db_item = Capex(**item.model_dump()) db.add(db_item) db.commit() db.refresh(db_item) return db_item @router.get("/capex", response_model=List[CapexRead]) def list_capex(db: Session = Depends(get_db)): return db.query(Capex).all() # Opex endpoints @router.post("/opex", response_model=OpexRead) def create_opex(item: OpexCreate, db: Session = Depends(get_db)): db_item = Opex(**item.model_dump()) db.add(db_item) db.commit() db.refresh(db_item) return db_item @router.get("/opex", response_model=List[OpexRead]) def list_opex(db: Session = Depends(get_db)): return db.query(Opex).all()