很多人以为项目任务拖到日历上,就是把 planned_date_begin 改一下。可企业版 project_enterprise 处理得更像真正的排产:它会去问“这个人或这个公司,在这段时间里到底有没有可用工时”,再决定任务应该落到哪里、截止时间应该回填到哪里。
主要参考:
enterprise/project_enterprise/models/project_task.pyenterprise/project_enterprise/views/project_task_views.xmlenterprise/project_enterprise/tests/*
一、可用工时先看用户交集,不够时才退回公司日历
_get_users_available_work_intervals() 会先拿到所有分配用户的有效工时区间,再做交集;如果交集拿不到,就退回公司日历。这个选择很有意思:系统优先尊重任务实际负责人,再用公司级时间做兜底。
这解释了为什么有时同样一个任务,换了 assignee 以后手动排期结果会明显变化。因为企业版排的不是“日历格子”,而是资源可用性。
二、allocated_hours 才是决定 deadline 的真正驱动力
plan_task_in_calendar() 在有 allocated_hours 时,会从新的开始时间起,顺着可用工时区间往后扣减小时数,直到把预计工时消耗完,然后把那个时间点写成 date_deadline。也就是说,deadline 不是人工随便填的装饰字段,而是工时推导结果。
这和很多团队的习惯正好相反。业务人员常先想一个截止日期,再让开发/实施自己想办法塞进去;企业版则更强调“有多少可用工时,才能算出多晚做完”。
三、full-day 语义并不等于全天 24 小时
如果上下文里有 task_calendar_plan_full_day,系统会把开始时间对齐到日历首个可用工时,把结束时间对齐到当日末端,再结合可用区间处理。这里的“全天”,本质上是 按工作日语义对齐,不是自然日 24 小时暴力扩展。
这是新手很容易误解的地方:看到 full day,就以为系统忽略排班。实际上企业版依然在工作日历里求解,只是用户交互从精确时间切换成了全天模式。
四、为什么这个设计对项目管理有现实价值
手动排期通常发生在项目经理知道“我要把任务挪到某一天”,但不想手工重算截止时间的时候。企业版在这里做的是:
- 尊重 assignee/公司日历;
- 尊重 allocated hours;
- 用这些信息自动回填 deadline。
这让项目经理不必同时做两件事:既选时间,又自己心算多少天后完工。尤其在跨假期、跨请假场景里,这种自动回填非常有价值。
五、实战误区与建议
- 不要把
allocated_hours留空再指望排期准确;没工时,系统只能做更弱的日期推断。 - 多负责人任务的可用区间会更严格,因为要看交集,不是看并集。
- full-day 模式不是忽略排班,而是换一种工作日语义来求解。
建议项目经理先把用户日历、请假和工时估算维护干净,再依赖拖拽排期;否则看似智能,实际只是把脏数据更快传播。
六、结论
plan_task_in_calendar() 的价值,在于它把“拖一个任务到某一天”翻译成了“根据真实可用工时,重新求出开始与截止”。这一步做实了,项目排期才不是看板上的漂亮条块,而是真能落到人和时间上的计划。
DISCUSSION
评论区