本文介绍如何将重复周期与Planner任务配合使用,以自动创建重复任务。 Planner任务上的定期属性允许用户自动创建表示需要重复完成的实际任务的未来任务。
用户方案
支持以下方案:
向现有任务添加重复行为,从而创建重复序列。 或者,创建定义了重复周期的新任务。 两者的最终结果相同:定期任务,定期系列中的第一个任务。 用户指定定期计划。
编辑现有定期系列的定期计划。
继续一个系列。 根据重复计划,将任务标记为完成会导致生成新任务以继续序列。 如果删除序列中的活动任务,应提示用户确定是继续还是终止该系列。 如果客户端不知道重复周期并且未提供提示,则序列应继续。 不应意外终止。
通过以下方式终止序列:
- 删除系列中的活动任务 (并选择 “是 ”以终止系列) 。
- 在不删除活动任务的情况下终止序列。
恢复系列。 如果重复周期已终止,则应可以恢复序列。
定期会议和定期任务之间的概念差异
本部分介绍重复任务的实际方案,以说明定期会议和定期任务之间的有趣差异,并探索定期模式更改的问题空间。
以下示例涉及必须定期完成的报表,并利用定期任务来跟踪报表的完成情况。
报告及其相关任务每两周在周五到期:该系列于 2021 年 5 月 14 日开始。 第一份报告将于5月14日星期五公布。 快进到 2022 年 1 月 7 日,34 周后。 做报告的人在12月请了一些假,没有人完成报告。 当前定期任务 (和相应的报告) 将于 12 月 10 日到期。 报告及其相关任务现已过期 4 周。
注意: 此时,定期会议和事件之间的对比变得明显。 无需 将会议标记为“已完成 ”即可让自动化系统在日历上安排下一次会议。 完成过期任务可能会生成另一个过去到期的任务,但过去没有 完成会议的概念。 会议的下一个实例始终是将来的,具体取决于 今天的日期。 今天的日期不用于计算定期任务的截止日期,以避免丢失延迟工时跟踪。
对于此任务,如果未编辑重复计划,并且 12 月 10 日任务已标记为完成,则会使用截止日期 12 月 24 日实例化该系列的下一个任务。
但是,假设决定今后应每隔 3 周(而不是每 2 周)完成一次报告。 甚至可能决定,3周的节奏应该对逾期的报告具有追溯性。 此更改会邀请不同的可能选项来定义序列的延续:
- 是否应更改 12 月 10 日截止日期?
- 下一个任务应何时到期?
以下是定期任务的当前状态和决策:
- 当前任务的截止日期为 2021 年 12 月 10 日。
- 上一个已完成的任务将于 2021 年 11 月 26 日完成。
- 决定将节奏从 2 周更改为 3 周:更改将追溯应用于逾期报表。
鉴于上下文,有两个选项是可能的,两个选项都是有效的客户案例,用于如何更改系列以适应新的 3 周节奏。
选项 1:将 12 月 10 日任务更改为在上一个 11 月 26 日任务之后 3 周到期。 当前任务的截止日期已更改为 12 月 17 日,以下任务将于 1 月 7 日完成。
选项 2:保留当前的 12 月 10 日截止日期,并更改 12 月 31 日到期的以下任务的节奏。
Planner支持这两个选项:今天的日期不会影响处理这些不同情况的方式。 此示例将在 示例 1:使用和不更改 patternStartDateTime 更改模式中进一步探讨。
定义
以下术语用于讨论和描述定期Planner任务:
具有活动重复周期的任务的定义
如果满足以下三个条件,则 plannerTask 具有 活动重复周期:
-
percentComplete 属性的值小于
100。 -
recurrence.nextInSeriesTaskId 为
null或未定义。 - recurrence.schedule 包含具有非 null nextOccurrenceDateTime 的有效 plannerRecurrenceSchedule。
具有 活动重复 周期 (任务称为 任务 A) 可以触发服务定期机制,以 (任务 B) 继续执行定期序列。 发生这种情况时, 任务 A 将其 recurrence.nextInSeriesTaskId 设置为 任务 B 的 ID。由于 任务 A 不再满足条件 2,因此它不再具有 活动重复周期。 任务 A 再也不能有 活动的重复周期 ,因为 nextInSeriesTaskId 是一个只读属性,服务永远不会删除其值。
定期序列的定义
定期系列 (也称为定期系列) 是一系列任务。 当第一次在一个任务上定义定期时,该系列开始,该系列将继续通过自动创建具有相同 recurrence.seriesId 的新任务。
- 共享同一 recurrence.seriesId 的任务属于同一 定期系列。
- 系列中的每个任务都有一个不同的 recurrence.occurenceId。
- 系列中的第一个任务有 一个 occurrenceId
1。 - 当第一个任务的重复机制被标记为完成或删除 (触发时,当它具有 活动重复) 时,则会创建第二个任务, 其 occurenceId 为
2。 此过程会一直持续到 定期序列 终止。
避免使用不明确的术语定期任务
在常见语音中, 术语定期任务 有时是指在一系列中 具有活动重复 的唯一任务:和 有时引用 定期系列 本身,或定期系列中的所有任务。 这种模棱两可的英语口语很常见:同样, 每周报告 可能引用报告的一个实例,或者每周定期报告的责任。 由于这种多义性,避免使用 术语定期任务 :相反,首选以下术语之一: 具有活动重复 周期或 重复序列的任务。
资源类型详细信息
使用Planner任务的重复周期需要使用多种资源类型:plannerTaskRecurrence、plannerRecurrenceSchedule 和 recurrencePattern。 以下部分提供有关后两种资源类型的更多详细信息。
plannerRecurrenceSchedule
plannerRecurrenceSchedule 封装了一个重复模式定义 (模式) 、该模式的开始日期 (patternStartDateTime) ,以及一个系统生成的属性,该属性指示下一个发生日期 (nextOccurrenceDateTime) 。
模式是 recurrencePattern;有关详细信息,请参阅有关 recurrencePattern 的特定于Planner说明。
patternStartDateTime 将序列的开始日期和时间指示为 DateTimeOffset。 每当使用 pattern 属性时,必须将非 null 值分配给 patternStartDateTime;这是目前定义重复周期的唯一方法。 客户端在对 recurrence.schedule.pattern 进行更改以指示新模式的开始日期时,通常应重新分配此值;但是,如果客户端不包含值,则服务会根据计划使用默认值继续序列。 有关更多详细信息,请参阅以下说明和说明。
nextOccurrenceDateTime 是系统生成的只读字段。 它提供服务计算的日期,用作系列中下一个 plannerTask 的 dueDateTime。 nextOccurrenceDateTime 由模式以及 patternStartDateTime 或跟踪给定任务最初计划日期的定位点值一起计算。
注意:Planner当前不使用 recurrenceRange 资源类型。
有关 recurrencePattern 的特定于Planner注释
以下是针对 recurrencePattern 的特定于Planner限制:
-
relativeMonthly和relativeYearly模式可能不会为 daysOfWeek 指定超过一天。 - 对于
weekly模式,如果 daysOfWeek 包含超过一天,则 间隔 必须为1。
有关 recurrencePattern 的说明:
每当 recurrencePattern 中的任何属性发生更改时,都必须指定所有相关的模式属性。 例如 ,类型为 =
daily和 间隔 =1的模式不能仅使用 间隔 =2进行修补;否则,服务将400 Bad Request返回响应代码。 还必须指定 类型 =daily属性,即使 类型 未更改。 这是 recurrencePattern 资源类型的正常行为,尽管其他一些Planner属性的工作方式不同。自动为未使用的属性分配默认值。
- 例如, month 属性仅用于每年模式,有效值从
1到12。 但是,daily、weekly和monthly模式已0分配给 month 属性,因为0是整数值的默认值。 - 枚举属性(包括 firstDayOfWeek 和 index)分别获取对应于第一个枚举值的默认值:
sunday和first。
- 例如, month 属性仅用于每年模式,有效值从
对于
absoluteMonthly模式,如果选定 日期OfMonth 在特定月份不存在,则会替换该月 的最后 一天。- 示例:如果 dayOfMonth 为
31,并且你为 4 月重复,则所选日期为 4 月 30 日。 - 示例:如果 dayOfMonth 为
29、30或31且重复为 2 月,则所选日期为 2 月 的最后 一天。
- 示例:如果 dayOfMonth 为
同样,对于
absoluteYearly具有 month =2和 dayOfMonth =29的模式,非闰年所选日期为 2 月 28 日。对于
weekly模式, firstDayOfWeek 属性用于区分 本周 考虑的内容和 下周考虑的内容。 更改模式时,这与weekly相关。 下一个任务计划于下周执行,firstDayOfWeek 确定下周的开始时间。
firstDayOfWeek 如何影响每周模式更改的示例
给定具有以下属性 的活动定期任务 :
- 每周三发生一次:模式的类型 =
weekly、interval =1、daysOfWeek = [wednesday]和 firstDayOfWeek =sunday - dueDateTime 为星期三 2/2
- 下一个OccurrenceDateTime是星期三 2/9
可对 模式 进行三次更改,下表显示了生成的 nextOccurrenceDateTime 。
| 模式更改 | 生成的 nextOccurrenceDateTime |
|---|---|
| 每周星期二 | 星期二 2/8 |
| 每周四 | 星期四 2/10 |
| 每周四和 firstDayOfWeek 更改为星期四 | 星期四 2/3 |
请注意 2/10 星期四与星期四 2/3 的差异。 当 firstDayOfWeek = Thursday 时,星期四 2/3 与星期三 2/2 不在同一周 ,因为新周从星期四开始;而如果 第一个DayOfWeek 不是 Thursday,则星期四 2/3 与星期三 2/2 在同 一周 ,2/10 星期四在下 周。
有关计划和截止日期的说明
客户端可能会编辑 dueDateTime 以具有不同的值 (包括 null) ,而不会影响计划和 nextOccurrenceDateTime。 例如,如果某个任务延迟,并且截止日期已更改为适应该延迟,则序列中的下一个任务将按原计划显示,除非显式更新 了模式 和/或 patternStartDateTime 。 因此,推迟截止日期不会导致根据定义的计划 跳过日期 。 这与 会议 模型不同,会议模型今天的 日期 在确定下一次会议的召开时间方面起着一定的作用。 知道 今天的日期 与计算下一个会议或活动日期相关,但与计算下一个任务截止日期无关。
示例 1:使用和不更改 patternStartDateTime 更改模式
给定具有以下属性 的活动定期任务 :
- 定期模式在星期五指定每 2 周一次,例如 ,类型 =
weekly、 interval =2、 daysOfWeek = [friday]和 firstDayOfWeek =sunday。 - 上一个已完成的任务将于 2021 年 11 月 26 日完成。
- 当前任务截止日期为 2021 年 12 月 10 日。
- nextOccurrenceDateTime 为 2021 年 12 月 24 日, (当前截止日期) 两周后。
决定将节奏从 2 周更改为 3 周。 因此,模式被修改为每周星期五的 间隔 = 3 和相同的值。
检查了三个不同的可能性,每个可能性都会为系列中的下一个任务生成不同的截止日期:
| 更改说明 | 生成的 nextOccurrenceDateTime |
|---|---|
| 将 patternStartDateTime 更改为 2021 年 12 月 10 日 | 2021 年 12 月 31 日 |
| 将 patternStartDateTime 更改为 2021 年 12 月 17 日 | 2022 年 1 月 7 日 |
| 不要更改 模式StartDateTime | 2021 年 12 月 31 日 |
在第一个示例中, patternStartDateTime 设置为与 dueDateTime 相同的值,例如 12 月 10 日。 nextOccurrenceDateTime 设置为 patternStartDateTime 后的 3 周,即 12 月 31 日。 从概念上讲,这表示仅对以下任务而不是此任务生效的节奏更改。
第二个示例中, patternStartDateTime 设置为 11 月 26 日之后的 3 周,即 12 月 17 日。 同样, nextOccurrenceDateTime 设置为 模式StartDateTime之后的 3 周,这一次是 1 月 7 日。 从概念上讲,这表示从 11 月 26 日 (上一个任务) 生效的节奏更改,而不是从当前任务) 的原始截止日期 (12 月 10 日生效。
我们通常建议将任务的 dueDateTime 更改为与新 模式StartDateTime 一致;但是,这不是必需的。 如果 dueDateTime 未随第二个示例中的 patternStartDateTime 一起更改,则用户将继续看到当前任务的 12 月 10 日截止日期。 完成后,该系列中的下一个任务计划于 1 月 7 日进行。 由于这可能会给用户造成混淆,建议将 dueDateTime 和 patternStartDateTime 一起分配。
第三个示例与第一个示例类似,只不过它未指定 patternStartDateTime。 无法使用很久以前(如 8 月)的 patternStartDateTime 。 在这种情况下, 下一个OccurrenceDateTime 是基于 12 月 10 日 的原始截止日期 计算的,因此下 一个 OccurrenceDateTime 为 12 月 31 日,类似于第一个示例。 请注意, 原始截止日期 不会公开,尽管它用于此计算。 这意味着 ,dueDateTime 可以更改为另一个值,甚至更改为 null,但对于此计算,将忽略 dueDateTime 值,而是使用 原始截止日期。 这是建议同时更改 dueDateTime 和 patternStartDateTime 的另一个原因。
示例 2:截止日期不会影响下一个匹配项
给定具有以下属性 的活动定期任务 :
- 每周三发生一次:模式的类型、 =
weeklyinterval =1、daysOfWeek = [wednesday]和 firstDayOfWeek =sunday。 - dueDateTime 为周三 2/16。
- 下一个OccurrenceDateTime 是周三 2/9。
- 原始截止日期为星期三 2/2。 此值不会公开,但可以从 nextOccurrenceDateTime 推断它。
下面是对三种可能的更改的检查。
| 更改 | 生成的 nextOccurrenceDateTime |
|---|---|
| 无变化 | 星期二 2/9 |
| 模式更改为每周四;对 patternStartDateTime 没有更改 | 星期四 2/10 |
| patternStartDateTime 更改为 2/9;模式没有更改 | 星期三 2/16 |
在这三个示例中, dueDateTime 不会从其修改值星期三 2/16 更改,并且创建系列中的下一个任务,其 dueDateTime 等于上表中的 nextOccurrenceDateTime 。
注意:
- 未显式重新分配 patternStartDateTime 时,默认行为是计划基于 原始截止日期继续。 在这种情况下, 原始截止日期 为 2/2,而当前 dueDateTime 为 2/16。
- 如果 patternStartDateTime 已更改,则会使用该新的开始日期重新计算 nextOccurrenceDateTime 。
- 如果截止日期更改为
null2/16,或者更改为将来或过去的任何其他日期,前面的示例将不受影响。
开发人员方案
创建定期系列
recurrence.schedule 是重复周期的唯一可客户端编辑子属性。 通过添加 recurrence.schedule (是否已) 定义了 重复周期 ,客户端可以将非重复任务更改为具有 活动重复周期的任务。
活动定期定义中提到的其他两个条件会影响是否可以添加 recurrence.schedule:
-
percentComplete 属性必须小于
100。 -
recurrence.nextInSeriesTaskId 属性必须是
null或取消分配。
其他 定期 子属性是只读的。 如果尚未分配它们,服务会在添加 recurrence.schedule 时自动生成它们。
触发器重复
下面显示了在具有 活动定期的任务上触发重复机制的两种方式:
在具有活动定期的_task的先前定义中,如果不满足这三个条件中的任何一个,则不会触发重复机制 (不创建新任务,也不会分配 nextInSeriesTaskId 。)
新任务的实例化通常立即发生,这偶尔会导致新任务的创建延迟。
新任务具有以下从现已完成的任务复制的属性: 标题、 说明、 清单项 (设置为不完整) 、 分配、 优先级和 类别。 新任务的 percentComplete 设置为 0。 根据定期计划设置新任务的 dueDateTime 。 复制定期的以下子属性: seriesId、 recurrenceStartDateTime 和 schedule; schedule.nextOccurrenceDateTime 是为新任务新计算的。 为新任务提供了适当的其他重复属性值。
发现系列中的下一个任务
如果 任务 C 定义了重复周期,并且用户将 任务 C 标记为完成 (percentComplete = 100) ,则会创建 任务 D 以继续重复序列。
任务 C 具有其 recurrence.nextInSeriesTaskId 属性,该属性填充了 任务 D 的 ID。
另一方面,如果 删除了任务 C ,并且删除会触发重复,客户端必须通过某种其他方式发现 任务 D 的 ID。 例如,通过查询同一存储桶中的任务或使用增量同步源。
编辑定期序列
具有活动重复周期的任务可以编辑其重复计划。 请注意, recurrence.schedule 是可以编辑的重复周期的唯一子属性。
例如,具有活动重复周期和 每周星期三计划的任务可以在 每月第 15 天将其计划更改为每月一次。
终止定期序列
若要终止定期序列,请将 recurrence.schedule 属性设置为 null。 仅当 nextInSeriesTaskId 已 null 分配或取消分配时,才能执行此作。
终止后恢复重复周期
删除 recurrence.schedule 后,可以向恢复序列的任务添加新 的 recurrence.schedule 。
按照上述步骤 创建定期系列。 同样的限制也适用。 原始 recurrence.seriesId 和 定期 的其他子属性保持不变,有效地恢复或继续原始序列。
在重复周期系列中标识具有活动重复周期的任务
给定 recurrence.seriesId,具有该 seriesId 的最多一个任务可以具有 活动重复周期。
已完成的任务对大多数视图都是隐藏的。 用户查看已标记为完成的任务的情况并不常见。 无法查看已删除的任务。 这意味着在大多数情况下,定期序列中只有一个具有活动重复周期的任务。 如果具有活动重复周期的任务已通过删除计划停用其定期,则不存在在该系列中具有活动重复任务的任务。
罕见的异常方案
以下方案很少见,但可能。 虽然这些任务在客户端上看起来可能是例外,但事实上,服务始终保持规则的完整性:在给定的重复周期系列中,最多有一个任务具有活动重复周期。 提供了消除歧义的指导。
原因
下面显示了信息出现不同步的两个可能原因:
信息尚未到达面向客户端的快速存储Planner。 Planner的权威信息源具有数据,但数据尚未复制到请求优化存储,该存储将数据返回给客户端。
重复机制遇到暂时故障。 这意味着尚未创建用于继续序列的新任务;它通常在几秒钟或几分钟内创建。
同一重复序列中具有活动重复周期的两个任务
如果客户端在同一重复序列中观察到两个具有活动重复周期的任务,则可以假定 具有较小 occurrenceId 的任务已触发其重复机制。 Planner的后端存储设置了 nextInSeriesTaskId,但该信息尚未到达面向客户端的快速存储。 具有较大 occurrenceId 的任务是具有活动重复周期的唯一任务。
具有活动重复周期的任务的 occurrenceId 小于同一重复序列中的另一个任务
与前面的“具有活动重复周期的两个任务”类似,如果 具有较大 occurrenceId 的任务已停用其定期 (recurrence.schedule = null) ,则可能会观察到第二种情况。 存在 一个具有较大 occurrenceId 的任务意味着,该系列中 具有较小 occurrenceId 的任何任务都没有 活动重复周期,即使具有较大 occurrenceId 的任务也没有 活动重复周期 。
在序列中具有活动重复周期的零任务
这是一种真正不明确的情况,因为可能出现以下任一情况:
- 定期机制因暂时性故障而延迟;将重试。
- 重复机制成功,但新任务尚未添加到面向客户端的快速存储。
- 新任务已创建,但随后又被另一个客户端删除。
前两个是临时状态,通常可在几秒钟或几分钟内通过服务进行补救。 第三个通常是永久性的。 将这种情况描述为 罕见或异常可能不准确;然而,前面曾描述过这样一个事实,即由于前两种情况的可能性,观察到的状态存在模棱两可性。
查找定期系列中的所有任务
使用 Planner 的开发人员熟悉现有 API,以便获取计划中的所有任务。 Planner还没有 API 来获取定期系列中的所有任务;但是,通过获取计划中的所有任务,通常可以获取定期系列中的所有任务。
每个 plannerTask 上的 recurrence.seriesId 属性是一个标识符,该标识符不同于一个或多个任务所属的特定定期系列。 分配后,此值永远不会更改。
recurrence.occurrenceId 是一个整数值,指示序列中任务的排序。 系列中的第一个任务 (首次添加定期的任务,) 的 occurrenceId 为 1。
注意:
- 如果删除了系列中的某些任务,则索引可能包含间隙。
- 如果用户已将定期系列移到其他计划,则需要查看其他计划才能查看该系列中的其他任务;但是,用户通常主要对一个计划内的定期系列感兴趣。 任务可能不会跨组边界移动;如果查询了组中的所有计划,则可以找到可能已移出原始计划的所有任务。
REST作示例
以下请求和响应表示有序作序列。 它们可能用作实现Planner任务定期的客户端的测试用例,方法是将适当的标识符 (替换为任务、计划、定期系列等。) 许多错误案例都穿插在一起,以说明对特定状态的错误更改。
向现有 plannerTask 添加截止日期和重复周期
以下示例请求和响应演示如何重复执行任务。 具有 ID Q7SNdWp5ekeJTpRRSCcZ3pUAD6kV 的任务已存在,并且已 定期执行 = null。 若要添加定期,需要分配 recurrence.schedule 的必需属性。 不应包括未使用的 recurrencePattern 属性 (month、 dayOfMonth、 firstDayOFWeek 和 index) 。
请求
PATCH https://graph.microsoft.com/beta/planner/tasks/Q7SNdWp5ekeJTpRRSCcZ3pUAD6kV
{
"recurrence": {
"schedule": {
"pattern": {
"type": "daily",
"interval": 2
},
"patternStartDateTime": "2021-11-13T10:30:00Z"
}
},
"dueDateTime": "2021-11-13T10:30:00Z"
}
响应
HTTP/1.1 204 NO CONTENT
获取上一个任务
以下示例请求和响应演示如何检索新添加的定期任务。
请求
GET https://graph.microsoft.com/beta/planner/tasks/Q7SNdWp5ekeJTpRRSCcZ3pUAD6kV
响应
下面是有关响应的注释:
- 服务为未使用的 recurrencePattern 属性 (month、 dayOfMonth、 firstDayOFWeek 和 index) 分配默认值。
- nextOccurrenceDateTime 是从计划计算的。 在这种情况下,patternStartDateTime 为 11 月 13 日,并且该模式定义每隔一天;这将提供 patternStartDateTime 后两天的 nextOccurrenceDateTime,即 11 月 15 日。
-
seriesId 和 occurrenceId 是自动生成的。
seriesId 是采用Planner标识符格式编码的新 GUID。 由于这是系列中的第一个任务,因此它获取 的 occurrenceId 为
1。 -
为 recurrenceStartDateTime 分配与 patternStartDateTime 相同的值。 这适用于系列中的第一个任务, (occurrenceId =
1) 。 但是,对于系列中将来的任务,即使 patternStartDateTime 发生更改, recurrenceStartDateTime 的值也不会更改;它跟踪重复周期的开始,与模式更改相反。 -
previousInSeriesTaskId 始终
null为 ,因为这是 (occurrenceId =1) 系列中的第一个任务。 - 如果创建下一个任务以继续序列,则会分配 nextInSeriesTaskId 。
HTTP/1.1 200 OK
Content-type: application/json
{
"@odata.context": "https://graph.microsoft.com/beta/$metadata#planner/tasks/$entity",
"@odata.etag": "W/\"JzEtVGFzayAgQEBAQEBAQEBAQEBAQEBASCc=\"",
"planId": "4CaQUsrKXkyMDBhpF9cu-JUAAZ1V",
"bucketId": "mVAeurfATUOEkpxi-60a9pUAJDxm",
"title": "Water the plants",
"orderHint": "8586352620867692777",
"assigneePriority": "",
"percentComplete": 0,
"priority": 5,
"startDate": null,
"createdDateTime": "2019-08-20T23:46:38.708303Z",
"hasDescription": false,
"previewType": "automatic",
"completedDateTime": null,
"completedBy": null,
"referenceCount": 0,
"checklistItemCount": 0,
"activeChecklistItemCount": 0,
"conversationThreadId": null,
"id": "Q7SNdWp5ekeJTpRRSCcZ3pUAD6kV",
"createdBy": {
"user": {
"displayName": null,
"id": "edcfc4b0-be77-4866-948a-b93267e151f8"
}
},
"appliedCategories": {},
"assignments": {},
"recurrence": {
"seriesId": "w5tLb5HceUmpuiYlhdXyHg",
"occurrenceId": 1,
"previousInSeriesTaskId": null,
"nextInSeriesTaskId": null,
"recurrenceStartDateTime": "2021-11-13T10:30:00Z",
"schedule": {
"patternStartDateTime": "2021-11-13T10:30:00Z",
"nextOccurrenceDateTime": "2021-11-15T10:30:00Z",
"pattern": {
"type": "daily",
"interval": 2,
"firstDayOfWeek": "sunday",
"dayOfMonth": 0,
"daysOfWeek": [],
"index": "first",
"month": 0
}
}
},
"dueDateTime": "2021-11-13T10:30:00Z",
"creationSource": null
}
将任务标记为完成, (系列中的第一个任务触发重复)
以下示例请求和响应演示如何将 percentComplete 设置为 100 (也称为 完成任务 或 ) 标记任务完成 。
请求
以下示例显示了一个请求,该请求与具有或没有重复周期的任务相同。
PATCH https://graph.microsoft.com/beta/planner/tasks/Q7SNdWp5ekeJTpRRSCcZ3pUAD6kV
{
"percentComplete": 100
}
响应
HTTP/1.1 204 NO CONTENT
获取现已完成的任务并发现系列中下一 (第二个) 任务的 ID
以下示例请求和响应演示如何在任务标记为完成后检索任务。
请求
GET https://graph.microsoft.com/beta/planner/tasks/Q7SNdWp5ekeJTpRRSCcZ3pUAD6kV
响应
以下示例显示了一个请求。 由于 已分配 nextInSeriesTaskId ,因此此任务不能再配置 活动重复周期 。
HTTP/1.1 200 OK
Content-type: application/json
{
"_comment": "other fields omitted for brevity",
"percentComplete": 100,
"recurrence": {
"seriesId": "w5tLb5HceUmpuiYlhdXyHg",
"occurrenceId": 1,
"previousInSeriesTaskId": null,
"nextInSeriesTaskId": "GxOo0ms1iEu3eBI1-6lk85UAI5FI",
"recurrenceStartDateTime": "2021-11-13T10:30:00Z",
"schedule": {
"patternStartDateTime": "2021-11-13T10:30:00Z",
"nextOccurrenceDateTime": "2021-11-15T10:30:00Z",
"pattern": {
"type": "daily",
"interval": 2,
"firstDayOfWeek": "sunday",
"dayOfMonth": 0,
"daysOfWeek": [],
"index": "first",
"month": 0
}
}
},
"dueDateTime": "2021-11-13T10:30:00Z",
}
获取系列中的新任务 (第二次出现)
以下示例请求和响应演示如何检索系列中的新任务,该任务 ID 是从上一响应中的 nextInSeriesTaskId 发现的。
请求
与前面的示例 () GxOo0ms1iEu3eBI1-6lk85UAI5FI 相比,) 示例请求 (Q7SNdWp5ekeJTpRRSCcZ3pUAD6kV 包含以下差异:
- 已为 dueDateTime 分配了任务的上 一个 nextOccurrenceDateTime 中的值。
- nextOccurrenceDateTime 已根据 计划进行计算:上一个 dueDateTime 之后的下一个匹配项。
-
occurrenceId 是
2而不是1 -
percentComplete 为
0。
GET https://graph.microsoft.com/beta/planner/tasks/GxOo0ms1iEu3eBI1-6lk85UAI5FI
响应
HTTP/1.1 200 OK
Content-type: application/json
{
"_comment": "other fields omitted for brevity",
"planId": "4CaQUsrKXkyMDBhpF9cu-JUAAZ1V",
"bucketId": "mVAeurfATUOEkpxi-60a9pUAJDxm",
"title": "Water the plants",
"percentComplete": 0,
"id": "GxOo0ms1iEu3eBI1-6lk85UAI5FI",
"appliedCategories": {},
"assignments": {},
"recurrence": {
"seriesId": "w5tLb5HceUmpuiYlhdXyHg",
"occurrenceId": 2,
"previousInSeriesTaskId": "Q7SNdWp5ekeJTpRRSCcZ3pUAD6kV",
"nextInSeriesTaskId": null,
"recurrenceStartDateTime": "2021-11-13T10:30:00Z",
"schedule": {
"patternStartDateTime": "2021-11-13T10:30:00Z",
"nextOccurrenceDateTime": "2021-11-17T10:30:00Z",
"pattern": {
"type": "daily",
"interval": 2,
"firstDayOfWeek": "sunday",
"dayOfMonth": 0,
"daysOfWeek": [],
"index": "first",
"month": 0
}
}
},
"dueDateTime": "2021-11-15T10:30:00Z"
}
将任务的重复周期编辑为每周一天,并将截止日期设置为 null
以下示例请求和响应演示如何将 dueDateTime 和其他模式分配给null具有活动重复周期的任务。
请求
PATCH https://graph.microsoft.com/beta/planner/tasks/GxOo0ms1iEu3eBI1-6lk85UAI5FI
{
"recurrence": {
"schedule": {
"pattern": {
"type": "weekly",
"interval": 1,
"daysOfWeek": [ "tuesday" ],
"firstDayOfWeek": "sunday"
}
}
},
"dueDateTime": null
}
响应
HTTP/1.1 204 NO CONTENT
再次获取任务以查看编辑结果
以下示例请求和响应演示如何在前面的编辑之后检索任务。 可以看到前面指定的 recurrence.schedule.pattern :每周星期二,以及 dueDateTime = null。
请求
GET https://graph.microsoft.com/beta/planner/tasks/GxOo0ms1iEu3eBI1-6lk85UAI5FI
响应
在以下示例中,任务可以具有活动重复周期以及 null 截止日期。
下一个OccurrenceDateTime 是重新计算的,现在为 11 月 23 日(星期二),从 daysOfWeek 开始。 下一个匹配项是根据 11 月 15 日(星期一)任务的原始 dueDateTime 计算的。
HTTP/1.1 200 OK
Content-type: application/json
{
"_comment": "other fields omitted for brevity",
"planId": "4CaQUsrKXkyMDBhpF9cu-JUAAZ1V",
"bucketId": "mVAeurfATUOEkpxi-60a9pUAJDxm",
"title": "Water the plants",
"percentComplete": 0,
"id": "GxOo0ms1iEu3eBI1-6lk85UAI5FI",
"appliedCategories": {},
"assignments": {},
"recurrence": {
"seriesId": "w5tLb5HceUmpuiYlhdXyHg",
"occurrenceId": 2,
"previousInSeriesTaskId": "Q7SNdWp5ekeJTpRRSCcZ3pUAD6kV",
"nextInSeriesTaskId": null,
"recurrenceStartDateTime": "2021-11-13T10:30:00Z",
"schedule": {
"patternStartDateTime": "2021-11-13T10:30:00Z",
"nextOccurrenceDateTime": "2021-11-23T10:30:00Z",
"pattern": {
"type": "weekly",
"interval": 1,
"firstDayOfWeek": "sunday",
"dayOfMonth": 0,
"daysOfWeek": [ "tuesday" ],
"index": "first",
"month": 0
}
}
},
"dueDateTime": null
}
删除定期计划
以下示例请求和响应演示如何分配 nullrecurrence.schedule,从而终止此任务的重复周期。
请求
PATCH https://graph.microsoft.com/beta/planner/tasks/GxOo0ms1iEu3eBI1-6lk85UAI5FI
{
"recurrence": {
"schedule": null
}
}
响应
HTTP/1.1 204 NO CONTENT
获取已删除重复计划的任务
以下示例请求和响应演示如何在前面的编辑之后检索任务。
请求
GET https://graph.microsoft.com/beta/planner/tasks/GxOo0ms1iEu3eBI1-6lk85UAI5FI
响应
下面是将定期系列信息保留 (recurrence.schedule = null) 的响应示例。 如果指定了新计划,则此任务仍属于同一系列。
HTTP/1.1 200 OK
Content-type: application/json
{
"_comment": "other fields omitted for brevity",
"recurrence": {
"seriesId": "w5tLb5HceUmpuiYlhdXyHg",
"occurrenceId": 2,
"previousInSeriesTaskId": "Q7SNdWp5ekeJTpRRSCcZ3pUAD6kV",
"nextInSeriesTaskId": null,
"schedule": null,
"recurrenceStartDateTime": "2021-11-13T10:30:00Z"
},
"dueDateTime": null
}
错误案例:尝试在不指定 patternStartDateTime 的情况下添加新的定期计划
以下示例请求和响应显示错误的请求,即尝试添加新 的 recurrence.schedule 而不指定 patternStartDateTime。
请求
PATCH https://graph.microsoft.com/beta/planner/tasks/GxOo0ms1iEu3eBI1-6lk85UAI5FI
{
"recurrence": {
"schedule": {
"pattern": {
"type": "daily",
"interval": 5
}
}
}
}
响应
下面是一个响应示例,其中显示了描述问题的错误。 响应对象包含 bug,因为错误消息应提及Recurrence.Schedule.PatternStartDateTime而不是 Recurrence.Schedule.Range。 这目前是一个已知问题。
HTTP/1.1 400 BAD REQUEST
Content-type: application/json
{
"error": {
"code": "",
"message": "Schema validation has failed. Validation for field 'Recurrence.Schedule.Range', on entity 'Task' has failed: A non-null value must be specified for this field.",
"innerError": {
"request-id": "922f7646-513a-4f63-a231-9cf2d7b647cb",
"date": "2021-06-22T21:37:35"
}
}
}
通过添加新计划来恢复任务的重复周期
以下示例请求和响应演示如何将新的 recurrence.schedule 分配给当前具有 recurrence.schedule = null 的任务。
注意: 未分配 dueDateTime 。
请求
PATCH https://graph.microsoft.com/beta/planner/tasks/GxOo0ms1iEu3eBI1-6lk85UAI5FI
{
"recurrence": {
"schedule": {
"pattern": {
"type": "absoluteMonthly",
"interval": 2,
"dayOfMonth": 25
},
"patternStartDateTime": "2021-11-25T10:30:00Z"
}
}
}
响应
HTTP/1.1 204 NO CONTENT
使用新的定期计划获取任务
以下示例请求和响应演示如何使用新的定期计划检索任务。
除了计划) 之外,定期属性 ( 保持不变,并且任务具有活动的重复周期,即使 dueDateTime 属性保持null为 。
请求
GET https://graph.microsoft.com/beta/planner/tasks/GxOo0ms1iEu3eBI1-6lk85UAI5FI
响应
HTTP/1.1 200 OK
Content-type: application/json
{
"_comment": "other fields omitted for brevity",
"planId": "4CaQUsrKXkyMDBhpF9cu-JUAAZ1V",
"bucketId": "mVAeurfATUOEkpxi-60a9pUAJDxm",
"title": "Water the plants",
"percentComplete": 0,
"id": "GxOo0ms1iEu3eBI1-6lk85UAI5FI",
"appliedCategories": {},
"assignments": {},
"recurrence": {
"seriesId": "w5tLb5HceUmpuiYlhdXyHg",
"occurrenceId": 2,
"previousInSeriesTaskId": "Q7SNdWp5ekeJTpRRSCcZ3pUAD6kV",
"nextInSeriesTaskId": null,
"recurrenceStartDateTime": "2021-11-13T10:30:00Z",
"schedule": {
"patternStartDateTime": "2021-11-25T10:30:00Z",
"nextOccurrenceDateTime": "2022-01-25T10:30:00Z",
"pattern": {
"type": "absoluteMonthly",
"interval": 2,
"firstDayOfWeek": "sunday",
"dayOfMonth": 25,
"daysOfWeek": [],
"index": "first",
"month": 0
}
}
},
"dueDateTime": null
}
错误案例:尝试编辑只读属性
以下示例请求和响应显示错误请求,尝试将值分配给 只读的 recurrence.seriesId 属性。
请求
PATCH https://graph.microsoft.com/beta/planner/tasks/GxOo0ms1iEu3eBI1-6lk85UAI5FI
{
"recurrence": {
"seriesId": "abc"
}
}
响应
以下响应对象显示描述问题的错误。
HTTP/1.1 400 BAD REQUEST
Content-type: application/json
{
"error": {
"code": "",
"message": "Invalid recurrence sub-property assignment(s): \"seriesId\".",
"innerError": {
"request-id": "922f7646-513a-4f63-a231-9cf2d7b647cb",
"date": "2021-06-22T21:37:35"
}
}
}
将任务标记为完成, (系列中的第 2 个任务触发重复周期,使用 null dueDateTime)
以下示例请求和响应演示如何将 percentComplete 设置为 100 (也称为 完成任务 或 ) 标记任务完成 。
请求
以下请求对于具有或不重复周期的任务相同。
PATCH https://graph.microsoft.com/beta/planner/tasks/GxOo0ms1iEu3eBI1-6lk85UAI5FI
{
"percentComplete": 100
}
响应
HTTP/1.1 204 NO CONTENT
获取现已完成的任务并发现系列中下一个 (第三个) 任务的 ID
以下示例请求和响应演示如何在任务标记为完成后检索任务。
请求
GET https://graph.microsoft.com/beta/planner/tasks/GxOo0ms1iEu3eBI1-6lk85UAI5FI
响应
HTTP/1.1 200 OK
Content-type: application/json
{
"_comment": "other fields omitted for brevity",
"planId": "4CaQUsrKXkyMDBhpF9cu-JUAAZ1V",
"bucketId": "mVAeurfATUOEkpxi-60a9pUAJDxm",
"title": "Water the plants",
"percentComplete": 100,
"id": "GxOo0ms1iEu3eBI1-6lk85UAI5FI",
"appliedCategories": {},
"assignments": {},
"recurrence": {
"seriesId": "w5tLb5HceUmpuiYlhdXyHg",
"occurrenceId": 2,
"previousInSeriesTaskId": "Q7SNdWp5ekeJTpRRSCcZ3pUAD6kV",
"nextInSeriesTaskId": "-6zr7XfE6E2JvxCSmE7Wdf8AClON",
"recurrenceStartDateTime": "2021-11-13T10:30:00Z",
"schedule": {
"patternStartDateTime": "2021-11-25T10:30:00Z",
"nextOccurrenceDateTime": "2022-01-25T10:30:00Z",
"pattern": {
"type": "absoluteMonthly",
"interval": 2,
"firstDayOfWeek": "sunday",
"dayOfMonth": 25,
"daysOfWeek": [],
"index": "first",
"month": 0
}
}
},
"dueDateTime": null
}
错误案例:在已分配 nextInSeriesTaskId 时尝试删除重复计划
以下示例请求和响应显示错误请求,尝试在分配 nextInSeriesTaskId 属性后向 recurrence.schedule 属性赋值。
请求
PATCH https://graph.microsoft.com/beta/planner/tasks/Q7SNdWp5ekeJTpRRSCcZ3pUAD6kV
{
"recurrence": {
"schedule": null
}
}
响应
以下响应对象显示描述问题的错误。
HTTP/1.1 400 BAD REQUEST
Content-type: application/json
{
"error": {
"code": "",
"message": "Schema validation has failed. Validation for field 'Recurrence', on entity 'Task' has failed: Cannot add/edit/delete recurrence when the next instance should already be created.",
"innerError": {
"request-id": "922f7646-513a-4f63-a231-9cf2d7b647cb",
"date": "2021-06-22T21:37:35"
}
}
}
获取系列中的新任务 (第三次出现)
以下示例请求和响应演示如何检索系列中的新任务,该系列中的 ID 是从上一响应中的 nextInSeriesTaskId 发现的。
dueDateTime 已分配给任务的上一个 NextOccurrenceDateTime 中显示的值,即使该任务的上一个 dueDateTime 为 。null
请求
GET https://graph.microsoft.com/beta/planner/tasks/-6zr7XfE6E2JvxCSmE7Wdf8AClON
响应
HTTP/1.1 200 OK
Content-type: application/json
{
"_comment": "other fields omitted for brevity",
"planId": "4CaQUsrKXkyMDBhpF9cu-JUAAZ1V",
"bucketId": "mVAeurfATUOEkpxi-60a9pUAJDxm",
"title": "Water the plants",
"percentComplete": 0,
"id": "-6zr7XfE6E2JvxCSmE7Wdf8AClON",
"appliedCategories": {},
"assignments": {},
"recurrence": {
"seriesId": "w5tLb5HceUmpuiYlhdXyHg",
"occurrenceId": 3,
"previousInSeriesTaskId": "GxOo0ms1iEu3eBI1-6lk85UAI5FI",
"nextInSeriesTaskId": null,
"recurrenceStartDateTime": "2021-11-13T10:30:00Z",
"schedule": {
"patternStartDateTime": "2021-11-25T10:30:00Z",
"nextOccurrenceDateTime": "2022-03-25T10:30:00Z",
"pattern": {
"type": "absoluteMonthly",
"interval": 2,
"firstDayOfWeek": "sunday",
"dayOfMonth": 25,
"daysOfWeek": [],
"index": "first",
"month": 0
}
}
},
"dueDateTime": "2022-01-25T10:30:00Z"
}