fix: 预算年度分解幂等加固+数据质量七规则测试
- auto-decompose批量聚合只取年度行(period=YYYY-00)排除月度行,修复重复点击执行分解年底预算滚雪球 - 同一KPI多个version年度行时只取一行(优先请求version),避免多版本叠加总额虚高 - 新增tests/test_data_quality.py: 财务七规则(governance-check)3用例全过
This commit is contained in:
@@ -197,18 +197,26 @@ def auto_decompose_budget(
|
||||
|
||||
# ── 批量模式:不传kpi_id → 分解该年所有有年度预算的KPI ──
|
||||
if not kpi_id:
|
||||
# 找该年已存在的年度预算(period=YYYY-00 或已按月填的KPI汇总)
|
||||
# 优先用 budget_plans 中该年的预算作为年度总额
|
||||
# 只取年度行(period=YYYY-00)作为年度总额,避免把月度行也加进来导致滚雪球(非幂等bug修复)
|
||||
year_budget_rows = db.query(BudgetPlan).filter(
|
||||
BudgetPlan.entity_id == 1,
|
||||
BudgetPlan.budget_year == year,
|
||||
BudgetPlan.period == f"{year}-00",
|
||||
BudgetPlan.status == "active",
|
||||
).all()
|
||||
|
||||
# 按KPI聚合年度预算总额
|
||||
kpi_annual = {}
|
||||
# 按KPI聚合年度预算总额——同一KPI存在多个version年度行时只取一行
|
||||
# (优先匹配请求version,否则取第一条),避免多版本叠加导致总额虚高(幂等加固)
|
||||
from collections import defaultdict
|
||||
per_kpi = defaultdict(list)
|
||||
for r in year_budget_rows:
|
||||
kpi_annual[r.kpi_id] = kpi_annual.get(r.kpi_id, 0) + (r.budget_value or 0)
|
||||
per_kpi[r.kpi_id].append(r)
|
||||
kpi_annual = {}
|
||||
kpi_version_used = {}
|
||||
for kid, rows in per_kpi.items():
|
||||
chosen = next((r for r in rows if r.version == version), rows[0])
|
||||
kpi_annual[kid] = chosen.budget_value or 0
|
||||
kpi_version_used[kid] = chosen.version
|
||||
|
||||
if not kpi_annual:
|
||||
raise HTTPException(400, "该年度没有可分解的预算,请先在预算执行中录入年度预算")
|
||||
@@ -268,6 +276,7 @@ def auto_decompose_budget(
|
||||
"kpi_code": kpi.kpi_code,
|
||||
"kpi_name": kpi.kpi_name,
|
||||
"annual_budget": round(annual, 2),
|
||||
"version_used": kpi_version_used.get(kid),
|
||||
"method": "equal" if not weights else "weighted",
|
||||
"monthly": monthly,
|
||||
"monthly_count": 12,
|
||||
|
||||
Reference in New Issue
Block a user