Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds extra parameters for Add-PnPPlannerTask cmdlet #1964

Merged
merged 2 commits into from
Jun 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Added `Add-PnPListItemAttachment` cmdlet to provide ability to upload a file as an attachment to a SharePoint list item. [#1932](https://github.com/pnp/powershell/pull/1932)
- Added `Remove-PnPListItemAttachment` cmdlet to provide ability to delete a list item attachment. [#1932](https://github.com/pnp/powershell/pull/1932)
- Added `Get-PnPListItemAttachment` cmdlet to download the attachments from a list item. [#1932](https://github.com/pnp/powershell/pull/1932)
- Added `-PercentComplete`, `-Priority`, `-StartDateTime`, `-DueDateTime` and `-Description` to `Add-PnPPlannerTask` [#1964](https://github.com/pnp/powershell/pull/1964)

### Changed
- Changed `Sync-PnPSharePointUserProfilesFromAzureActiveDirectory` to map users based on their Ids instead which should resolve some issues around user identities reporting not to exist. You can use the new `-IdType` option to switch it back to `PrincipalName` if needed. [#1752](https://github.com/pnp/powershell/pull/1752)
Expand Down
89 changes: 87 additions & 2 deletions documentation/Add-PnPPlannerTask.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,18 @@ Adds a new task to a planner bucket

### By Group
```powershell
Add-PnPPlannerTask -Group <PlannerGroupPipeBind> -Plan <PlannerPlanPipeBind> -Bucket <PlannerBucketPipeBind> -Title <String> [-AssignedTo <String[]>]
Add-PnPPlannerTask -Group <PlannerGroupPipeBind> -Plan <PlannerPlanPipeBind> -Bucket <PlannerBucketPipeBind> -Title <String>
[-PercentComplete <Int32>] [-DueDateTime <DateTime>] [-StartDateTime <DateTime>]
[-AssignedTo <String[]] [-Priority <Int32>] [-Description <String>]
[<CommonParameters>]
```

### By Plan Id
```powershell
Add-PnPPlannerTask -Bucket <PlannerBucketPipeBind> -PlanId <String> -Title <String> [-AssignedTo <String[]>]
Add-PnPPlannerTask -Bucket <PlannerBucketPipeBind> -PlanId <String> -Title <String>
[-PercentComplete <Int32>] [-DueDateTime <DateTime>] [-StartDateTime <DateTime>]
[-AssignedTo <String[]] [-Priority <Int32>] [-Description <String>]
[<CommonParameters>]
```

## DESCRIPTION
Expand Down Expand Up @@ -148,6 +154,85 @@ Accept pipeline input: False
Accept wildcard characters: False
```

### -StartDateTime
Defines the start date of the task.

```yaml
Type: DateTime
Parameter Sets: (All)
Aliases:

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```

### -DueDateTime
Specify the due date.

```yaml
Type: DateTime
Parameter Sets: (All)
Aliases:

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```

### -PercentComplete
Defines the percentage of completeness of the task.

```yaml
Type: Int32
Parameter Sets: (All)
Aliases:

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```

### -Priority
Sets the priority of the task. Value should be a number between 0 and 10.
- values 0 and 1 are interpreted as _Urgent_
- values 2, 3 and 4 are interpreted as _Important_
- values 5, 6 and 7 are interpreted as _Medium_
- values 8, 9 and 10 are interpreted as _Low_

```yaml
Type: Int32
Parameter Sets: (All)
Aliases:

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```

### -Description
Sets the description (notes) of the task.

```yaml
Type: String
Parameter Sets: (All)
Aliases:

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```

### CommonParameters
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).

Expand Down
125 changes: 98 additions & 27 deletions src/Commands/Planner/AddPlannerTask.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
using System.Management.Automation;
using PnP.PowerShell.Commands.Attributes;
using PnP.PowerShell.Commands.Base;
using PnP.PowerShell.Commands.Base.PipeBinds;
using PnP.PowerShell.Commands.Model.Planner;
using PnP.PowerShell.Commands.Utilities;
using PnP.PowerShell.Commands.Utilities.REST;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;

namespace SharePointPnP.PowerShell.Commands.Graph
namespace PnP.PowerShell.Commands.Planner
{
[Cmdlet(VerbsCommon.Add, "PnPPlannerTask")]
[RequiredMinimalApiPermissions("Group.ReadWrite.All")]
Expand All @@ -28,53 +33,119 @@ public class AddPlannerTask : PnPGraphCmdlet
[Parameter(Mandatory = true, ParameterSetName = ParameterAttribute.AllParameterSets)]
public string Title;

[Parameter(Mandatory = false)]
public int PercentComplete;

[Parameter(Mandatory = false)]
public int Priority;

[Parameter(Mandatory = false)]
public DateTime DueDateTime;

[Parameter(Mandatory = false)]
public DateTime StartDateTime;

[Parameter(Mandatory = false)]
public string Description;

[Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets)]
public string[] AssignedTo;

protected override void ExecuteCmdlet()
{
PlannerTask createdTask;
var newTask = new PlannerTask
{
Title = Title
};

if (ParameterSpecified(nameof(PercentComplete)))
{
if (PercentComplete < 0 || PercentComplete > 100)
{
throw new PSArgumentException($"{nameof(PercentComplete)} value must be between 0 and 100.", nameof(PercentComplete));
}

newTask.PercentComplete = PercentComplete;
}

if (ParameterSetName == ParameterName_BYGROUP)
if (ParameterSpecified(nameof(Priority)))
{
var groupId = Group.GetGroupId(HttpClient, AccessToken);
if (groupId != null)
if (Priority < 0 || Priority > 10)
{
var planId = Plan.GetIdAsync(HttpClient, AccessToken, groupId).GetAwaiter().GetResult();
throw new PSArgumentException($"{nameof(Priority)} value must be between 0 and 10.", nameof(Priority));
}
newTask.Priority = Priority;
}

if (planId != null)
{
var bucket = Bucket.GetBucket(HttpClient, AccessToken, planId);
if (bucket != null)
{
PlannerUtility.AddTaskAsync(HttpClient, AccessToken, planId, bucket.Id, Title, AssignedTo).GetAwaiter().GetResult();
}
else
{
throw new PSArgumentException("Bucket not found", nameof(Bucket));
}
if (ParameterSpecified(nameof(StartDateTime)))
{
newTask.StartDateTime = StartDateTime.ToUniversalTime();
}

}
else
if (ParameterSpecified(nameof(DueDateTime)))
{
newTask.DueDateTime = DueDateTime.ToUniversalTime();
}

if (ParameterSpecified(nameof(AssignedTo)))
{
newTask.Assignments = new Dictionary<string, TaskAssignment>();
var chunks = AssignedTo.Chunk(20);
foreach (var chunk in chunks)
{
var userIds = BatchUtility.GetPropertyBatchedAsync(HttpClient, AccessToken, chunk.ToArray(), "/users/{0}", "id").GetAwaiter().GetResult();
foreach (var userId in userIds)
{
throw new PSArgumentException("Plan not found", nameof(Plan));
newTask.Assignments.Add(userId.Value, new TaskAssignment());
}
}
else
}

// By Group
if (ParameterSetName == ParameterName_BYGROUP)
{
var groupId = Group.GetGroupId(HttpClient, AccessToken);
if (groupId == null)
{
throw new PSArgumentException("Group not found", nameof(Group));
}

var planId = Plan.GetIdAsync(HttpClient, AccessToken, groupId).GetAwaiter().GetResult();
if (planId == null)
{
throw new PSArgumentException("Plan not found", nameof(Plan));
}
newTask.PlanId = planId;

var bucket = Bucket.GetBucket(HttpClient, AccessToken, planId);
if (bucket == null)
{
throw new PSArgumentException("Bucket not found", nameof(Bucket));
}
newTask.BucketId = bucket.Id;

createdTask = PlannerUtility.AddTaskAsync(HttpClient, AccessToken, newTask).GetAwaiter().GetResult();
}
else if (ParameterSetName == ParameterName_BYPLANID)
// By PlanId
else
{
var bucket = Bucket.GetBucket(HttpClient, AccessToken, PlanId);
if (bucket != null)
{
PlannerUtility.AddTaskAsync(HttpClient, AccessToken, PlanId, bucket.Id, Title).GetAwaiter().GetResult();
}
else
if (bucket == null)
{
throw new PSArgumentException("Bucket not found", nameof(Bucket));
}

newTask.PlanId = PlanId;
newTask.BucketId = bucket.Id;

createdTask = PlannerUtility.AddTaskAsync(HttpClient, AccessToken, newTask).GetAwaiter().GetResult();
}

if (ParameterSpecified(nameof(Description)))
{
var existingTaskDetails = PlannerUtility.GetTaskDetailsAsync(HttpClient, AccessToken, createdTask.Id, false).GetAwaiter().GetResult();
PlannerUtility.UpdateTaskDetailsAsync(HttpClient, AccessToken, existingTaskDetails, Description).GetAwaiter().GetResult();
}
}
}
Expand Down
24 changes: 2 additions & 22 deletions src/Commands/Utilities/PlannerUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,29 +161,9 @@ public static async Task<PlannerTaskDetails> GetTaskDetailsAsync(HttpClient http
return taskDetails;
}

public static async Task<PlannerTask> AddTaskAsync(HttpClient httpClient, string accessToken, string planId, string bucketId, string title, string[] assignedTo = null)
public static async Task<PlannerTask> AddTaskAsync(HttpClient httpClient, string accessToken, PlannerTask task)
{
StringContent stringContent = null;
if (assignedTo != null)
{
var assignments = new Dictionary<string, object>();
var chunks = BatchUtility.Chunk(assignedTo, 20);
foreach (var chunk in chunks)
{
var results = await BatchUtility.GetPropertyBatchedAsync(httpClient, accessToken, chunk.ToArray(), "/users/{0}", "id");
foreach (var userid in results.Select(r => r.Value))
{
assignments.Add(userid, new Model.Planner.PlannerAssignedToUser());
}
}
stringContent = new StringContent(JsonSerializer.Serialize(new { planId = planId, bucketId = bucketId, title = title, assignments = assignments }));
}
else
{
stringContent = new StringContent(JsonSerializer.Serialize(new { planId = planId, bucketId = bucketId, title = title }));
}
stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
return await GraphHelper.PostAsync<PlannerTask>(httpClient, "v1.0/planner/tasks", stringContent, accessToken);
return await GraphHelper.PostAsync(httpClient, "v1.0/planner/tasks", task, accessToken);
}

public static async Task DeleteTaskAsync(HttpClient httpClient, string accessToken, string taskId)
Expand Down