feat: 增加差旅报销标准测算和财务终审流程

新增差旅报销测算接口及 Spreadsheet 规则解析,审批流程拆分
直属领导审批与财务终审两阶段并细分权限,修复 PDF 文本层
缺失时自动回退 OCR,提交后清理关联会话,前端适配审批流
交互并补充单元测试。
This commit is contained in:
caoxiaozhu
2026-05-21 09:28:33 +08:00
parent 002bf4f756
commit 8f65661809
43 changed files with 4366 additions and 410 deletions

View File

@@ -20,9 +20,12 @@ from app.schemas.reimbursement import (
ExpenseClaimReturnPayload,
ReimbursementCreate,
ReimbursementRead,
TravelReimbursementCalculatorRequest,
TravelReimbursementCalculatorResponse,
)
from app.services.expense_claims import ExpenseClaimService
from app.services.reimbursement import ReimbursementService
from app.services.travel_reimbursement_calculator import TravelReimbursementCalculatorService
router = APIRouter()
DbSession = Annotated[Session, Depends(get_db)]
@@ -50,6 +53,29 @@ def create_reimbursement(payload: ReimbursementCreate, db: DbSession) -> Reimbur
return ReimbursementService(db).create_reimbursement(payload)
@router.post(
"/travel-calculator",
response_model=TravelReimbursementCalculatorResponse,
summary="差旅报销标准测算",
description="根据规则中心的差旅报销表、当前员工职级、出差天数与地点测算住宿和补贴参考金额。",
responses={
status.HTTP_400_BAD_REQUEST: {
"model": ErrorResponse,
"description": "测算入参或规则匹配失败。",
}
},
)
def calculate_travel_reimbursement(
payload: TravelReimbursementCalculatorRequest,
db: DbSession,
current_user: CurrentUser,
) -> TravelReimbursementCalculatorResponse:
try:
return TravelReimbursementCalculatorService(db).calculate(payload, current_user)
except ValueError as error:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(error)) from error
@router.get(
"/claims",
response_model=list[ExpenseClaimRead],
@@ -463,8 +489,8 @@ def return_expense_claim(
@router.post(
"/claims/{claim_id}/approve",
response_model=ExpenseClaimRead,
summary="直属领导审批通过报销单",
description="当前审批人确认报销信息无误后,将报销单从直属领导审批流转到财务审批。",
summary="审批通过报销单",
description="直属领导审批通过后流转到财务审批;财务终审通过后进入归档入账",
responses={
status.HTTP_404_NOT_FOUND: {
"model": ErrorResponse,
@@ -497,7 +523,7 @@ def approve_expense_claim(
"/claims/{claim_id}",
response_model=ExpenseClaimActionResponse,
summary="删除报销单",
description="普通用户仅可删除草稿待补充报销单;财务人员和高级管理人员可删除可见报销单。",
description="申请人仅可删除自己的草稿待补充或退回单据;高级管理人员可删除可见单据,财务人员没有删除权限",
responses={
status.HTTP_404_NOT_FOUND: {
"model": ErrorResponse,