企业 项目 甘特

Odoo 企业版甘特重排:consume buffer 和 maintain buffer 为什么会带出不同级联结果

project_enterprise 的甘特重排不是简单平移任务条,它会根据依赖、有效工时区间和缓冲策略,递归计算后续候选任务的最早/最晚可能日期。

企业 项目
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 3 阅读

很多项目经理以为甘特图里的“往后拖一格”只是视觉平移。但在企业版 project_enterprise 里,只要任务之间存在依赖,拖动一个任务,系统就必须重新判断后续任务还能不能在原来的缓冲区里待着。consume buffermaintain buffer 的区别,就在这里爆发出来。

主要参考:

  • enterprise/project_enterprise/models/project_task.py
  • enterprise/project_enterprise/views/project_task_views.xml
  • enterprise/project_enterprise/static/src/*

一、级联重排先不是写库,而是先求一组可能日期

_web_gantt_move_candidates() 在真正提交结果前,会先准备旧值、用户时区、候选任务集合、有效工时区间,再进入一轮计算。这说明企业版把甘特拖拽当作“约束求解”而不是“直接写字段”。

这非常重要。因为只要有依赖链,后续任务是否能挪、往哪挪、需不需要报错,都不是当前任务自己说了算。

二、_get_new_dates() 解决的是“给定可用区间,任务还能落在哪”

这个方法会在向前或向后搜索的方向上,遍历有效工时区间,累计时长,直到满足候选任务持续时间。它既能给任务求新开始/结束日期,也能在 maintain buffer 模式下求缓冲区的新边界。

也就是说,buffer 不是一个抽象概念,它在源码里会被当作真正需要占用工作区间的时间长度去计算。

三、maintain buffer 比 consume buffer 更保守

_web_gantt_update_next_candidates_dates() 的逻辑里,如果不消耗 buffer,系统会尝试保留原本任务间的缓冲时长:它不是只把后续任务顺延到前置任务结束之后,而是还要把中间空出来的工作时间也重新算进去。

这正是两种策略的根本区别:

  • consume buffer:允许挤掉原先的缓冲;
  • maintain buffer:把缓冲也当作计划的一部分继续保留。

项目团队如果不理解这个差别,就会以为“为什么我只拖了一下,后面一串任务全变了”。其实系统不是失控,而是在忠实执行你选的排程策略。

四、为什么依赖排程不能只看任务自己

后续候选任务是否能移动,还要看:

  • 任务本身是否仍是候选记录;
  • 用户或公司是否存在足够可用区间;
  • 依赖方向是前推还是后推;
  • 同一批候选任务之间是否存在冲突。

这也是为什么企业版代码里会维护 first_possible_start_date_per_candidatelast_possible_end_date_per_candidate 这类结构。甘特重排本质上是在求一个满足依赖约束的可行解集合。

五、新手误区

  • 以为甘特条拖动一定是一对一影响。实际上依赖链一长,后续会级联变化。
  • 以为 buffer 只是视觉空白。源码里 buffer 是会被重新计算的工作区间。
  • 以为 maintain buffer 只是“更慢一点”。它本质上是在保护原计划冗余。

六、落地建议

  1. 项目经理培训时要讲清两种 buffer 策略,不然大家会把系统输出当 bug。
  2. 在多人协作项目里,先保证 assignee 日历可靠,否则级联求解很容易出现看似奇怪的顺延。
  3. 对关键路径任务,优先使用能被团队共同理解的策略,而不是让每个人自己猜“拖动后会发生什么”。

七、结论

project_enterprise 的甘特重排并不是“移动任务条”,而是围绕依赖、工时区间和缓冲策略重新求解一组可执行日期。理解 consume buffermaintain buffer 的区别,才算真正理解企业版甘特为什么会给出不同的级联结果。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。