Skip to content

Commit 9f3f15c

Browse files
committed
Projects
1 parent 9707994 commit 9f3f15c

File tree

5 files changed

+440
-1
lines changed

5 files changed

+440
-1
lines changed

Tests/Integration/Projects.Tests.ps1

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
Import-Module -Name Pester -Force
2+
Import-Module .\Toggl.API\Toggl.API.psm1 -Force
3+
4+
$configPath = Join-Path -Path $PSScriptRoot -ChildPath "..\config.json"
5+
$config = Get-Content -Path $configPath | ConvertFrom-Json
6+
7+
$apiToken = $config.apiToken
8+
$workspaceId = $config.workspaceId
9+
10+
Describe 'Toggl Projects Integration Tests' {
11+
$projectName = "TestProjectToRemove"
12+
$projectId = $null
13+
14+
Context "New-TogglProject" {
15+
It "should create a new project in the workspace" {
16+
$newProject = New-TogglProject `
17+
-ApiToken $apiToken `
18+
-WorkspaceId $workspaceId `
19+
-Name $projectName `
20+
-Active $true
21+
22+
$newProject | Should -Not -BeNullOrEmpty
23+
$newProject.name | Should -BeExactly $projectName
24+
$Script:projectId = $newProject.id
25+
}
26+
}
27+
28+
Context "Get-TogglProjects" {
29+
It "should retrieve the project from the workspace" {
30+
$projects = Get-TogglProjects `
31+
-ApiToken $apiToken `
32+
-WorkspaceId $workspaceId `
33+
-SortPinned $true `
34+
-Name $projectName `
35+
-Page 1 `
36+
-SortField "name" `
37+
-SortOrder "asc" `
38+
-OnlyTemplates $false
39+
$projects | Where-Object { $_.id -eq $Script:projectId } | Should -Not -BeNullOrEmpty
40+
}
41+
}
42+
43+
Context "Remove-TogglProject" {
44+
It "should delete the project from the workspace" -Skip:($Script:projectId -eq $null) {
45+
Remove-TogglProject `
46+
-ApiToken $apiToken `
47+
-WorkspaceId $workspaceId `
48+
-ProjectId $Script:projectId
49+
50+
# Verify the project was deleted
51+
$projects = Get-TogglProjects `
52+
-ApiToken $apiToken `
53+
-WorkspaceId $workspaceId `
54+
-SortPinned $true `
55+
-Name $projectName `
56+
-Page 1 `
57+
-SortField "name" `
58+
-SortOrder "asc" `
59+
-OnlyTemplates $false
60+
$projects | Where-Object { $_.id -eq $Script:projectId } | Should BeNullOrEmpty
61+
}
62+
}
63+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
<#
2+
.SYNOPSIS
3+
Gets projects for a specified workspace in Toggl.
4+
5+
.DESCRIPTION
6+
This cmdlet retrieves the list of projects for a specified workspace from Toggl. It sends a GET request to the Toggl API.
7+
8+
.PARAMETER ApiToken
9+
The API token for authentication. (Mandatory)
10+
11+
.PARAMETER WorkspaceId
12+
Numeric ID of the workspace. (Mandatory)
13+
14+
.PARAMETER SortPinned
15+
Place pinned projects at top of response. (Mandatory)
16+
17+
.PARAMETER Active
18+
Return active or inactive projects. You can pass 'both' to get both active and inactive projects. (Optional)
19+
20+
.PARAMETER Since
21+
Retrieve projects created/modified/deleted since this date using UNIX timestamp. (Optional)
22+
23+
.PARAMETER Billable
24+
Filter by billable projects. (Optional)
25+
26+
.PARAMETER UserIds
27+
Filter by user IDs. (Optional)
28+
29+
.PARAMETER ClientIds
30+
Filter by client IDs. (Optional)
31+
32+
.PARAMETER GroupIds
33+
Filter by group IDs. (Optional)
34+
35+
.PARAMETER Statuses
36+
Filter by project statuses. (Optional)
37+
38+
.PARAMETER Name
39+
Filter by project name. (Mandatory)
40+
41+
.PARAMETER Page
42+
Page number for pagination. (Mandatory)
43+
44+
.PARAMETER SortField
45+
Field to sort by. (Mandatory)
46+
47+
.PARAMETER SortOrder
48+
Order to sort by. (Mandatory)
49+
50+
.PARAMETER OnlyTemplates
51+
Filter by template projects. (Mandatory)
52+
53+
.PARAMETER OnlyMe
54+
Get only projects assigned to the current user. (Optional)
55+
56+
.PARAMETER PerPage
57+
Number of items per page, default 151. Cannot exceed 200. (Optional)
58+
59+
.EXAMPLE
60+
Get-TogglProjects -ApiToken "your_api_token" -WorkspaceId 123456 -SortPinned $true -Name "ProjectName" -Page 1 -SortField "name" -SortOrder "asc" -OnlyTemplates $false
61+
#>
62+
function Get-TogglProjects {
63+
[CmdletBinding()]
64+
param (
65+
[Parameter(Mandatory = $true)]
66+
[string]$ApiToken,
67+
68+
[Parameter(Mandatory = $true)]
69+
[int]$WorkspaceId,
70+
71+
[bool]$SortPinned,
72+
73+
[Parameter()]
74+
[bool]$Active,
75+
76+
[Parameter()]
77+
[int]$Since,
78+
79+
[Parameter()]
80+
[bool]$Billable,
81+
82+
[Parameter()]
83+
[int[]]$UserIds,
84+
85+
[Parameter()]
86+
[int[]]$ClientIds,
87+
88+
[Parameter()]
89+
[int[]]$GroupIds,
90+
91+
[Parameter()]
92+
[string[]]$Statuses,
93+
94+
[string]$Name,
95+
96+
[int]$Page,
97+
98+
[string]$SortField,
99+
100+
[string]$SortOrder,
101+
102+
[bool]$OnlyTemplates,
103+
104+
[Parameter()]
105+
[bool]$OnlyMe,
106+
107+
[Parameter()]
108+
[int]$PerPage = 151
109+
)
110+
111+
$params = @{
112+
sort_pinned = $SortPinned
113+
name = $Name
114+
page = $Page
115+
sort_field = $SortField
116+
sort_order = $SortOrder
117+
only_templates = $OnlyTemplates
118+
}
119+
120+
if ($PSBoundParameters.ContainsKey('Active')) { $params['active'] = $Active }
121+
if ($PSBoundParameters.ContainsKey('Since')) { $params['since'] = $Since }
122+
if ($PSBoundParameters.ContainsKey('Billable')) { $params['billable'] = $Billable }
123+
if ($PSBoundParameters.ContainsKey('UserIds')) { $params['user_ids'] = $UserIds }
124+
if ($PSBoundParameters.ContainsKey('ClientIds')) { $params['client_ids'] = $ClientIds }
125+
if ($PSBoundParameters.ContainsKey('GroupIds')) { $params['group_ids'] = $GroupIds }
126+
if ($PSBoundParameters.ContainsKey('Statuses')) { $params['statuses'] = $Statuses }
127+
if ($PSBoundParameters.ContainsKey('OnlyMe')) { $params['only_me'] = $OnlyMe }
128+
if ($PSBoundParameters.ContainsKey('PerPage')) { $params['per_page'] = $PerPage }
129+
130+
$queryString = ($params.GetEnumerator() | ForEach-Object { "$($_.Key)=$($_.Value)" }) -join '&'
131+
$url = "$Global:TogglBaseUrl/workspaces/$WorkspaceId/projects?$queryString"
132+
133+
$headers = Get-TogglAuthHeader -ApiToken $ApiToken
134+
135+
try {
136+
$response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get
137+
return $response
138+
}
139+
catch {
140+
Write-Error "Failed to retrieve projects: $_"
141+
}
142+
}
143+
144+
Export-ModuleMember -Function Get-TogglProjects
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
<#
2+
.SYNOPSIS
3+
Creates a new project in a specified workspace in Toggl.
4+
5+
.DESCRIPTION
6+
This cmdlet creates a new project in a specified workspace in Toggl. It sends a POST request to the Toggl API.
7+
8+
.PARAMETER ApiToken
9+
The API token for authentication. (Mandatory)
10+
11+
.PARAMETER WorkspaceId
12+
Numeric ID of the workspace. (Mandatory)
13+
14+
.PARAMETER Name
15+
Project name. (Mandatory)
16+
17+
.PARAMETER Active
18+
Whether the project is active or archived. (Optional)
19+
20+
.PARAMETER AutoEstimates
21+
Whether estimates are based on task hours, optional, premium feature. (Optional)
22+
23+
.PARAMETER Billable
24+
Whether the project is set as billable, optional, premium feature. (Optional)
25+
26+
.PARAMETER ClientId
27+
Client ID, optional. (Optional)
28+
29+
.PARAMETER ClientName
30+
Client name, optional. (Optional)
31+
32+
.PARAMETER Color
33+
Project color. (Optional)
34+
35+
.PARAMETER Currency
36+
Project currency, optional, premium feature. (Optional)
37+
38+
.PARAMETER EndDate
39+
End date of a project timeframe. (Optional)
40+
41+
.PARAMETER EstimatedHours
42+
Estimated hours, optional, premium feature. (Optional)
43+
44+
.PARAMETER ExternalReference
45+
External reference. (Optional)
46+
47+
.PARAMETER FixedFee
48+
Project fixed fee, optional, premium feature. (Optional)
49+
50+
.PARAMETER IsPrivate
51+
Whether the project is private or not. (Optional)
52+
53+
.PARAMETER IsShared
54+
Whether the project is shared. (Optional)
55+
56+
.PARAMETER Rate
57+
Hourly rate, optional, premium feature. (Optional)
58+
59+
.PARAMETER RateChangeMode
60+
Rate change mode, optional, premium feature. Can be "start-today", "override-current", "override-all". (Optional)
61+
62+
.PARAMETER Recurring
63+
Whether the project is recurring, optional, premium feature. (Optional)
64+
65+
.PARAMETER RecurringParameters
66+
Project recurring parameters, optional, premium feature. (Optional)
67+
68+
.PARAMETER StartDate
69+
Start date of a project timeframe. (Optional)
70+
71+
.PARAMETER Template
72+
Whether the project is a template, optional, premium feature. (Optional)
73+
74+
.PARAMETER TemplateId
75+
Template ID, optional. (Optional)
76+
77+
.EXAMPLE
78+
New-TogglProject -ApiToken "your_api_token" -WorkspaceId 123456 -Name "New Project"
79+
#>
80+
function New-TogglProject {
81+
[CmdletBinding()]
82+
param (
83+
[Parameter(Mandatory = $true)]
84+
[string]$ApiToken,
85+
86+
[Parameter(Mandatory = $true)]
87+
[int]$WorkspaceId,
88+
89+
[Parameter(Mandatory = $true)]
90+
[string]$Name,
91+
92+
[bool]$Active,
93+
94+
[bool]$AutoEstimates,
95+
96+
[bool]$Billable,
97+
98+
[int]$ClientId,
99+
100+
[string]$ClientName,
101+
102+
[string]$Color,
103+
104+
[string]$Currency,
105+
106+
[string]$EndDate,
107+
108+
[int]$EstimatedHours,
109+
110+
[string]$ExternalReference,
111+
112+
[decimal]$FixedFee,
113+
114+
[bool]$IsPrivate,
115+
116+
[bool]$IsShared,
117+
118+
[decimal]$Rate,
119+
120+
[string]$RateChangeMode,
121+
122+
[bool]$Recurring,
123+
124+
[psobject]$RecurringParameters,
125+
126+
[string]$StartDate,
127+
128+
[bool]$Template,
129+
130+
[int]$TemplateId
131+
)
132+
133+
$url = "$Global:TogglBaseUrl/workspaces/$WorkspaceId/projects"
134+
135+
$body = @{
136+
name = $Name
137+
}
138+
139+
if ($PSBoundParameters.ContainsKey('Active')) { $body.active = $Active }
140+
if ($PSBoundParameters.ContainsKey('AutoEstimates')) { $body.auto_estimates = $AutoEstimates }
141+
if ($PSBoundParameters.ContainsKey('Billable')) { $body.billable = $Billable }
142+
if ($PSBoundParameters.ContainsKey('ClientId')) { $body.client_id = $ClientId }
143+
if ($PSBoundParameters.ContainsKey('ClientName')) { $body.client_name = $ClientName }
144+
if ($PSBoundParameters.ContainsKey('Color')) { $body.color = $Color }
145+
if ($PSBoundParameters.ContainsKey('Currency')) { $body.currency = $Currency }
146+
if ($PSBoundParameters.ContainsKey('EndDate')) { $body.end_date = $EndDate }
147+
if ($PSBoundParameters.ContainsKey('EstimatedHours')) { $body.estimated_hours = $EstimatedHours }
148+
if ($PSBoundParameters.ContainsKey('ExternalReference')) { $body.external_reference = $ExternalReference }
149+
if ($PSBoundParameters.ContainsKey('FixedFee')) { $body.fixed_fee = $FixedFee }
150+
if ($PSBoundParameters.ContainsKey('IsPrivate')) { $body.is_private = $IsPrivate }
151+
if ($PSBoundParameters.ContainsKey('IsShared')) { $body.is_shared = $IsShared }
152+
if ($PSBoundParameters.ContainsKey('Rate')) { $body.rate = $Rate }
153+
if ($PSBoundParameters.ContainsKey('RateChangeMode')) { $body.rate_change_mode = $RateChangeMode }
154+
if ($PSBoundParameters.ContainsKey('Recurring')) { $body.recurring = $Recurring }
155+
if ($PSBoundParameters.ContainsKey('RecurringParameters')) { $body.recurring_parameters = $RecurringParameters }
156+
if ($PSBoundParameters.ContainsKey('StartDate')) { $body.start_date = $StartDate }
157+
if ($PSBoundParameters.ContainsKey('Template')) { $body.template = $Template }
158+
if ($PSBoundParameters.ContainsKey('TemplateId')) { $body.template_id = $TemplateId }
159+
160+
$jsonBody = $body | ConvertTo-Json -Compress -Depth 10
161+
162+
$headers = Get-TogglAuthHeader -ApiToken $ApiToken
163+
$headers.Add("Content-Type", "application/json")
164+
165+
try {
166+
$response = Invoke-RestMethod -Uri $url -Method Post -Headers $headers -Body $jsonBody
167+
return $response
168+
}
169+
catch {
170+
Write-Error "Failed to create project: $_"
171+
}
172+
}
173+
174+
Export-ModuleMember -Function New-TogglProject

0 commit comments

Comments
 (0)