Skip to content
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changes between versions

## 8.1.0 (2025-03-27)

* upgrade to `janephp/open-api` 7.9
* update the SDK based on the latest spec updates - see jolicode/harvest-openapi-generator#31 in #51
* add the `approval_status` in the Expense and Time Entry objects

## 8.0.0 (2025-03-27)

* update the SDK based on the latest spec updates - see jolicode/harvest-openapi-generator#30 in #50
Expand Down
124 changes: 80 additions & 44 deletions Resources/harvest-openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,11 @@ components:
nullable: true
is_closed:
type: boolean
description: 'Whether the expense has been approved or not.'
description: 'Whether the expense has been approved or not. Deprecated, use approval_status instead.'
nullable: true
approval_status:
type: string
description: 'The approval status of the expense. Possible values: “unsubmitted”, “submitted”, or “approved”.'
nullable: true
is_locked:
type: boolean
Expand Down Expand Up @@ -1301,7 +1305,11 @@ components:
nullable: true
is_closed:
type: boolean
description: 'Whether or not the time entry has been approved via Timesheet Approval.'
description: 'Whether or not the time entry has been approved via Timesheet Approval. Deprecated, use approval_status instead.'
nullable: true
approval_status:
type: string
description: 'The approval status of the time entry. Possible values: “unsubmitted”, “submitted”, or “approved”.'
nullable: true
is_billed:
type: boolean
Expand Down Expand Up @@ -1538,11 +1546,6 @@ components:
description: 'Rate for projects billed by Project Hourly Rate.'
nullable: true
format: float
budget:
type: number
description: 'The budget in hours for the project when budgeting by time.'
nullable: true
format: float
budget_by:
type: string
description: 'The method by which the project is budgeted.'
Expand All @@ -1551,6 +1554,20 @@ components:
type: boolean
description: 'Option to have the budget reset every month.'
nullable: true
budget:
type: number
description: 'The budget in hours for the project when budgeting by time.'
nullable: true
format: float
cost_budget:
type: number
description: 'The monetary budget for the project when budgeting by money.'
nullable: true
format: float
cost_budget_include_expenses:
type: boolean
description: 'Option for budget of Total Project Fees projects to include tracked expenses.'
nullable: true
notify_when_over_budget:
type: boolean
description: 'Whether Project Managers should be notified when the project goes over budget.'
Expand All @@ -1569,15 +1586,6 @@ components:
type: boolean
description: 'Option to show project budget to all employees. Does not apply to Total Project Fee projects.'
nullable: true
cost_budget:
type: number
description: 'The monetary budget for the project when budgeting by money.'
nullable: true
format: float
cost_budget_include_expenses:
type: boolean
description: 'Option for budget of Total Project Fees projects to include tracked expenses.'
nullable: true
fee:
type: number
description: 'The amount you plan to invoice for the project. Only used by fixed-fee projects.'
Expand Down Expand Up @@ -5360,6 +5368,7 @@ paths:
total_cost: 33.35
units: 1.0
is_closed: false
approval_status: unsubmitted
is_locked: true
is_billed: true
locked_reason: 'Expense is invoiced.'
Expand Down Expand Up @@ -5405,6 +5414,7 @@ paths:
total_cost: 100.0
units: 1.0
is_closed: true
approval_status: approved
is_locked: true
is_billed: false
locked_reason: 'The project is locked for this time period.'
Expand Down Expand Up @@ -5484,6 +5494,13 @@ paths:
in: query
schema:
type: boolean
-
name: approval_status
description: 'Only return expenses with the given approval status. Possible values: “unsubmitted”, “submitted”, or “approved”.'
required: false
in: query
schema:
type: string
-
name: updated_since
description: 'Only return expenses that have been updated since the given date and time.'
Expand Down Expand Up @@ -5543,6 +5560,7 @@ paths:
total_cost: 13.59
units: 1.0
is_closed: false
approval_status: unsubmitted
is_locked: false
is_billed: false
locked_reason: null
Expand Down Expand Up @@ -5688,6 +5706,7 @@ paths:
total_cost: 33.35
units: 1.0
is_closed: false
approval_status: unsubmitted
is_locked: true
is_billed: true
locked_reason: 'Expense is invoiced.'
Expand Down Expand Up @@ -5764,6 +5783,7 @@ paths:
total_cost: 13.59
units: 1.0
is_closed: false
approval_status: unsubmitted
is_locked: false
is_billed: false
locked_reason: null
Expand Down Expand Up @@ -7616,11 +7636,6 @@ paths:
description: 'Rate for projects billed by Project Hourly Rate.'
nullable: true
format: float
budget:
type: number
description: 'The budget in hours for the project when budgeting by time.'
nullable: true
format: float
budget_by:
type: string
description: 'The method by which the project is budgeted. Options: project (Hours Per Project), project_cost (Total Project Fees), task (Hours Per Task), task_fees (Fees Per Task), person (Hours Per Person), none (No Budget).'
Expand All @@ -7629,6 +7644,20 @@ paths:
type: boolean
description: 'Option to have the budget reset every month. Defaults to false.'
nullable: true
budget:
type: number
description: 'The budget in hours for the project when budgeting by time.'
nullable: true
format: float
cost_budget:
type: number
description: 'The monetary budget for the project when budgeting by money.'
nullable: true
format: float
cost_budget_include_expenses:
type: boolean
description: 'Option for budget of Total Project Fees projects to include tracked expenses. Defaults to false.'
nullable: true
notify_when_over_budget:
type: boolean
description: 'Whether Project Managers should be notified when the project goes over budget. Defaults to false.'
Expand All @@ -7642,15 +7671,6 @@ paths:
type: boolean
description: 'Option to show project budget to all employees. Does not apply to Total Project Fee projects. Defaults to false.'
nullable: true
cost_budget:
type: number
description: 'The monetary budget for the project when budgeting by money.'
nullable: true
format: float
cost_budget_include_expenses:
type: boolean
description: 'Option for budget of Total Project Fees projects to include tracked expenses. Defaults to false.'
nullable: true
fee:
type: number
description: 'The amount you plan to invoice for the project. Only used by fixed-fee projects.'
Expand Down Expand Up @@ -7864,11 +7884,6 @@ paths:
description: 'Rate for projects billed by Project Hourly Rate.'
nullable: true
format: float
budget:
type: number
description: 'The budget in hours for the project when budgeting by time.'
nullable: true
format: float
budget_by:
type: string
description: 'The method by which the project is budgeted. Options: project (Hours Per Project), project_cost (Total Project Fees), task (Hours Per Task), task_fees (Fees Per Task), person (Hours Per Person), none (No Budget).'
Expand All @@ -7877,6 +7892,20 @@ paths:
type: boolean
description: 'Option to have the budget reset every month. Defaults to false.'
nullable: true
budget:
type: number
description: 'The budget in hours for the project when budgeting by time.'
nullable: true
format: float
cost_budget:
type: number
description: 'The monetary budget for the project when budgeting by money.'
nullable: true
format: float
cost_budget_include_expenses:
type: boolean
description: 'Option for budget of Total Project Fees projects to include tracked expenses. Defaults to false.'
nullable: true
notify_when_over_budget:
type: boolean
description: 'Whether Project Managers should be notified when the project goes over budget. Defaults to false.'
Expand All @@ -7890,15 +7919,6 @@ paths:
type: boolean
description: 'Option to show project budget to all employees. Does not apply to Total Project Fee projects. Defaults to false.'
nullable: true
cost_budget:
type: number
description: 'The monetary budget for the project when budgeting by money.'
nullable: true
format: float
cost_budget_include_expenses:
type: boolean
description: 'Option for budget of Total Project Fees projects to include tracked expenses. Defaults to false.'
nullable: true
fee:
type: number
description: 'The amount you plan to invoice for the project. Only used by fixed-fee projects.'
Expand Down Expand Up @@ -10479,6 +10499,7 @@ paths:
is_locked: true
locked_reason: 'Item Approved and Locked for this Time Period'
is_closed: true
approval_status: approved
is_billed: false
timer_started_at: null
started_time: '3:00pm'
Expand Down Expand Up @@ -10530,6 +10551,7 @@ paths:
is_locked: true
locked_reason: 'Item Invoiced and Approved and Locked for this Time Period'
is_closed: true
approval_status: approved
is_billed: true
timer_started_at: null
started_time: '1:00pm'
Expand Down Expand Up @@ -10583,6 +10605,7 @@ paths:
is_locked: true
locked_reason: 'Item Approved and Locked for this Time Period'
is_closed: true
approval_status: approved
is_billed: false
timer_started_at: null
started_time: '11:00am'
Expand Down Expand Up @@ -10634,6 +10657,7 @@ paths:
is_locked: true
locked_reason: 'Item Invoiced and Approved and Locked for this Time Period'
is_closed: true
approval_status: approved
is_billed: true
timer_started_at: null
started_time: '9:00am'
Expand Down Expand Up @@ -10714,6 +10738,13 @@ paths:
in: query
schema:
type: boolean
-
name: approval_status
description: 'Only return time entries with the given approval status. Possible values: “unsubmitted”, “submitted”, or “approved”.'
required: false
in: query
schema:
type: string
-
name: updated_since
description: 'Only return time entries that have been updated since the given date and time. Use the ISO 8601 Format.'
Expand Down Expand Up @@ -10806,6 +10837,7 @@ paths:
is_locked: false
locked_reason: null
is_closed: false
approval_status: unsubmitted
is_billed: false
timer_started_at: null
started_time: null
Expand Down Expand Up @@ -10975,6 +11007,7 @@ paths:
is_locked: true
locked_reason: 'Item Invoiced and Approved and Locked for this Time Period'
is_closed: true
approval_status: approved
is_billed: true
timer_started_at: null
started_time: '1:00pm'
Expand Down Expand Up @@ -11059,6 +11092,7 @@ paths:
is_locked: false
locked_reason: null
is_closed: false
approval_status: unsubmitted
is_billed: false
timer_started_at: null
started_time: null
Expand Down Expand Up @@ -11227,6 +11261,7 @@ paths:
is_locked: false
locked_reason: null
is_closed: false
approval_status: unsubmitted
is_billed: false
timer_started_at: '2017-08-22T17:40:24Z'
started_time: '11:40am'
Expand Down Expand Up @@ -11310,6 +11345,7 @@ paths:
is_locked: false
locked_reason: null
is_closed: false
approval_status: unsubmitted
is_billed: false
timer_started_at: null
started_time: '11:37am'
Expand Down
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@
},
"require": {
"php": ">=8.2",
"jane-php/open-api-runtime": "^7.6",
"jane-php/open-api-runtime": "^7.9",
"php-http/client-common": "^1.9 || ^2.0",
"php-http/client-implementation": "*"
},
"require-dev": {
"jane-php/open-api-3": "^7.6",
"jane-php/open-api-3": "^7.9",
"nyholm/psr7": "^1.6",
"symfony/http-client": "^6.4 || ^7.0",
"symfony/phpunit-bridge": "^6.4 || ^7.0"
"symfony/http-client": "^6.4 || ^7.0 || ^8.0",
"symfony/phpunit-bridge": "^6.4 || ^7.0 || ^8.0"
},
"config": {
"allow-plugins": {
Expand Down
2 changes: 2 additions & 0 deletions generated/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ public function updateExpenseCategory(string $expenseCategoryId, Model\ExpenseCa
* @var int $client_id only return expenses belonging to the client with the given ID
* @var int $project_id only return expenses belonging to the project with the given ID
* @var bool $is_billed pass true to only return expenses that have been invoiced and false to return expenses that have not been invoiced
* @var string $approval_status Only return expenses with the given approval status. Possible values: “unsubmitted”, “submitted”, or “approved”.
* @var string $updated_since only return expenses that have been updated since the given date and time
* @var string $from only return expenses with a spent_date on or after the given date
* @var string $to only return expenses with a spent_date on or before the given date
Expand Down Expand Up @@ -1352,6 +1353,7 @@ public function updateTask(string $taskId, Model\TasksTaskIdPatchBody $requestBo
* @var string $external_reference_id only return time entries with the given external_reference ID
* @var bool $is_billed pass true to only return time entries that have been invoiced and false to return time entries that have not been invoiced
* @var bool $is_running pass true to only return running time entries and false to return non-running time entries
* @var string $approval_status Only return time entries with the given approval status. Possible values: “unsubmitted”, “submitted”, or “approved”.
* @var string $updated_since Only return time entries that have been updated since the given date and time. Use the ISO 8601 Format.
* @var string $from only return time entries with a spent_date on or after the given date
* @var string $to only return time entries with a spent_date on or before the given date
Expand Down
4 changes: 3 additions & 1 deletion generated/Endpoint/ListExpenses.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class ListExpenses extends \JoliCode\Harvest\Api\Runtime\Client\BaseEndpoint imp
* @var int $client_id only return expenses belonging to the client with the given ID
* @var int $project_id only return expenses belonging to the project with the given ID
* @var bool $is_billed pass true to only return expenses that have been invoiced and false to return expenses that have not been invoiced
* @var string $approval_status Only return expenses with the given approval status. Possible values: “unsubmitted”, “submitted”, or “approved”.
* @var string $updated_since only return expenses that have been updated since the given date and time
* @var string $from only return expenses with a spent_date on or after the given date
* @var string $to only return expenses with a spent_date on or before the given date
Expand Down Expand Up @@ -66,14 +67,15 @@ public function getAuthenticationScopes(): array
protected function getQueryOptionsResolver(): \Symfony\Component\OptionsResolver\OptionsResolver
{
$optionsResolver = parent::getQueryOptionsResolver();
$optionsResolver->setDefined(['user_id', 'client_id', 'project_id', 'is_billed', 'updated_since', 'from', 'to', 'page', 'per_page']);
$optionsResolver->setDefined(['user_id', 'client_id', 'project_id', 'is_billed', 'approval_status', 'updated_since', 'from', 'to', 'page', 'per_page']);
$optionsResolver->setRequired([]);
$optionsResolver->setDefaults([]);
$optionsResolver->addAllowedTypes('user_id', ['int']);
$optionsResolver->addAllowedTypes('client_id', ['int']);
$optionsResolver->addAllowedTypes('project_id', ['int']);
$optionsResolver->addAllowedTypes('is_billed', ['bool']);
$optionsResolver->setNormalizer('is_billed', \Closure::fromCallable([new \JoliCode\Harvest\BooleanCustomQueryResolver(), '__invoke']));
$optionsResolver->addAllowedTypes('approval_status', ['string']);
$optionsResolver->addAllowedTypes('updated_since', ['string']);
$optionsResolver->addAllowedTypes('from', ['string']);
$optionsResolver->addAllowedTypes('to', ['string']);
Expand Down
Loading