news 2026/5/3 9:38:20

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

作者头像

张小明

前端开发工程师

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/5/3 14:16:49

为啥你的论文总遭导师打回、期刊拒稿?答案藏不住了

为什么你的论文总会被导师“打回重写”或被期刊高冷“拒稿”?事实上,很多人投入大量时间与精力,却往往忽略了论文写作与发表过程中的几个关键难点。也许正是这些“隐形的坑”,拖慢了你的科研进程:选题困局:…

作者头像 李华
网站建设 2026/4/29 18:28:49

【视频帧提取性能优化实战】:Dify存储瓶颈全解析与高效解决方案

第一章:视频帧提取的 Dify 存储优化在高并发视频处理场景中,视频帧提取往往伴随海量小文件写入,对存储系统造成显著压力。Dify 作为支持多模态数据处理的 AI 应用平台,在处理视频任务时需优化底层存储策略,以提升帧提取…

作者头像 李华
网站建设 2026/5/2 17:28:00

Linux系统编程(进程1)

1.进程进程是一个程序执行的过程,会去分配内存资源,cpu的资源。 PCB是一个结构体,process control block。系统用于描述正在运行的进程的相关(所有)信息。pcb 中的内容 ,列出了一部分 PID,进程标识符 当前工作路径 chdir umask 00…

作者头像 李华
网站建设 2026/5/1 8:49:39

如何实现零宕机流量调度?,基于Docker MCP 网关的智能负载方案

第一章:零宕机流量调度的核心挑战在现代分布式系统架构中,实现零宕机流量调度是保障服务高可用性的关键环节。系统在升级、扩容或故障转移过程中必须确保用户请求持续被正确处理,任何中断都可能导致业务损失和用户体验下降。为此,…

作者头像 李华
网站建设 2026/5/2 12:31:21

紧急修复农业预测模型漏洞:R语言变量选择三大陷阱你避开了吗?

第一章:农业产量预测中R语言变量选择的核心挑战在农业产量预测建模过程中,变量选择是决定模型性能的关键环节。R语言因其强大的统计分析能力和丰富的扩展包(如caret、glmnet、randomForest)被广泛应用于该领域,但在实际…

作者头像 李华