fix(action-plans): 「已逾期」改日期粒度(口径 B,当天到期不算逾期)

- _apply_overdue():`ActionPlan.due_date < datetime.now()` → `... < 今天0点`
  (唯一实现,plan_stats 与 list_plans 共用,故一处改即两端点同改)
- 口径同步注释(口径 A→B 的沿革与分界式);行为改动仅此一处
- 测试夹具改到日粒度(整天偏移),新增「今日到期不算逾期」鉴别行与
  `test_overdue_caliber_is_date_granularity` 口径锁定用例(防回退 A)
- 依据:任总 2026-09-22 10:10 拍板口径 B;前端角标 ActionPlanLibrary.vue::isOverdue
  与 cash.py::_plan_dict 本就同粒度,本单未动
- 只改码:未 push / 未部署 / 未重启(发布须放行)

(cherry picked from commit 2da5b6da018013f860430913b5b0e0436f966685)
This commit is contained in:
Hermes CI Fix
2026-10-18 16:31:52 +08:00
parent 5fa83e2532
commit 57f9dbae15
2 changed files with 92 additions and 31 deletions
+11 -3
View File
@@ -66,7 +66,9 @@ def _validate_due_date_against_quarter(due_date: datetime, quarter: str):
# ──────────────────────────────────────────────
# 「已逾期」派生口径(单一来源,2026-09-21 project-20260921-actionplan-overdue-filter)
# ──────────────────────────────────────────────
# 口径:overdue = status in (pending, in_progress) AND due_date < now
# 口径:overdue = status in (pending, in_progress) AND due_date < 今天0点
# (**日期粒度 · 口径 B**,任总 2026-09-22 10:10 拍板;当天到期不算逾期。
# 2026-09-21 首版为 datetime 粒度 `due_date < now`,本次仅此一处改为日粒度。)
#
# 为什么要有这个函数(缺陷根因):status 的取值域只有
# pending / in_progress / completed / cancelled —— **没有** overdue 这个值。
@@ -82,10 +84,16 @@ OVERDUE_STATUSES = ("pending", "in_progress")
def _apply_overdue(query):
"""把「已逾期」派生口径施加到 ActionPlan 查询上(stats / list 共用)。"""
"""把「已逾期」派生口径施加到 ActionPlan 查询上(stats / list 共用)。
口径 B(日期粒度,任总 2026-09-22 拍板):due_date < **今天 0 点** —— 当天到期不算逾期。
与 cash.py::_plan_dict(应收催收 overdue)及前端行内角标
ActionPlanLibrary.vue::isOverdue 同粒度(二者本就是日期粒度,本单未动)。
"""
today_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
return query.filter(
ActionPlan.status.in_(list(OVERDUE_STATUSES)),
ActionPlan.due_date < datetime.now(),
ActionPlan.due_date < today_start,
)