news 2026/8/1 5:58:41

项目管理中如何项目完成后自动关闭所有任务?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
项目管理中如何项目完成后自动关闭所有任务?

当项目被标记为“已完成”时,可能仍然存在一些未完成的任务,例如未标记为已完成的重复任务、不再相关的任务或项目结束后不再需要关注的任务。

为了确保项目反映其最终状态,您可以使用任务工作流程规则,在项目达到“已完成”状态后自动关闭所有未完成的任务。

要进行此设置,请执行以下步骤:

首先,使用以下权限范围创建与 Zoho Projects 的连接:

ZohoProjects.tasks.ALL

ZohoProjects.projects.READ

ZohoProjects.portals.READ

ZohoProjects.milestones.ALL

创建一个自定义函数并添加以下 Deluge 脚本。将“xxxxxxxxx”替换为您的 Zoho Projects 连接名称,并映射下面列出的参数。

  1. 以下脚本将删除任务重复项并关闭项目中的所有任务。在以下脚本中,连接名称为“closealltasks”。

    / TODO: Please create a connection for the Zoho Projects service with the scopes "ZohoProjects.tasks.ALL, ZohoProjects.projects.READ, ZohoProjects.portals.READ, ZohoProjects.milestones.ALL". Replace 'xxxxxxxxx' with the connection name. Click this link below to learn how to create the connection.

  2. // Link - https://help.zoho.com/portal/en/kb/projects/integration/connections/articles/connections-23-5-2022#How_to_establish_a_Connection

  3. // TODO: Replace the status name (Closed status type) in Line No. 6, if needed.

  4. projectsAPIEndPoint = "https://projectsapi.zoho.com/restapi";

  5. projectsv3APIEndPoint = "https://projectsapi.zoho.com/api/v3";

  6. statusName = "Closed";

  7. statusId = null;

  8. /* Close all tasks */

  9. //Fetch task layouts

  10. taskLayoutDetails = invokeurl

  11. [

  12. url :projectsAPIEndPoint + "/portal/" + portalId + "/projects/" + projectId + "/tasklayouts"

  13. type :GET

  14. connection:"closealltasks"

  15. ];

  16. // info taskLayoutDetails;

  17. if(taskLayoutDetails != null && taskLayoutDetails.get("status_details") != null)

  18. {

  19. statusDetails = taskLayoutDetails.get("status_details");

  20. for each status in statusDetails

  21. {

  22. if(status.get("name").equalsIgnoreCase(statusName))

  23. {

  24. // Fetch task status id based on status name

  25. statusId = status.get("id");

  26. info status.get("name") + " : " + statusId;

  27. break;

  28. }

  29. }

  30. }

  31. if(statusId != null)

  32. {

  33. indexValue = 1;

  34. rangeValue = 100;

  35. loop = {1,2,3,4,5,6,7,8,9,10};

  36. predStatusMap = Map();

  37. // This loop fetches up to 300 tasks. Increase the count as needed, e.g., loop = {1,2,3,4,5}; to fetch 500 tasks.

  38. for each i in loop

  39. {

  40. taskParameter = Map();

  41. taskParameter.put("index",indexValue);

  42. taskParameter.put("range",rangeValue);

  43. taskParameter.put("status","notcompleted");

  44. // info taskParameter;

  45. taskResponse = zoho.projects.getRecords(portalId,projectId,"tasks",taskParameter,0,"closealltasks");

  46. // info taskResponse;

  47. if(taskResponse.containKey("tasks"))

  48. {

  49. taskIds = list();

  50. for each task in taskResponse.get("tasks")

  51. {

  52. taskId = task.get("id");

  53. if(task.get("is_recurrence_set"))

  54. {

  55. updateTaskParameter = Map();

  56. updateTaskParameter.put("json_string",{"recurrence":{"recurring_frequency":"none","time_span":"1","number_of_occurrences":"2","is_comments_recurred":false,"recurrence_type":"after_current_task_completed"}});

  57. updateTaskResponse = zoho.projects.update(portalId,projectId,"tasks",taskId,updateTaskParameter,"closealltasks");

  58. info updateTaskResponse;

  59. }

  60. if(task.containsKey("dependency") && task.get("dependency").containsKey("predecessor"))

  61. {

  62. predTasks = task.get("dependency").get("predecessor");

  63. predList = list();

  64. for each predTaskId in predTasks

  65. {

  66. predList.add(task.get("dependency").get("dependencyDetails").get(predTaskId).get("IS_COMPLETED"));

  67. }

  68. if(!predList.contains(false))

  69. {

  70. taskIds.add(taskId);

  71. }

  72. }

  73. else

  74. {

  75. taskIds.add(taskId);

  76. }

  77. info "taskIds : " + taskIds;

  78. }

  79. bulkUpdateParams = Map();

  80. bulkUpdateParams.put("taskids",taskIds.toText().remove("[").remove("]"));

  81. bulkUpdateParams.put("status",{"id":statusId});

  82. info bulkUpdateParams;

  83. /* Bulk update */

  84. taskBulkUpdate = invokeurl

  85. [

  86. url :projectsv3APIEndPoint + "/portal/" + portalId + "/projects/" + projectId + "/tasks/bulk-update"

  87. type :PATCH

  88. parameters:bulkUpdateParams.toString()

  89. connection:"closealltasks"

  90. ];

  91. info taskBulkUpdate;

  92. }

  93. else

  94. {

  95. break;

  96. }

  97. }

  98. }

  99. return "success";

