efc200b6de
- 抽取 auto_complete_work_plans() 可复用函数到 visits service - POST/PUT 拜访均触发自动完成(更新场景解决补录问题) - Excel 导入旧周报时也触发自动完成 - 逾期计划自动取消:plan_date < today 且无匹配拜访→已取消 - edit_log 记录区分三种来源:拜访自动完成/拜访更新自动完成/旧周报导入自动完成/逾期自动取消 Co-Authored-By: Claude <noreply@anthropic.com>
41 lines
1.2 KiB
Python
41 lines
1.2 KiB
Python
"""Visit service — shared logic for visit creation, update, and import."""
|
|
|
|
from uuid import UUID
|
|
from datetime import date
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from app.models.work_plan import WorkPlan
|
|
from app.utils.edit_log import append_entry
|
|
|
|
|
|
async def auto_complete_work_plans(
|
|
db: AsyncSession,
|
|
customer_id: UUID,
|
|
visit_date: date,
|
|
editor_name: str,
|
|
reason: str = "拜访自动完成",
|
|
) -> int:
|
|
"""Auto-complete matching work plans when a visit is created/updated/imported.
|
|
|
|
Matches by: same customer_id + status=="计划中" + plan_date <= visit_date.
|
|
Returns the number of plans completed.
|
|
"""
|
|
plans_result = await db.execute(
|
|
select(WorkPlan).where(
|
|
WorkPlan.customer_id == customer_id,
|
|
WorkPlan.status == "计划中",
|
|
WorkPlan.plan_date <= visit_date,
|
|
)
|
|
)
|
|
count = 0
|
|
for plan in plans_result.scalars().all():
|
|
plan.status = "已完成"
|
|
append_entry(plan, editor_name, [{
|
|
"field": "status",
|
|
"from": "计划中",
|
|
"to": "已完成",
|
|
"reason": reason,
|
|
}])
|
|
count += 1
|
|
return count
|