feat(expenses): add transactional expense case events

This commit is contained in:
caoxiaozhu
2026-07-13 11:58:48 +08:00
parent 9a84e125d0
commit 661990b27b
21 changed files with 1973 additions and 63 deletions

View File

@@ -0,0 +1,42 @@
from __future__ import annotations
from typing import Annotated
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from app.api.deps import CurrentUserContext, get_current_user, get_db
from app.schemas.expense_case import ExpenseCaseTimelineRead
from app.services.expense_cases import ExpenseCaseService
from app.services.expense_claims import ExpenseClaimService
router = APIRouter(prefix="/expense-cases")
DbSession = Annotated[Session, Depends(get_db)]
CurrentUser = Annotated[CurrentUserContext, Depends(get_current_user)]
@router.get(
"/by-claim/{claim_id}",
response_model=ExpenseCaseTimelineRead,
summary="查询报销单所属费用事件时间线",
description="返回当前用户有权查看的费用事件、关联单据和结构化业务事件。",
)
def get_expense_case_by_claim(
claim_id: str,
db: DbSession,
current_user: CurrentUser,
) -> ExpenseCaseTimelineRead:
claim = ExpenseClaimService(db).get_claim(claim_id, current_user)
if claim is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="费用单据不存在。")
expense_case = ExpenseCaseService(db).get_timeline_for_claim(
claim.id,
tenant_id=current_user.tenant_id,
)
if expense_case is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="该单据尚未纳入统一费用事件。",
)
return ExpenseCaseTimelineRead.model_validate(expense_case)

View File

@@ -12,6 +12,7 @@ from app.api.v1.endpoints.auth import router as auth_router
from app.api.v1.endpoints.bootstrap import router as bootstrap_router
from app.api.v1.endpoints.budgets import router as budgets_router
from app.api.v1.endpoints.employees import router as employees_router
from app.api.v1.endpoints.expense_cases import router as expense_cases_router
from app.api.v1.endpoints.employee_profiles import router as employee_profiles_router
from app.api.v1.endpoints.health import router as health_router
from app.api.v1.endpoints.knowledge import router as knowledge_router
@@ -48,6 +49,7 @@ router.include_router(ontology_router, tags=["ontology"])
router.include_router(orchestrator_router, tags=["orchestrator"])
router.include_router(receipt_folder_router, tags=["receipt-folder"])
router.include_router(employees_router, prefix="/employees", tags=["employees"])
router.include_router(expense_cases_router, tags=["expense-cases"])
router.include_router(employee_profiles_router, tags=["employee-profiles"])
router.include_router(reimbursements_router, prefix="/reimbursements", tags=["reimbursements"])
router.include_router(risk_observations_router, tags=["risk-observations"])