参数映射:

  1. portalId - Portal System ID

  2. projectId - Project System ID

保存自定义函数后,创建一个工作流程规则,并进行以下设置:

规则保存后,每当项目被标记为“已完成”时,所有未完成的任务都会自动完成。这确保项目能够准确反映其真实的完成状态,避免手动清理,并使您的项目保持最新状态。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/1 18:51:06

日志断层频发?,一文搞懂Dify与Spring AI无缝同步架构设计

第一章:日志断层频发?重新审视Dify与Spring AI的协同挑战在微服务架构日益复杂的背景下,Dify 与 Spring AI 的集成虽提升了智能决策效率,却也暴露出日志追踪断裂的问题。尤其在跨服务调用链中,AI 模型推理阶段的日志常…

作者头像 李华
网站建设 2026/8/1 19:07:37

第8篇 | 流量的“密语”:网络监听与中间人攻击的全景解析

《网络安全的攻防启示录》 第一篇章:破壁之术 第8篇 “你以为你在跟服务器说悄悄话,其实全世界都在听广播。” 想象这样一个场景:周末的午后,你坐在星巴克里,连上了店里的免费 Wi-Fi,点了一杯拿铁,顺手打开手机银行给房东转了房租,又登录公司邮箱回了几封紧急邮件。一…

作者头像 李华
网站建设 2026/7/31 16:02:18

技术升职加薪路上总卡点怎么办?

在职场和技术成长的路上,你是否遇到这些困扰: 想去海外发展,却不知道机会与挑战如何权衡团队里有“技术刺头”,管理难度大测试架构设计一头雾水,不知道从哪个维度下手算法测试、质量大盘建设等知识多但不知如何落地学…

作者头像 李华
网站建设 2026/8/1 7:51:15

CSS伪类及伪元素:一篇搞懂

文章目录一、 伪类(Pseudo-classes)1.链接伪类2.用户行为伪类3.结构伪类选择器4.表单伪类二、伪元素(Pseudo-elements)三、核心区别一、 伪类(Pseudo-classes) 伪类用于选择处于特定状态的元素&#xff0c…

作者头像 李华
网站建设 2026/8/1 14:54:04

【Dify内存管理实战】:应对加密PDF高负载解析的7种降耗策略

第一章:加密 PDF 解析的 Dify 内存占用在处理加密 PDF 文件时,Dify 平台因需执行解密、内容提取与语义分析等多阶段操作,容易引发显著的内存占用问题。尤其当批量解析高页数或强加密的 PDF 文档时,Java 虚拟机(JVM&…

作者头像 李华