first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled

This commit is contained in:
2026-03-17 16:22:57 +03:30
commit 3d5eaf9445
15349 changed files with 2847338 additions and 0 deletions
@@ -0,0 +1,273 @@
import type { INodeProperties } from 'n8n-workflow';
const resource = ['client'];
export const clientOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource,
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a client',
action: 'Create a client',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a client',
action: 'Delete a client',
},
{
name: 'Get',
value: 'get',
description: 'Get data of a client',
action: 'Get data of a client',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get data of many clients',
action: 'Get data of all clients',
},
{
name: 'Update',
value: 'update',
description: 'Update a client',
action: 'Update a client',
},
],
default: 'getAll',
},
];
export const clientFields: INodeProperties[] = [
/* -------------------------------------------------------------------------- */
/* client:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource,
operation: ['getAll'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 100,
description: 'Max number of results to return',
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Filter',
default: {},
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
options: [
{
displayName: 'Is Active',
name: 'is_active',
type: 'boolean',
default: true,
description: 'Whether to only return active clients and false to return inactive clients',
},
{
displayName: 'Updated Since',
name: 'updated_since',
type: 'dateTime',
default: '',
description: 'Only return clients that have been updated since the given date and time',
},
],
},
/* -------------------------------------------------------------------------- */
/* client:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Client ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource,
},
},
description: 'The ID of the client you are retrieving',
},
/* -------------------------------------------------------------------------- */
/* client:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'Client ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource,
},
},
description: 'The ID of the client you want to delete',
},
/* -------------------------------------------------------------------------- */
/* client:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'Name',
name: 'name',
type: 'string',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: '',
required: true,
description: 'The name of the client',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: {},
options: [
{
displayName: 'Address',
name: 'address',
type: 'string',
default: '',
description:
'A textual representation of the clients physical address. May include new line characters.',
},
{
displayName: 'Currency',
name: 'currency',
type: 'string',
default: '',
description:
'The currency used by the estimate. If not provided, the clients currency will be used. See a list of supported currencies',
},
{
displayName: 'Is Active',
name: 'is_active',
type: 'string',
default: '',
description: 'Whether the client is active, or archived. Defaults to true.',
},
],
},
/* -------------------------------------------------------------------------- */
/* client:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Client ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
description: 'The ID of the client want to update',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
default: {},
options: [
{
displayName: 'Address',
name: 'address',
type: 'string',
default: '',
description:
'A textual representation of the clients physical address. May include new line characters.',
},
{
displayName: 'Currency',
name: 'currency',
type: 'string',
default: '',
description:
'The currency used by the estimate. If not provided, the clients currency will be used. See a list of supported currencies',
},
{
displayName: 'Is Active',
name: 'is_active',
type: 'boolean',
default: true,
description: 'Whether the client is active, or archived. Defaults to true.',
},
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: 'Whether the client is active, or archived. Defaults to true.',
},
],
},
];
@@ -0,0 +1,26 @@
import type { INodeProperties } from 'n8n-workflow';
const resource = ['company'];
export const companyOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource,
},
},
options: [
{
name: 'Get',
value: 'get',
description: 'Retrieves the company for the currently authenticated user',
action: 'Retrieve the company for the currently authenticated user',
},
],
default: 'get',
},
];
@@ -0,0 +1,334 @@
import type { INodeProperties } from 'n8n-workflow';
const resource = ['contact'];
export const contactOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource,
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a contact',
action: 'Create a contact',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a contact',
action: 'Delete a contact',
},
{
name: 'Get',
value: 'get',
description: 'Get data of a contact',
action: 'Get data of a contact',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get data of many contacts',
action: 'Get data of all contacts',
},
{
name: 'Update',
value: 'update',
description: 'Update a contact',
action: 'Update a contact',
},
],
default: 'getAll',
},
];
export const contactFields: INodeProperties[] = [
/* -------------------------------------------------------------------------- */
/* contact:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource,
operation: ['getAll'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 100,
description: 'Max number of results to return',
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Filter',
default: {},
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
options: [
{
displayName: 'Is Active',
name: 'is_active',
type: 'boolean',
default: true,
description: 'Whether to only return active clients and false to return inactive clients',
},
{
displayName: 'Updated Since',
name: 'updated_since',
type: 'dateTime',
default: '',
description: 'Only return clients that have been updated since the given date and time',
},
],
},
/* -------------------------------------------------------------------------- */
/* contact:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Contact ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource,
},
},
description: 'The ID of the contact you are retrieving',
},
/* -------------------------------------------------------------------------- */
/* contact:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'Contact ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource,
},
},
description: 'The ID of the contact you want to delete',
},
/* -------------------------------------------------------------------------- */
/* contact:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'First Name',
name: 'firstName',
type: 'string',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: '',
required: true,
description: 'The first name of the contact',
},
{
displayName: 'Client ID',
name: 'clientId',
type: 'string',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: '',
required: true,
description: 'The ID of the client associated with this contact',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: {},
options: [
{
displayName: 'Email',
name: 'email',
type: 'string',
placeholder: 'name@email.com',
default: '',
description: 'The contacts email address',
},
{
displayName: 'Fax',
name: 'fax',
type: 'string',
default: '',
description: 'The contacts fax number',
},
{
displayName: 'Last Name',
name: 'last_name',
type: 'string',
default: '',
description: 'The last name of the contact',
},
{
displayName: 'Phone Mobile',
name: 'phone_mobile',
type: 'string',
default: '',
description: 'The contacts mobile phone number',
},
{
displayName: 'Phone Office',
name: 'phone_office',
type: 'string',
default: '',
description: 'The contacts office phone number',
},
{
displayName: 'Title',
name: 'title',
type: 'string',
default: '',
description: 'The title of the contact',
},
],
},
/* -------------------------------------------------------------------------- */
/* contact:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Contact ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
description: 'The ID of the contact want to update',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
default: {},
options: [
{
displayName: 'Client ID',
name: 'client_id',
type: 'string',
default: '',
description: 'The ID of the client associated with this contact',
},
{
displayName: 'Email',
name: 'email',
type: 'string',
placeholder: 'name@email.com',
default: '',
description: 'The contacts email address',
},
{
displayName: 'Fax',
name: 'fax',
type: 'string',
default: '',
description: 'The contacts fax number',
},
{
displayName: 'First Name',
name: 'first_name',
type: 'string',
default: '',
description: 'The first name of the contact',
},
{
displayName: 'Last Name',
name: 'last_name',
type: 'string',
default: '',
description: 'The last name of the contact',
},
{
displayName: 'Phone Mobile',
name: 'phone_mobile',
type: 'string',
default: '',
description: 'The contacts mobile phone number',
},
{
displayName: 'Phone Office',
name: 'phone_office',
type: 'string',
default: '',
description: 'The contacts office phone number',
},
{
displayName: 'Title',
name: 'title',
type: 'string',
default: '',
description: 'The title of the contact',
},
],
},
];
@@ -0,0 +1,394 @@
import type { INodeProperties } from 'n8n-workflow';
const resource = ['estimate'];
export const estimateOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource,
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create an estimate',
action: 'Create an estimate',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete an estimate',
action: 'Delete an estimate',
},
{
name: 'Get',
value: 'get',
description: 'Get data of an estimate',
action: 'Get data of an estimate',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get data of many estimates',
action: 'Get data of all estimates',
},
{
name: 'Update',
value: 'update',
description: 'Update an estimate',
action: 'Update an estimate',
},
],
default: 'getAll',
},
];
export const estimateFields: INodeProperties[] = [
/* -------------------------------------------------------------------------- */
/* estimate:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource,
operation: ['getAll'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 100,
description: 'Max number of results to return',
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Filter',
default: {},
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
options: [
{
displayName: 'Client ID',
name: 'client_id',
type: 'string',
default: '',
description: 'Only return time entries belonging to the client with the given ID',
},
{
displayName: 'From',
name: 'from',
type: 'dateTime',
default: '',
description: 'Only return time entries with a spent_date on or after the given date',
},
{
displayName: 'State',
name: 'state',
type: 'string',
default: '',
description:
'Only return estimates with a state matching the value provided. Options: draft, sent, accepted, or declined.',
},
{
displayName: 'To',
name: 'to',
type: 'dateTime',
default: '',
description: 'Only return time entries with a spent_date on or before the given date',
},
{
displayName: 'Updated Since',
name: 'updated_since',
type: 'dateTime',
default: '',
description:
'Only return time entries that have been updated since the given date and time',
},
{
displayName: 'Page',
name: 'page',
type: 'number',
typeOptions: {
minValue: 1,
},
default: 1,
description:
'The page number to use in pagination. For instance, if you make a list request and receive 100 records, your subsequent call can include page=2 to retrieve the next page of the list. (Default: 1)',
},
],
},
/* -------------------------------------------------------------------------- */
/* estimate:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Estimate ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource,
},
},
description: 'The ID of the estimate you are retrieving',
},
/* -------------------------------------------------------------------------- */
/* estimate:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'Estimate ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource,
},
},
description: 'The ID of the estimate want to delete',
},
/* -------------------------------------------------------------------------- */
/* estimate:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'Client ID',
name: 'clientId',
type: 'string',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: '',
required: true,
description: 'The ID of the client this estimate belongs to',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: {},
options: [
{
displayName: 'Currency',
name: 'currency',
type: 'string',
default: '',
description:
'The currency used by the estimate. If not provided, the clients currency will be used. See a list of supported currencies',
},
{
displayName: 'Discount',
name: 'over_budget_notification_percentage',
type: 'string',
default: '',
description:
'This percentage is subtracted from the subtotal. Example: use 10.0 for 10.0%.',
},
{
displayName: 'Issue Date',
name: 'issue_date',
type: 'dateTime',
default: '',
description: 'Date the invoice was issued. Defaults to todays date.',
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Any additional notes to include on the estimate',
},
{
displayName: 'Number',
name: 'number',
type: 'string',
default: '',
description: 'If no value is set, the number will be automatically generated',
},
{
displayName: 'Purchase Order',
name: 'purchase_order',
type: 'string',
default: '',
description: 'The purchase order number',
},
{
displayName: 'Subject',
name: 'subject',
type: 'string',
default: '',
description: 'The estimate subject',
},
{
displayName: 'Tax',
name: 'tax',
type: 'string',
default: '',
description:
'This percentage is applied to the subtotal, including line items and discounts. Example: use 10.0 for 10.0%.',
},
{
displayName: 'Tax2',
name: 'tax2',
type: 'string',
default: '',
description:
'This percentage is applied to the subtotal, including line items and discounts. Example: use 10.0 for 10.0%.',
},
],
},
/* -------------------------------------------------------------------------- */
/* estimate:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Invoice ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
description: 'The ID of the invoice want to update',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
default: {},
options: [
{
displayName: 'Client ID',
name: 'client_id',
type: 'string',
default: '',
description: 'The ID of the retainer associated with this invoice',
},
{
displayName: 'Currency',
name: 'currency',
type: 'string',
default: '',
description:
'The currency used by the estimate. If not provided, the clients currency will be used. See a list of supported currencies',
},
{
displayName: 'Discount',
name: 'over_budget_notification_percentage',
type: 'string',
default: '',
description:
'This percentage is subtracted from the subtotal. Example: use 10.0 for 10.0%.',
},
{
displayName: 'Issue Date',
name: 'issue_date',
type: 'dateTime',
default: '',
description: 'Date the invoice was issued. Defaults to todays date.',
},
{
displayName: 'Number',
name: 'number',
type: 'string',
default: '',
description: 'If no value is set, the number will be automatically generated',
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Any additional notes to include on the estimate',
},
{
displayName: 'Purchase Order',
name: 'purchase_order',
type: 'string',
default: '',
description: 'The purchase order number',
},
{
displayName: 'Subject',
name: 'subject',
type: 'string',
default: '',
description: 'The estimate subject',
},
{
displayName: 'Tax',
name: 'tax',
type: 'string',
default: '',
description:
'This percentage is applied to the subtotal, including line items and discounts. Example: use 10.0 for 10.0%.',
},
{
displayName: 'Tax2',
name: 'tax2',
type: 'string',
default: '',
description:
'This percentage is applied to the subtotal, including line items and discounts. Example: use 10.0 for 10.0%.',
},
],
},
];
@@ -0,0 +1,390 @@
import type { INodeProperties } from 'n8n-workflow';
const resource = ['expense'];
export const expenseOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource,
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create an expense',
action: 'Create an expense',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete an expense',
action: 'Delete an expense',
},
{
name: 'Get',
value: 'get',
description: 'Get data of an expense',
action: 'Get data of an expense',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get data of many expenses',
action: 'Get data of all expenses',
},
{
name: 'Update',
value: 'update',
description: 'Update an expense',
action: 'Update an expense',
},
],
default: 'getAll',
},
];
export const expenseFields: INodeProperties[] = [
/* -------------------------------------------------------------------------- */
/* expense:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource,
operation: ['getAll'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 100,
description: 'Max number of results to return',
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Filter',
default: {},
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
options: [
{
displayName: 'Client ID',
name: 'client_id',
type: 'string',
default: '',
description: 'Only return time entries belonging to the client with the given ID',
},
{
displayName: 'From',
name: 'from',
type: 'dateTime',
default: '',
description: 'Only return time entries with a spent_date on or after the given date',
},
{
displayName: 'Is Billed',
name: 'is_billed',
type: 'boolean',
default: false,
description:
'Whether to only return time entries that have been invoiced and false to return time entries that have not been invoiced',
},
{
displayName: 'Page',
name: 'page',
type: 'number',
typeOptions: {
minValue: 1,
},
default: 1,
description:
'The page number to use in pagination. For instance, if you make a list request and receive 100 records, your subsequent call can include page=2 to retrieve the next page of the list. (Default: 1)',
},
{
displayName: 'Project ID',
name: 'project_id',
type: 'string',
default: '',
description: 'Only return time entries belonging to the client with the given ID',
},
{
displayName: 'To',
name: 'to',
type: 'dateTime',
default: '',
description: 'Only return time entries with a spent_date on or before the given date',
},
{
displayName: 'Updated Since',
name: 'updated_since',
type: 'dateTime',
default: '',
description:
'Only return time entries that have been updated since the given date and time',
},
{
displayName: 'User ID',
name: 'user_id',
type: 'string',
default: '',
description: 'Only return time entries belonging to the user with the given ID',
},
],
},
/* -------------------------------------------------------------------------- */
/* expense:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Expense ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource,
},
},
description: 'The ID of the expense you are retrieving',
},
/* -------------------------------------------------------------------------- */
/* expense:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'Expense ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource,
},
},
description: 'The ID of the expense you want to delete',
},
/* -------------------------------------------------------------------------- */
/* expense:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'Project ID',
name: 'projectId',
type: 'string',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: '',
required: true,
description: 'The ID of the project associated with this expense',
},
{
displayName: 'Expense Category ID',
name: 'expenseCategoryId',
type: 'string',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: '',
required: true,
description: 'The ID of the expense category this expense is being tracked against',
},
{
displayName: 'Spent Date',
name: 'spentDate',
type: 'dateTime',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: '',
required: true,
description: 'Date the expense occurred',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: {},
options: [
{
displayName: 'Billable',
name: 'billable',
type: 'boolean',
default: true,
description: 'Whether this expense is billable or not. Defaults to true.',
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Notes about the expense',
},
{
displayName: 'Total Cost',
name: 'total_cost',
type: 'string',
default: '',
description: 'The total amount of the expense',
},
{
displayName: 'Units',
name: 'units',
type: 'string',
default: '',
description: 'The quantity of units to use in calculating the total_cost of the expense',
},
{
displayName: 'User ID',
name: 'user_id',
type: 'boolean',
default: true,
// eslint-disable-next-line n8n-nodes-base/node-param-description-boolean-without-whether
description:
'The ID of the user associated with this expense. Defaults to the ID of the currently authenticated user.',
},
],
},
/* -------------------------------------------------------------------------- */
/* invoice:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Invoice ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
description: 'The ID of the invoice want to update',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
default: {},
options: [
{
displayName: 'Billable',
name: 'billable',
type: 'boolean',
default: true,
description: 'Whether this expense is billable or not. Defaults to true.',
},
{
displayName: 'Expense Category ID',
name: 'expense_category_id',
type: 'string',
default: '',
description: 'The ID of the expense category this expense is being tracked against',
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Notes about the expense',
},
{
displayName: 'Project ID',
name: 'project_id',
type: 'string',
default: '',
description: 'The ID of the project associated with this expense',
},
{
displayName: 'Spent Date',
name: 'spent_date',
type: 'dateTime',
default: '',
description: 'Date the expense occurred',
},
{
displayName: 'Total Cost',
name: 'total_cost',
type: 'string',
default: '',
description: 'The total amount of the expense',
},
{
displayName: 'Units',
name: 'units',
type: 'string',
default: '',
description: 'The quantity of units to use in calculating the total_cost of the expense',
},
{
displayName: 'User ID',
name: 'user_id',
type: 'boolean',
default: true,
// eslint-disable-next-line n8n-nodes-base/node-param-description-boolean-without-whether
description:
'The ID of the user associated with this expense. Defaults to the ID of the currently authenticated user.',
},
],
},
];
@@ -0,0 +1,116 @@
import type {
IDataObject,
IExecuteFunctions,
IHookFunctions,
ILoadOptionsFunctions,
JsonObject,
IRequestOptions,
IHttpRequestMethods,
} from 'n8n-workflow';
import { NodeApiError } from 'n8n-workflow';
export async function harvestApiRequest(
this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions,
method: IHttpRequestMethods,
qs: IDataObject,
path: string,
body: IDataObject = {},
option: IDataObject = {},
uri?: string,
): Promise<any> {
let options: IRequestOptions = {
headers: {
'Harvest-Account-Id': `${this.getNodeParameter('accountId', 0)}`,
'User-Agent': 'Harvest App',
Authorization: '',
},
method,
body,
uri: uri || `https://api.harvestapp.com/v2/${path}`,
qs,
json: true,
};
options = Object.assign({}, options, option);
if (Object.keys(options.body as IDataObject).length === 0) {
delete options.body;
}
const authenticationMethod = this.getNodeParameter('authentication', 0);
try {
if (authenticationMethod === 'accessToken') {
const credentials = await this.getCredentials('harvestApi');
//@ts-ignore
options.headers.Authorization = `Bearer ${credentials.accessToken}`;
return await this.helpers.request(options);
} else {
return await this.helpers.requestOAuth2.call(this, 'harvestOAuth2Api', options);
}
} catch (error) {
throw new NodeApiError(this.getNode(), error as JsonObject);
}
}
/**
* Make an API request to paginated flow endpoint
* and return all results
*/
export async function harvestApiRequestAllItems(
this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions,
method: IHttpRequestMethods,
qs: IDataObject,
uri: string,
resource: string,
body: IDataObject = {},
option: IDataObject = {},
): Promise<any> {
const returnData: IDataObject[] = [];
let responseData;
do {
responseData = await harvestApiRequest.call(this, method, qs, uri, body, option);
qs.page = responseData.next_page;
returnData.push.apply(returnData, responseData[resource] as IDataObject[]);
} while (responseData.next_page);
return returnData;
}
/**
* fetch All resource using paginated calls
*/
export async function getAllResource(
this: IExecuteFunctions | ILoadOptionsFunctions,
resource: string,
i: number,
) {
const endpoint = resource;
const qs: IDataObject = {};
const requestMethod = 'GET';
qs.per_page = 100;
const additionalFields = this.getNodeParameter('filters', i);
const returnAll = this.getNodeParameter('returnAll', i);
Object.assign(qs, additionalFields);
let responseData: IDataObject = {};
if (returnAll) {
responseData[resource] = await harvestApiRequestAllItems.call(
this,
requestMethod,
qs,
endpoint,
resource,
);
} else {
const limit = this.getNodeParameter('limit', i);
qs.per_page = limit;
responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint);
}
return responseData[resource] as IDataObject[];
}
@@ -0,0 +1,25 @@
{
"node": "n8n-nodes-base.harvest",
"nodeVersion": "1.0",
"codexVersion": "1.0",
"categories": ["Productivity"],
"resources": {
"credentialDocumentation": [
{
"url": "https://docs.n8n.io/integrations/builtin/credentials/harvest/"
}
],
"primaryDocumentation": [
{
"url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.harvest/"
}
],
"generic": [
{
"label": "6 e-commerce workflows to power up your Shopify s",
"icon": "store",
"url": "https://n8n.io/blog/no-code-ecommerce-workflow-automations/"
}
]
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,482 @@
import type { INodeProperties } from 'n8n-workflow';
const resource = ['invoice'];
export const invoiceOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource,
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create an invoice',
action: 'Create an invoice',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete an invoice',
action: 'Delete an invoice',
},
{
name: 'Get',
value: 'get',
description: 'Get data of an invoice',
action: 'Get data of an invoice',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get data of many invoices',
action: 'Get data of all invoices',
},
{
name: 'Update',
value: 'update',
description: 'Update an invoice',
action: 'Update an invoice',
},
],
default: 'getAll',
},
];
export const invoiceFields: INodeProperties[] = [
/* -------------------------------------------------------------------------- */
/* invoice:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource,
operation: ['getAll'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 100,
description: 'Max number of results to return',
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Filter',
default: {},
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
options: [
{
displayName: 'Client ID',
name: 'client_id',
type: 'string',
default: '',
description: 'Only return time entries belonging to the client with the given ID',
},
{
displayName: 'From',
name: 'from',
type: 'dateTime',
default: '',
description: 'Only return time entries with a spent_date on or after the given date',
},
{
displayName: 'Page',
name: 'page',
type: 'number',
typeOptions: {
minValue: 1,
},
default: 1,
description:
'The page number to use in pagination. For instance, if you make a list request and receive 100 records, your subsequent call can include page=2 to retrieve the next page of the list. (Default: 1)',
},
{
displayName: 'Project ID',
name: 'project_id',
type: 'string',
default: '',
description: 'Only return time entries belonging to the client with the given ID',
},
{
displayName: 'State',
name: 'state',
type: 'multiOptions',
options: [
{
name: 'Draft',
value: 'draft',
},
{
name: 'Open',
value: 'open',
},
{
name: 'Paid',
value: 'paid',
},
{
name: 'Closed',
value: 'closed',
},
],
default: [],
description:
'Only return invoices with a state matching the value provided. Options: draft, open, paid, or closed.',
},
{
displayName: 'To',
name: 'to',
type: 'dateTime',
default: '',
description: 'Only return time entries with a spent_date on or before the given date',
},
{
displayName: 'Updated Since',
name: 'updated_since',
type: 'dateTime',
default: '',
description:
'Only return time entries that have been updated since the given date and time',
},
],
},
/* -------------------------------------------------------------------------- */
/* invoice:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Invoice ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource,
},
},
description: 'The ID of the invoice you are retrieving',
},
/* -------------------------------------------------------------------------- */
/* invoice:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'Invoice ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource,
},
},
description: 'The ID of the invoice want to delete',
},
/* -------------------------------------------------------------------------- */
/* invoice:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'Client ID',
name: 'clientId',
type: 'string',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: '',
required: true,
description: 'The ID of the retainer associated with this invoice',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: {},
options: [
{
displayName: 'Currency',
name: 'currency',
type: 'string',
default: '',
description:
'The currency used by the invoice. If not provided, the clients currency will be used. See a list of supported currencies',
},
{
displayName: 'Discount',
name: 'over_budget_notification_percentage',
type: 'string',
default: '',
description:
'This percentage is subtracted from the subtotal. Example: use 10.0 for 10.0%.',
},
{
displayName: 'Due Date',
name: 'ends_on',
type: 'dateTime',
default: '',
description:
'Date the invoice is due. Defaults to the issue_date if no payment_term is specified.',
},
{
displayName: 'Estimate ID',
name: 'estimate_id',
type: 'string',
default: '',
description: 'The ID of the estimate associated with this invoice',
},
{
displayName: 'Issue Date',
name: 'issue_date',
type: 'dateTime',
default: '',
description: 'Date the invoice was issued. Defaults to todays date.',
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Notes about the project',
},
{
displayName: 'Number',
name: 'number',
type: 'string',
default: '',
description: 'If no value is set, the number will be automatically generated',
},
{
displayName: 'Payment Term',
name: 'payment_term',
type: 'string',
default: '',
description:
'The timeframe in which the invoice should be paid. Defaults to custom. Options: upon receipt, net 15, net 30, net 45, or net 60.',
},
{
displayName: 'Purchase Order',
name: 'purchase_order',
type: 'string',
default: '',
description: 'The purchase order number',
},
{
displayName: 'Retainer ID',
name: 'retainer_id',
type: 'boolean',
default: true,
// eslint-disable-next-line n8n-nodes-base/node-param-description-boolean-without-whether
description: 'The ID of the retainer associated with this invoice',
},
{
displayName: 'Subject',
name: 'subject',
type: 'string',
default: '',
description: 'The invoice subject',
},
{
displayName: 'Tax',
name: 'tax',
type: 'string',
default: '',
description:
'This percentage is applied to the subtotal, including line items and discounts. Example: use 10.0 for 10.0%.',
},
{
displayName: 'Tax2',
name: 'tax2',
type: 'string',
default: '',
description:
'This percentage is applied to the subtotal, including line items and discounts. Example: use 10.0 for 10.0%.',
},
],
},
/* -------------------------------------------------------------------------- */
/* invoice:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Invoice ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
description: 'The ID of the invoice want to update',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
default: {},
options: [
{
displayName: 'Client ID',
name: 'client_id',
type: 'string',
default: '',
description: 'The ID of the retainer associated with this invoice',
},
{
displayName: 'Currency',
name: 'currency',
type: 'string',
default: '',
description:
'The currency used by the invoice. If not provided, the clients currency will be used. See a list of supported currencies',
},
{
displayName: 'Discount',
name: 'over_budget_notification_percentage',
type: 'string',
default: '',
description:
'This percentage is subtracted from the subtotal. Example: use 10.0 for 10.0%.',
},
{
displayName: 'Due Date',
name: 'ends_on',
type: 'dateTime',
default: '',
description:
'Date the invoice is due. Defaults to the issue_date if no payment_term is specified.',
},
{
displayName: 'Estimate ID',
name: 'estimate_id',
type: 'string',
default: '',
description: 'The ID of the estimate associated with this invoice',
},
{
displayName: 'Issue Date',
name: 'issue_date',
type: 'dateTime',
default: '',
description: 'Date the invoice was issued. Defaults to todays date.',
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Notes about the project',
},
{
displayName: 'Number',
name: 'number',
type: 'string',
default: '',
description: 'If no value is set, the number will be automatically generated',
},
{
displayName: 'Payment Term',
name: 'payment_term',
type: 'string',
default: '',
description:
'The timeframe in which the invoice should be paid. Defaults to custom. Options: upon receipt, net 15, net 30, net 45, or net 60.',
},
{
displayName: 'Purchase Order',
name: 'purchase_order',
type: 'string',
default: '',
description: 'The purchase order number',
},
{
displayName: 'Retainer ID',
name: 'retainer_id',
type: 'boolean',
default: true,
// eslint-disable-next-line n8n-nodes-base/node-param-description-boolean-without-whether
description: 'The ID of the retainer associated with this invoice',
},
{
displayName: 'Subject',
name: 'subject',
type: 'string',
default: '',
description: 'The invoice subject',
},
{
displayName: 'Tax',
name: 'tax',
type: 'string',
default: '',
description:
'This percentage is applied to the subtotal, including line items and discounts. Example: use 10.0 for 10.0%.',
},
{
displayName: 'Tax2',
name: 'tax2',
type: 'string',
default: '',
description:
'This percentage is applied to the subtotal, including line items and discounts. Example: use 10.0 for 10.0%.',
},
],
},
];
@@ -0,0 +1,575 @@
import type { INodeProperties } from 'n8n-workflow';
const resource = ['project'];
export const projectOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource,
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a project',
action: 'Create a project',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a project',
action: 'Delete a project',
},
{
name: 'Get',
value: 'get',
description: 'Get data of a project',
action: 'Get data of a project',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get data of many projects',
action: 'Get data of all projects',
},
{
name: 'Update',
value: 'update',
description: 'Update a project',
action: 'Update a project',
},
],
default: 'getAll',
},
];
export const projectFields: INodeProperties[] = [
/* -------------------------------------------------------------------------- */
/* projects:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource,
operation: ['getAll'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 100,
description: 'Max number of results to return',
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Filter',
default: {},
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
options: [
{
displayName: 'Client ID',
name: 'client_id',
type: 'string',
default: '',
description: 'Only return projects belonging to the client with the given ID',
},
{
displayName: 'Is Active',
name: 'is_active',
type: 'boolean',
default: true,
description: 'Whether to only return active projects and false to return inactive projects',
},
{
displayName: 'Page',
name: 'page',
type: 'number',
typeOptions: {
minValue: 1,
},
default: 1,
description: 'The page number to use in pagination',
},
{
displayName: 'Updated Since',
name: 'updated_since',
type: 'dateTime',
default: '',
description: 'Only return projects by updated_since',
},
],
},
/* -------------------------------------------------------------------------- */
/* project:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Project ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource,
},
},
description: 'The ID of the project you are retrieving',
},
/* -------------------------------------------------------------------------- */
/* project:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'Project ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource,
},
},
description: 'The ID of the project want to delete',
},
/* -------------------------------------------------------------------------- */
/* project:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'Name',
name: 'name',
type: 'string',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: '',
required: true,
description: 'The name of the project',
},
{
displayName: 'Client ID',
name: 'clientId',
type: 'string',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: '',
required: true,
description: 'The ID of the client to associate this project with',
},
{
displayName: 'Is Billable',
name: 'isBillable',
type: 'boolean',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: true,
required: true,
description: 'Whether the project is billable or not',
},
{
displayName: 'Bill By',
name: 'billBy',
type: 'options',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
options: [
{
name: 'None',
value: 'none',
},
{
name: 'People',
value: 'People',
},
{
name: 'Project',
value: 'Project',
},
{
name: 'Tasks',
value: 'Tasks',
},
],
default: 'none',
required: true,
description: 'The method by which the project is invoiced',
},
{
displayName: 'Budget By',
name: 'budgetBy',
type: 'string',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: 'none',
placeholder: '',
required: true,
description: 'The email of the user or "none"',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: {},
options: [
{
displayName: 'Budget',
name: 'budget',
type: 'number',
typeOptions: {
minValue: 0,
},
default: 0,
description: 'The budget in hours for the project when budgeting by time',
},
{
displayName: 'Budget Is Monthly',
name: 'budget_is_monthly',
type: 'boolean',
default: false,
description: 'Whether the budget resets every month. Defaults to false.',
},
{
displayName: 'Cost Budget',
name: 'cost_budget',
type: 'string',
default: '',
description: 'The monetary budget for the project when budgeting by money',
},
{
displayName: 'Cost Budget Include Expenses',
name: 'cost_budget_include_expenses',
type: 'boolean',
default: false,
// eslint-disable-next-line n8n-nodes-base/node-param-description-boolean-without-whether
description:
'Option for budget of Total Project Fees projects to include tracked expenses. Defaults to false.',
},
{
displayName: 'Ends On',
name: 'ends_on',
type: 'dateTime',
default: '',
description: 'Date the project will end',
},
{
displayName: 'Fee',
name: 'fee',
type: 'string',
default: '',
description:
'The amount you plan to invoice for the project. Only used by fixed-fee projects.',
},
{
displayName: 'Hourly Rate',
name: 'hourly_rate',
type: 'string',
default: '',
description: 'Rate for projects billed by Project Hourly Rate',
},
{
displayName: 'Is Active',
name: 'is_active',
type: 'boolean',
default: true,
description: 'Whether the project is active or archived. Defaults to true.',
},
{
displayName: 'Is Fixed Fee',
name: 'is_fixed_fee',
type: 'boolean',
default: false,
description: 'Whether the project is a fixed-fee project or not',
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Notes about the project',
},
{
displayName: 'Notify When Over Budget',
name: 'notify_when_over_budget',
type: 'boolean',
default: false,
description:
'Whether project managers should be notified when the project goes over budget. Defaults to false.',
},
{
displayName: 'Over Budget Notification Percentage',
name: 'over_budget_notification_percentage',
type: 'string',
default: '',
description:
'Percentage value used to trigger over budget email alerts. Example: use 10.0 for 10.0%.',
},
{
displayName: 'Show Budget To All',
name: 'show_budget_to_all',
type: 'boolean',
default: false,
description:
'Whether to show project budget to all employees. Does not apply to Total Project Fee projects. Defaults to false.',
},
{
displayName: 'Starts On',
name: 'starts_on',
type: 'dateTime',
default: '',
description: 'Date the project was started',
},
],
},
/* -------------------------------------------------------------------------- */
/* project:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Project ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
description: 'The ID of the project want to update',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
default: {},
options: [
{
displayName: 'Bill By',
name: 'bill_by',
type: 'options',
options: [
{
name: 'None',
value: 'none',
},
{
name: 'People',
value: 'People',
},
{
name: 'Project',
value: 'Project',
},
{
name: 'Tasks',
value: 'Tasks',
},
],
default: 'none',
description: 'The method by which the project is invoiced',
},
{
displayName: 'Budget',
name: 'budget',
type: 'string',
default: '',
description: 'The budget in hours for the project when budgeting by time',
},
{
displayName: 'Budget By',
name: 'budget_by',
type: 'string',
default: '',
description: 'The email of the user or "none"',
},
{
displayName: 'Budget Is Monthly',
name: 'budget_is_monthly',
type: 'boolean',
default: false,
description: 'Whether to have the budget reset every month. Defaults to false.',
},
{
displayName: 'Client ID',
name: 'client_id',
type: 'string',
default: '',
description: 'The ID of the client to associate this project with',
},
{
displayName: 'Cost Budget',
name: 'cost_budget',
type: 'string',
default: '',
description: 'The monetary budget for the project when budgeting by money',
},
{
displayName: 'Cost Budget Include Expenses',
name: 'cost_budget_include_expenses',
type: 'boolean',
default: false,
// eslint-disable-next-line n8n-nodes-base/node-param-description-boolean-without-whether
description:
'Option for budget of Total Project Fees projects to include tracked expenses. Defaults to false.',
},
{
displayName: 'Ends On',
name: 'ends_on',
type: 'dateTime',
default: '',
description: 'Date the project will end',
},
{
displayName: 'Fee',
name: 'fee',
type: 'string',
default: '',
description:
'The amount you plan to invoice for the project. Only used by fixed-fee projects.',
},
{
displayName: 'Hourly Rate',
name: 'hourly_rate',
type: 'string',
default: '',
description: 'Rate for projects billed by Project Hourly Rate',
},
{
displayName: 'Is Active',
name: 'is_active',
type: 'boolean',
default: true,
description: 'Whether the project is active or archived. Defaults to true.',
},
{
displayName: 'Is Billable',
name: 'is_billable',
type: 'boolean',
default: true,
description: 'Whether the project is billable or not',
},
{
displayName: 'Is Fixed Fee',
name: 'is_fixed_fee',
type: 'boolean',
default: false,
description: 'Whether the project is a fixed-fee project or not',
},
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: 'The name of the project',
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Notes about the project',
},
{
displayName: 'Notify When Over Budget',
name: 'notify_when_over_budget',
type: 'boolean',
default: false,
description:
'Whether project managers should be notified when the project goes over budget. Defaults to false.',
},
{
displayName: 'Over Budget Notification Percentage',
name: 'over_budget_notification_percentage',
type: 'string',
default: '',
description:
'Percentage value used to trigger over budget email alerts. Example: use 10.0 for 10.0%.',
},
{
displayName: 'Show Budget To All',
name: 'show_budget_to_all',
type: 'boolean',
default: false,
description:
'Whether to show project budget to all employees. Does not apply to Total Project Fee projects. Defaults to false.',
},
{
displayName: 'Starts On',
name: 'starts_on',
type: 'dateTime',
default: '',
description: 'Date the project was started',
},
],
},
];
@@ -0,0 +1,297 @@
import type { INodeProperties } from 'n8n-workflow';
const resource = ['task'];
export const taskOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource,
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a task',
action: 'Create a task',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a task',
action: 'Delete a task',
},
{
name: 'Get',
value: 'get',
description: 'Get data of a task',
action: 'Get data of a task',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get data of many tasks',
action: 'Get data of all tasks',
},
{
name: 'Update',
value: 'update',
description: 'Update a task',
action: 'Update a task',
},
],
default: 'getAll',
},
];
export const taskFields: INodeProperties[] = [
/* -------------------------------------------------------------------------- */
/* task:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource,
operation: ['getAll'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 100,
description: 'Max number of results to return',
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Filter',
default: {},
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
options: [
{
displayName: 'Is Active',
name: 'is_active',
type: 'boolean',
default: true,
description: 'Whether to only return active tasks and false to return inactive tasks',
},
{
displayName: 'Page',
name: 'page',
type: 'number',
typeOptions: {
minValue: 1,
},
default: 1,
description: 'The page number to use in pagination',
},
{
displayName: 'Updated Since',
name: 'updated_since',
type: 'dateTime',
default: '',
description: 'Only return tasks belonging to the task with the given ID',
},
],
},
/* -------------------------------------------------------------------------- */
/* task:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Task ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource,
},
},
description: 'The ID of the task you are retrieving',
},
/* -------------------------------------------------------------------------- */
/* task:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'Task ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource,
},
},
description: 'The ID of the task you want to delete',
},
/* -------------------------------------------------------------------------- */
/* task:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'Name',
name: 'name',
type: 'string',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: '',
required: true,
description: 'The name of the task',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: {},
options: [
{
displayName: 'Billable By Default',
name: 'billable_by_default',
type: 'boolean',
default: true,
description:
'Whether default tasks should be marked billable when creating a new project. Defaults to true.',
},
{
displayName: 'Default Hourly Rate',
name: 'default_hourly_rate',
type: 'number',
default: 0,
description:
'The default hourly rate to use for this task when it is added to a project. Defaults to 0.',
},
{
displayName: 'Is Active',
name: 'is_active',
type: 'boolean',
default: true,
description: 'Whether this task is active or archived. Defaults to true.',
},
{
displayName: 'Is Default',
name: 'is_default',
type: 'boolean',
default: false,
description:
'Whether this task should be automatically added to future projects. Defaults to false.',
},
],
},
/* -------------------------------------------------------------------------- */
/* task:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Task ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
description: 'The ID of the task you want to update',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Update Field',
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
default: {},
options: [
{
displayName: 'Billable By Default',
name: 'billable_by_default',
type: 'boolean',
default: false,
description:
'Whether default tasks should be marked billable when creating a new project. Defaults to true.',
},
{
displayName: 'Default Hourly Rate',
name: 'default_hourly_rate',
type: 'number',
default: 0,
description:
'The default hourly rate to use for this task when it is added to a project. Defaults to 0.',
},
{
displayName: 'Is Active',
name: 'is_active',
type: 'boolean',
default: true,
description: 'Whether this task is active or archived. Defaults to true.',
},
{
displayName: 'Is Default',
name: 'is_default',
type: 'boolean',
default: false,
description:
'Whether this task should be automatically added to future projects. Defaults to false.',
},
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: 'Name of the task',
},
],
},
];
@@ -0,0 +1,526 @@
import type { INodeProperties } from 'n8n-workflow';
export const resource = ['timeEntry'];
export const timeEntryOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource,
},
},
options: [
{
name: 'Create via Duration',
value: 'createByDuration',
description: 'Create a time entry via duration',
action: 'Create a time entry via duration',
},
{
name: 'Create via Start and End Time',
value: 'createByStartEnd',
description: 'Create a time entry via start and end time',
action: 'Create a time entry via start and end time',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a time entry',
action: 'Delete a time entry',
},
{
name: 'Delete External Reference',
value: 'deleteExternal',
description: 'Delete a time entrys external reference',
action: 'Delete a time entrys external reference',
},
{
name: 'Get',
value: 'get',
description: 'Get data of a time entry',
action: 'Get data of a time entry',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get data of many time entries',
action: 'Get data of all time entries',
},
{
name: 'Restart',
value: 'restartTime',
description: 'Restart a time entry',
action: 'Restart a time entry',
},
{
name: 'Stop',
value: 'stopTime',
description: 'Stop a time entry',
action: 'Stop a time entry',
},
{
name: 'Update',
value: 'update',
description: 'Update a time entry',
action: 'Update a time entry',
},
],
default: 'getAll',
},
];
export const timeEntryFields: INodeProperties[] = [
/* -------------------------------------------------------------------------- */
/* timeEntry:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource,
operation: ['getAll'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 100,
description: 'Max number of results to return',
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Filter',
default: {},
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
options: [
{
displayName: 'Client ID',
name: 'client_id',
type: 'string',
default: '',
description: 'Only return time entries belonging to the client with the given ID',
},
{
displayName: 'From',
name: 'from',
type: 'dateTime',
default: '',
description: 'Only return time entries with a spent_date on or after the given date',
},
{
displayName: 'Is Billed',
name: 'is_billed',
type: 'boolean',
default: true,
description:
'Whether to only return time entries that have been invoiced and false to return time entries that have not been invoiced',
},
{
displayName: 'Is Running',
name: 'is_running',
type: 'boolean',
default: true,
description:
'Whether to only return running time entries and false to return non-running time entries',
},
{
displayName: 'Page',
name: 'page',
type: 'number',
typeOptions: {
minValue: 1,
},
default: 1,
description:
'The page number to use in pagination. For instance, if you make a list request and receive 100 records, your subsequent call can include page=2 to retrieve the next page of the list. (Default: 1)',
},
{
displayName: 'To',
name: 'to',
type: 'dateTime',
default: '',
description: 'Only return time entries with a spent_date on or before the given date',
},
{
displayName: 'Updated Since',
name: 'updated_since',
type: 'dateTime',
default: '',
description:
'Only return time entries that have been updated since the given date and time',
},
{
displayName: 'User ID',
name: 'user_id',
type: 'string',
default: '',
description: 'Only return time entries belonging to the user with the given ID',
},
],
},
/* -------------------------------------------------------------------------- */
/* timeEntry:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Time Entry ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource,
},
},
description: 'The ID of the time entry you are retrieving',
},
/* -------------------------------------------------------------------------- */
/* timeEntry:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'Time Entry ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource,
},
},
description: 'The ID of the time entry you are deleting',
},
/* -------------------------------------------------------------------------- */
/* timeEntry:deleteExternal */
/* -------------------------------------------------------------------------- */
{
displayName: 'Time Entry ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['deleteExternal'],
resource,
},
},
description: 'The ID of the time entry whose external reference you are deleting',
},
/* -------------------------------------------------------------------------- */
/* timeEntry:stopTime */
/* -------------------------------------------------------------------------- */
{
displayName: 'Time Entry ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['stopTime'],
resource,
},
},
description:
'Stop a running time entry. Stopping a time entry is only possible if its currently running.',
},
/* -------------------------------------------------------------------------- */
/* timeEntry:restartTime */
/* -------------------------------------------------------------------------- */
{
displayName: 'Time Entry ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['restartTime'],
resource,
},
},
description:
'Restart a stopped time entry. Restarting a time entry is only possible if it isnt currently running.',
},
/* -------------------------------------------------------------------------- */
/* timeEntry:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Time Entry ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
description: 'The ID of the time entry to update',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
default: {},
options: [
{
displayName: 'Ended Time',
name: 'ended_time',
type: 'string',
default: '',
placeholder: '3:00pm',
description: 'The time the entry ended',
},
{
displayName: 'Hours',
name: 'hours',
type: 'number',
typeOptions: {
minValue: 0,
},
default: 0,
description: 'The current amount of time tracked',
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'These are notes about the time entry',
},
{
displayName: 'Started Time',
name: 'started_time',
type: 'string',
default: '',
placeholder: '3:00pm',
description: 'The time the entry started. Defaults to the current time. Example: “8:00am”.',
},
],
},
/* -------------------------------------------------------------------------- */
/* timeEntry:createByDuration */
/* -------------------------------------------------------------------------- */
{
displayName: 'Project ID',
name: 'projectId',
type: 'string',
displayOptions: {
show: {
operation: ['createByDuration'],
resource,
},
},
default: '',
required: true,
description: 'The ID of the project to associate with the time entry',
},
{
displayName: 'Task ID',
name: 'taskId',
type: 'string',
displayOptions: {
show: {
operation: ['createByDuration'],
resource,
},
},
default: '',
required: true,
description: 'The ID of the task to associate with the time entry',
},
{
displayName: 'Spent Date',
name: 'spentDate',
type: 'dateTime',
displayOptions: {
show: {
operation: ['createByDuration'],
resource,
},
},
default: '',
required: true,
description: 'The ISO 8601 formatted date the time entry was spent',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['createByDuration'],
resource,
},
},
default: {},
options: [
{
displayName: 'Hours',
name: 'hours',
type: 'number',
typeOptions: {
minValue: 0,
},
default: 0,
description: 'The current amount of time tracked',
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'These are notes about the time entry',
},
{
displayName: 'User ID',
name: 'user_id',
type: 'string',
default: '',
description:
'The ID of the user to associate with the time entry. Defaults to the currently authenticated users ID.',
},
],
},
/* -------------------------------------------------------------------------- */
/* timeEntry:createByStartEnd */
/* -------------------------------------------------------------------------- */
{
displayName: 'Project ID',
name: 'projectId',
type: 'string',
displayOptions: {
show: {
operation: ['createByStartEnd'],
resource,
},
},
default: '',
required: true,
description: 'The ID of the project to associate with the time entry',
},
{
displayName: 'Task ID',
name: 'taskId',
type: 'string',
displayOptions: {
show: {
operation: ['createByStartEnd'],
resource,
},
},
default: '',
required: true,
description: 'The ID of the task to associate with the time entry',
},
{
displayName: 'Spent Date',
name: 'spentDate',
type: 'dateTime',
displayOptions: {
show: {
operation: ['createByStartEnd'],
resource,
},
},
default: '',
required: true,
description: 'The ISO 8601 formatted date the time entry was spent',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['createByStartEnd'],
resource,
},
},
default: {},
options: [
{
displayName: 'Ended Time',
name: 'ended_time',
type: 'string',
default: '',
placeholder: '3:00pm',
description: 'The time the entry ended',
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'These are notes about the time entry',
},
{
displayName: 'Started Time',
name: 'started_time',
type: 'string',
default: '',
placeholder: '8:00am',
description: 'The time the entry started. Defaults to the current time. Example: “8:00am”.',
},
{
displayName: 'User ID',
name: 'user_id',
type: 'string',
default: '',
description:
'The ID of the user to associate with the time entry. Defaults to the currently authenticated users ID.',
},
],
},
];
@@ -0,0 +1,491 @@
import type { INodeProperties } from 'n8n-workflow';
const resource = ['user'];
export const userOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource,
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a user',
action: 'Create a user',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a user',
action: 'Delete a user',
},
{
name: 'Get',
value: 'get',
description: 'Get data of a user',
action: 'Get data of a user',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get data of many users',
action: 'Get data of all users',
},
{
name: 'Me',
value: 'me',
description: 'Get data of authenticated user',
action: 'Get data of authenticated user',
},
{
name: 'Update',
value: 'update',
description: 'Update a user',
action: 'Update a user',
},
],
default: 'me',
},
];
export const userFields: INodeProperties[] = [
/* -------------------------------------------------------------------------- */
/* user:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource,
operation: ['getAll'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 100,
description: 'Max number of results to return',
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Filter',
default: {},
displayOptions: {
show: {
resource,
operation: ['getAll'],
},
},
options: [
{
displayName: 'Is Active',
name: 'is_active',
type: 'boolean',
default: true,
description: 'Whether to only return active users and false to return inactive users',
},
{
displayName: 'Updated Since',
name: 'updated_since',
type: 'dateTime',
default: '',
description: 'Only return users belonging to the user with the given ID',
},
{
displayName: 'Page',
name: 'page',
type: 'number',
typeOptions: {
minValue: 1,
},
default: 1,
description: 'The page number to use in pagination',
},
],
},
/* -------------------------------------------------------------------------- */
/* user:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'User ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource,
},
},
description: 'The ID of the user you are retrieving',
},
/* -------------------------------------------------------------------------- */
/* user:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'User ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource,
},
},
description: 'The ID of the user you want to delete',
},
/* -------------------------------------------------------------------------- */
/* user:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'First Name',
name: 'firstName',
type: 'string',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: '',
required: true,
description: 'The first name of the user',
},
{
displayName: 'Last Name',
name: 'lastName',
type: 'string',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: '',
required: true,
description: 'The last name of the user',
},
{
displayName: 'Email',
name: 'email',
type: 'string',
placeholder: 'name@email.com',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: '',
required: true,
description: 'The email of the user',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['create'],
resource,
},
},
default: {},
options: [
{
displayName: 'Can Create Invoices',
name: 'can_create_invoices',
type: 'boolean',
default: false,
description: 'Whether the user can create invoices. Only applicable to Project Managers.',
},
{
displayName: 'Can Create Projects',
name: 'can_create_projects',
type: 'boolean',
default: false,
description: 'Whether the user can create projects. Only applicable to Project Managers.',
},
{
displayName: 'Can See Rates',
name: 'can_see_rates',
type: 'boolean',
default: false,
description:
'Whether the user can see billable rates on projects. Only applicable to Project Managers.',
},
{
displayName: 'Cost Rate',
name: 'cost_rate',
type: 'number',
typeOptions: {
minValue: 0,
},
default: 0,
description:
'The cost rate to use for this user when calculating a projects costs vs billable amount',
},
{
displayName: 'Default Hourly Rate',
name: 'default_hourly_rate',
type: 'string',
default: '0',
description: 'The billable rate to use for this user when they are added to a project',
},
{
displayName: 'Has Access To All Future Projects',
name: 'has_access_to_all_future_projects',
type: 'boolean',
default: false,
description: 'Whether the user should be automatically added to future projects',
},
{
displayName: 'Is Active',
name: 'is_active',
type: 'boolean',
default: true,
description: 'Whether the user is active or archived',
},
{
displayName: 'Is Admin',
name: 'is_admin',
type: 'boolean',
default: false,
description: 'Whether the user has Admin permissions',
},
{
displayName: 'Is Contractor',
name: 'is_contractor',
type: 'boolean',
default: false,
description: 'Whether the user is a contractor or an employee',
},
{
displayName: 'Is Project Manager',
name: 'is_project_manager',
type: 'boolean',
default: false,
description: 'Whether the user has Project Manager permissions',
},
{
displayName: 'Roles',
name: 'roles',
type: 'string',
default: '',
description: 'The role names assigned to this person',
},
{
displayName: 'Timezone',
name: 'timezone',
type: 'string',
default: '',
// eslint-disable-next-line n8n-nodes-base/node-param-description-url-missing-protocol
description:
'The users timezone. Defaults to the companys timezone. See a list of <a href="/api-v2/introduction/overview/supported-timezones/">supported time zones</a>.',
},
{
displayName: 'Weekly Capacity',
name: 'weekly_capacity',
type: 'number',
typeOptions: {
minValue: 0,
},
default: 126000,
description:
'The number of hours per week this person is available to work in seconds. Defaults to <code class="language-plaintext highlighter-rouge">126000</code> seconds (35 hours).',
},
],
},
/* -------------------------------------------------------------------------- */
/* user:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Time Entry ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
description: 'The ID of the time entry to update',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['update'],
resource,
},
},
default: {},
options: [
{
displayName: 'Can Create Invoices',
name: 'can_create_invoices',
type: 'boolean',
default: false,
description: 'Whether the user can create invoices. Only applicable to Project Managers.',
},
{
displayName: 'Can Create Projects',
name: 'can_create_projects',
type: 'boolean',
default: false,
description: 'Whether the user can create projects. Only applicable to Project Managers.',
},
{
displayName: 'Can See Rates',
name: 'can_see_rates',
type: 'boolean',
default: false,
description:
'Whether the user can see billable rates on projects. Only applicable to Project Managers.',
},
{
displayName: 'Cost Rate',
name: 'cost_rate',
type: 'number',
typeOptions: {
minValue: 0,
},
default: 0,
description:
'The cost rate to use for this user when calculating a projects costs vs billable amount',
},
{
displayName: 'Default Hourly Rate',
name: 'default_hourly_rate',
type: 'string',
default: '0',
description: 'The billable rate to use for this user when they are added to a project',
},
{
displayName: 'Email',
name: 'email',
type: 'string',
placeholder: 'name@email.com',
default: '',
description: 'The user email',
},
{
displayName: 'First Name',
name: 'first_name',
type: 'string',
default: '',
description: 'The user first name',
},
{
displayName: 'Has Access To All Future Projects',
name: 'has_access_to_all_future_projects',
type: 'boolean',
default: false,
description: 'Whether the user should be automatically added to future projects',
},
{
displayName: 'Is Active',
name: 'is_active',
type: 'boolean',
default: true,
description: 'Whether the user is active or archived',
},
{
displayName: 'Is Admin',
name: 'is_admin',
type: 'boolean',
default: false,
description: 'Whether the user has Admin permissions',
},
{
displayName: 'Is Contractor',
name: 'is_contractor',
type: 'boolean',
default: false,
description: 'Whether the user is a contractor or an employee',
},
{
displayName: 'Is Project Manager',
name: 'is_project_manager',
type: 'boolean',
default: false,
description: 'Whether the user has Project Manager permissions',
},
{
displayName: 'Last Name',
name: 'last_name',
type: 'string',
default: '',
description: 'The user last name',
},
{
displayName: 'Roles',
name: 'roles',
type: 'string',
default: '',
description: 'The role names assigned to this person',
},
{
displayName: 'Timezone',
name: 'timezone',
type: 'string',
default: '',
// eslint-disable-next-line n8n-nodes-base/node-param-description-url-missing-protocol
description:
'The users timezone. Defaults to the companys timezone. See a list of <a href="/api-v2/introduction/overview/supported-timezones/">supported time zones</a>.',
},
{
displayName: 'Weekly Capacity',
name: 'weekly_capacity',
type: 'number',
typeOptions: {
minValue: 0,
},
default: 126000,
description:
'The number of hours per week this person is available to work in seconds. Defaults to <code class="language-plaintext highlighter-rouge">126000</code> seconds (35 hours).',
},
],
},
];
@@ -0,0 +1,27 @@
{
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"currency": {
"type": "string"
},
"id": {
"type": "integer"
},
"is_active": {
"type": "boolean"
},
"name": {
"type": "string"
},
"statement_key": {
"type": "string"
},
"updated_at": {
"type": "string"
}
},
"version": 1
}
@@ -0,0 +1,125 @@
{
"type": "object",
"properties": {
"client": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"client_key": {
"type": "string"
},
"closed_at": {
"type": "null"
},
"created_at": {
"type": "string"
},
"creator": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"currency": {
"type": "string"
},
"discount_amount": {
"type": "integer"
},
"due_date": {
"type": "string"
},
"estimate": {
"type": "null"
},
"id": {
"type": "integer"
},
"issue_date": {
"type": "string"
},
"line_items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"kind": {
"type": "string"
},
"project": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"taxed": {
"type": "boolean"
},
"taxed2": {
"type": "boolean"
}
}
}
},
"notes": {
"type": "string"
},
"number": {
"type": "string"
},
"payment_options": {
"type": "array",
"items": {
"type": "string"
}
},
"payment_term": {
"type": "string"
},
"purchase_order": {
"type": "string"
},
"retainer": {
"type": "null"
},
"state": {
"type": "string"
},
"subject": {
"type": "string"
},
"tax2": {
"type": "null"
},
"tax2_amount": {
"type": "integer"
},
"updated_at": {
"type": "string"
}
},
"version": 1
}
@@ -0,0 +1,65 @@
{
"type": "object",
"properties": {
"bill_by": {
"type": "string"
},
"budget_by": {
"type": "string"
},
"budget_is_monthly": {
"type": "boolean"
},
"client": {
"type": "object",
"properties": {
"currency": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"cost_budget_include_expenses": {
"type": "boolean"
},
"created_at": {
"type": "string"
},
"id": {
"type": "integer"
},
"is_active": {
"type": "boolean"
},
"is_billable": {
"type": "boolean"
},
"is_fixed_fee": {
"type": "boolean"
},
"name": {
"type": "string"
},
"notes": {
"type": "string"
},
"notify_when_over_budget": {
"type": "boolean"
},
"over_budget_notification_percentage": {
"type": "integer"
},
"show_budget_to_all": {
"type": "boolean"
},
"updated_at": {
"type": "string"
}
},
"version": 1
}
@@ -0,0 +1,62 @@
{
"type": "object",
"properties": {
"bill_by": {
"type": "string"
},
"budget_by": {
"type": "string"
},
"budget_is_monthly": {
"type": "boolean"
},
"client": {
"type": "object",
"properties": {
"currency": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"cost_budget_include_expenses": {
"type": "boolean"
},
"created_at": {
"type": "string"
},
"id": {
"type": "integer"
},
"is_active": {
"type": "boolean"
},
"is_billable": {
"type": "boolean"
},
"is_fixed_fee": {
"type": "boolean"
},
"name": {
"type": "string"
},
"notify_when_over_budget": {
"type": "boolean"
},
"over_budget_notification_percentage": {
"type": "integer"
},
"show_budget_to_all": {
"type": "boolean"
},
"updated_at": {
"type": "string"
}
},
"version": 1
}
@@ -0,0 +1,123 @@
{
"type": "object",
"properties": {
"billable": {
"type": "boolean"
},
"budgeted": {
"type": "boolean"
},
"client": {
"type": "object",
"properties": {
"currency": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"created_at": {
"type": "string"
},
"id": {
"type": "integer"
},
"is_billed": {
"type": "boolean"
},
"is_closed": {
"type": "boolean"
},
"is_locked": {
"type": "boolean"
},
"is_running": {
"type": "boolean"
},
"project": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"spent_date": {
"type": "string"
},
"task": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"task_assignment": {
"type": "object",
"properties": {
"billable": {
"type": "boolean"
},
"created_at": {
"type": "string"
},
"id": {
"type": "integer"
},
"updated_at": {
"type": "string"
}
}
},
"updated_at": {
"type": "string"
},
"user": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"user_assignment": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"id": {
"type": "integer"
},
"is_active": {
"type": "boolean"
},
"is_project_manager": {
"type": "boolean"
},
"updated_at": {
"type": "string"
},
"use_default_rates": {
"type": "boolean"
}
}
}
},
"version": 1
}
@@ -0,0 +1,69 @@
{
"type": "object",
"properties": {
"access_roles": {
"type": "array",
"items": {
"type": "string"
}
},
"avatar_url": {
"type": "string"
},
"calendar_integration_enabled": {
"type": "boolean"
},
"can_create_projects": {
"type": "boolean"
},
"created_at": {
"type": "string"
},
"email": {
"type": "string"
},
"first_name": {
"type": "string"
},
"has_access_to_all_future_projects": {
"type": "boolean"
},
"id": {
"type": "integer"
},
"is_active": {
"type": "boolean"
},
"is_contractor": {
"type": "boolean"
},
"last_name": {
"type": "string"
},
"permissions_claims": {
"type": "array",
"items": {
"type": "string"
}
},
"roles": {
"type": "array",
"items": {
"type": "string"
}
},
"telephone": {
"type": "string"
},
"timezone": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"weekly_capacity": {
"type": "integer"
}
},
"version": 1
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB