- R-A2 sync-cash-plans: 年度行形态判定(_is_annual_budget_row)跳过 + skipped_annual 披露 - R2 POST /plans 期间形态校验(YYYY-MM / YYYY-00 显式接受) - R3 budget_roll_forward 排除年度行 - R1 cash_classify 归类路径年度行判据 + 披露 - 新增 2 个回归件(14+10 例) 仅含本族 hunk(禁整文件提交): 开发区其余 14 hunk 属他会话在途件,未纳入。
This commit is contained in:
@@ -196,40 +196,53 @@ def classify_unclassified(
|
||||
item.status = "classified"
|
||||
item.resolved_at = datetime.now()
|
||||
|
||||
# ③ 联动生成 CashPlan(有期间和预算值时)
|
||||
# ③ 联动生成 CashPlan(有期间和预算值时;年度行跳过,不落月度计划)
|
||||
from app.api.budget import _is_annual_budget_row # 函数内局部导入,规避 import 顺序/循环风险
|
||||
plan_created = False
|
||||
skipped_annual = False
|
||||
if item.period and item.budget_value is not None:
|
||||
try:
|
||||
year, month = int(item.period.split("-")[0]), int(item.period.split("-")[1])
|
||||
plan_date = datetime(year, month, 1)
|
||||
except Exception:
|
||||
plan_date = None
|
||||
if plan_date:
|
||||
existing_plan = db.query(CashPlan).filter(
|
||||
CashPlan.entity_id == entity_id,
|
||||
CashPlan.related_kpi_id == item.kpi_id,
|
||||
CashPlan.plan_type == plan_type,
|
||||
CashPlan.plan_date == plan_date,
|
||||
).first()
|
||||
if not existing_plan:
|
||||
db.add(CashPlan(
|
||||
entity_id=entity_id,
|
||||
plan_type=plan_type,
|
||||
related_kpi_id=item.kpi_id,
|
||||
amount=item.budget_value,
|
||||
plan_date=plan_date,
|
||||
description=f"待分类队列归类: {item.kpi_name or ''}",
|
||||
status="pending",
|
||||
source="budget_sync",
|
||||
))
|
||||
plan_created = True
|
||||
# 先按形态解析月份(不裸索引 split,避免 'YYYY' / 'YYYY-00' 抛异常被静默吞掉)
|
||||
parts = item.period.split("-") if isinstance(item.period, str) else []
|
||||
month = int(parts[1]) if len(parts) > 1 and parts[1].isdigit() else None
|
||||
if _is_annual_budget_row(item.period, month):
|
||||
# 年度行(YYYY / YYYY-00 / budget_month=0)不得落成月度现金流计划
|
||||
skipped_annual = True
|
||||
else:
|
||||
try:
|
||||
year, month = int(item.period.split("-")[0]), int(item.period.split("-")[1])
|
||||
plan_date = datetime(year, month, 1)
|
||||
except Exception:
|
||||
plan_date = None
|
||||
if plan_date:
|
||||
existing_plan = db.query(CashPlan).filter(
|
||||
CashPlan.entity_id == entity_id,
|
||||
CashPlan.related_kpi_id == item.kpi_id,
|
||||
CashPlan.plan_type == plan_type,
|
||||
CashPlan.plan_date == plan_date,
|
||||
).first()
|
||||
if not existing_plan:
|
||||
db.add(CashPlan(
|
||||
entity_id=entity_id,
|
||||
plan_type=plan_type,
|
||||
related_kpi_id=item.kpi_id,
|
||||
amount=item.budget_value,
|
||||
plan_date=plan_date,
|
||||
description=f"待分类队列归类: {item.kpi_name or ''}",
|
||||
status="pending",
|
||||
source="budget_sync",
|
||||
))
|
||||
plan_created = True
|
||||
|
||||
db.commit()
|
||||
message = f"已归类为 {plan_type}" + (" 并生成现金流计划" if plan_created else "")
|
||||
if skipped_annual:
|
||||
message += "(年度行,跳过月度现金流计划)"
|
||||
return {
|
||||
"message": f"已归类为 {plan_type}" + (" 并生成现金流计划" if plan_created else ""),
|
||||
"message": message,
|
||||
"plan_type": plan_type,
|
||||
"rule_created": not existing_rule,
|
||||
"plan_created": plan_created,
|
||||
"skipped_annual": skipped_annual,
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user