test: 同步报销审批流与预算分析测试

- 新增预算审批合并、风险标记去重与占位条目校验用例
- 补充预算分析对当前审核人与财务的可见性断言
- 调整单据删除权限测试以匹配 admin 限制
This commit is contained in:
caoxiaozhu
2026-06-17 14:39:26 +08:00
parent 0fac8b615f
commit 4199feb681
10 changed files with 907 additions and 42 deletions

View File

@@ -313,15 +313,34 @@ def test_budget_analysis_endpoint_is_limited_to_budget_roles() -> None:
with session_factory() as db:
seed_budget_allocations(db)
budget_role, market_department = seed_market_budget_monitor(db)
manager_role = Role(role_code="manager", name="直属领导")
finance_role = Role(role_code="finance", name="财务")
manager = Employee(
employee_no="E-BUDGET-MANAGER",
name="预算领导",
email="budget-manager-review@example.com",
grade="P7",
organization_unit=market_department,
roles=[manager_role],
)
finance_user = Employee(
employee_no="E-BUDGET-FINANCE",
name="预算财务",
email="budget-finance-review@example.com",
grade="P6",
organization_unit=market_department,
roles=[finance_role],
)
p6_budget_monitor = Employee(
employee_no="E-BUDGET-MARKET-P6",
name="低级预算",
email="p6-budget-monitor@example.com",
grade="P6",
organization_unit=market_department,
manager=manager,
roles=[budget_role],
)
db.add(p6_budget_monitor)
db.add_all([manager, finance_user, p6_budget_monitor])
db.flush()
claim = ExpenseClaim(
claim_no="APP-BUDGET-ANALYSIS-001",
@@ -342,9 +361,49 @@ def test_budget_analysis_endpoint_is_limited_to_budget_roles() -> None:
approval_stage="预算管理者审批",
risk_flags_json=[],
)
db.add(claim)
leader_claim = ExpenseClaim(
claim_no="RE-BUDGET-ANALYSIS-LEADER",
employee_id=p6_budget_monitor.id,
employee_name="低级预算",
department_id="dept-market",
department_name="市场部",
project_code=None,
expense_type="travel",
reason="客户现场交付报销",
location="上海",
amount=Decimal("6000.00"),
currency="CNY",
invoice_count=1,
occurred_at=datetime(2026, 5, 12, 9, 0, tzinfo=UTC),
submitted_at=datetime(2026, 5, 12, 10, 0, tzinfo=UTC),
status="submitted",
approval_stage="直属领导审批",
risk_flags_json=[],
)
finance_claim = ExpenseClaim(
claim_no="RE-BUDGET-ANALYSIS-FINANCE",
employee_id=p6_budget_monitor.id,
employee_name="低级预算",
department_id="dept-market",
department_name="市场部",
project_code=None,
expense_type="travel",
reason="客户现场交付报销",
location="上海",
amount=Decimal("8000.00"),
currency="CNY",
invoice_count=1,
occurred_at=datetime(2026, 5, 12, 9, 0, tzinfo=UTC),
submitted_at=datetime(2026, 5, 12, 10, 0, tzinfo=UTC),
status="submitted",
approval_stage="财务审批",
risk_flags_json=[],
)
db.add_all([claim, leader_claim, finance_claim])
db.commit()
claim_id = claim.id
leader_claim_id = leader_claim.id
finance_claim_id = finance_claim.id
ordinary_response = client.get(
f"/api/v1/reimbursements/claims/{claim_id}/budget-analysis",
@@ -367,8 +426,26 @@ def test_budget_analysis_endpoint_is_limited_to_budget_roles() -> None:
"x-auth-role-codes": "budget_monitor",
},
)
leader_response = client.get(
f"/api/v1/reimbursements/claims/{leader_claim_id}/budget-analysis",
headers={
"x-auth-username": "budget-manager-review@example.com",
"x-auth-role-codes": "manager",
},
)
finance_response = client.get(
f"/api/v1/reimbursements/claims/{finance_claim_id}/budget-analysis",
headers={
"x-auth-username": "budget-finance-review@example.com",
"x-auth-role-codes": "finance",
},
)
assert ordinary_response.status_code == 403
assert p6_monitor_response.status_code == 403
assert monitor_response.status_code == 200
assert leader_response.status_code == 200
assert finance_response.status_code == 200
assert Decimal(monitor_response.json()["metrics"]["claim_amount_ratio"]) == Decimal("24.00")
assert Decimal(leader_response.json()["metrics"]["claim_amount_ratio"]) == Decimal("12.00")
assert Decimal(finance_response.json()["metrics"]["claim_amount_ratio"]) == Decimal("16.00")