diff --git a/packages/nodes-base/nodes/Harvest/ClientDescription.ts b/packages/nodes-base/nodes/Harvest/ClientDescription.ts index 532d3a67a..eccb91018 100644 --- a/packages/nodes-base/nodes/Harvest/ClientDescription.ts +++ b/packages/nodes-base/nodes/Harvest/ClientDescription.ts @@ -23,6 +23,16 @@ export const clientOperations = [ value: 'getAll', description: 'Get data of all clients', }, + { + name: 'Create', + value: 'create', + description: `Create a client`, + }, + { + name: 'Update', + value: 'update', + description: `Update a client`, + }, { name: 'Delete', value: 'delete', diff --git a/packages/nodes-base/nodes/Harvest/ContactDescription.ts b/packages/nodes-base/nodes/Harvest/ContactDescription.ts index 66dd0386e..0fda65bf6 100644 --- a/packages/nodes-base/nodes/Harvest/ContactDescription.ts +++ b/packages/nodes-base/nodes/Harvest/ContactDescription.ts @@ -23,6 +23,16 @@ export const contactOperations = [ value: 'getAll', description: 'Get data of all contacts', }, + { + name: 'Create', + value: 'create', + description: `Create a contact`, + }, + { + name: 'Update', + value: 'update', + description: `Update a contact`, + }, { name: 'Delete', value: 'delete', diff --git a/packages/nodes-base/nodes/Harvest/EstimateDescription.ts b/packages/nodes-base/nodes/Harvest/EstimateDescription.ts index 4216ab0db..1bb35601f 100644 --- a/packages/nodes-base/nodes/Harvest/EstimateDescription.ts +++ b/packages/nodes-base/nodes/Harvest/EstimateDescription.ts @@ -23,6 +23,16 @@ export const estimateOperations = [ value: 'getAll', description: 'Get data of all estimates', }, + { + name: 'Create', + value: 'create', + description: `Create a estimate`, + }, + { + name: 'Update', + value: 'update', + description: `Update a estimate`, + }, { name: 'Delete', value: 'delete', @@ -179,6 +189,215 @@ export const estimateFields = [ }, }, description: 'The ID of the estimate want to delete.', -} +}, + + /* -------------------------------------------------------------------------- */ + /* invoice:create */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'client_id', + name: 'client_id', + 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: '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: '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%.' + }, + { + 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: 'Subject', + name: 'subject', + type: 'string', + default: '', + description: 'The estimate subject.' + }, + { + displayName: 'Currency', + name: 'currency', + type: 'string', + default: '', + description: 'The currency used by the estimate. If not provided, the client’s currency will be used. See a list of supported currencies' + }, + { + displayName: 'Notes', + name: 'notes', + type: 'string', + default: '', + description: 'Any additional notes to include on the estimate.' + }, + { + displayName: 'Issue Date', + name: 'issue_date', + type: 'dateTime', + default: '', + description: 'Date the invoice was issued. Defaults to today’s date.' + }, + + ], + }, + + /* -------------------------------------------------------------------------- */ + /* 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: '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: '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%.' + }, + { + 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: 'Subject', + name: 'subject', + type: 'string', + default: '', + description: 'The estimate subject.' + }, + { + displayName: 'Currency', + name: 'currency', + type: 'string', + default: '', + description: 'The currency used by the estimate. If not provided, the client’s currency will be used. See a list of supported currencies' + }, + { + displayName: 'Notes', + name: 'notes', + type: 'string', + default: '', + description: 'Any additional notes to include on the estimate.' + }, + { + displayName: 'Issue Date', + name: 'issue_date', + type: 'dateTime', + default: '', + description: 'Date the invoice was issued. Defaults to today’s date.' + }, + + ], + }, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Harvest/ExpenseDescription.ts b/packages/nodes-base/nodes/Harvest/ExpenseDescription.ts index ff1613d62..c2095b622 100644 --- a/packages/nodes-base/nodes/Harvest/ExpenseDescription.ts +++ b/packages/nodes-base/nodes/Harvest/ExpenseDescription.ts @@ -1,6 +1,6 @@ import { INodeProperties } from "n8n-workflow"; -const resource = [ 'invoices' ]; +const resource = [ 'expenses' ]; export const expenseOperations = [ { @@ -23,6 +23,16 @@ export const expenseOperations = [ value: 'getAll', description: 'Get data of all expenses', }, + { + name: 'Create', + value: 'create', + description: `Create a expense`, + }, + { + name: 'Update', + value: 'update', + description: `Update a expense`, + }, { name: 'Delete', value: 'delete', @@ -193,6 +203,205 @@ export const expenseFields = [ }, }, description: 'The ID of the expense you want to delete.', -} +}, + + /* -------------------------------------------------------------------------- */ + /* expense:create */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Project Id', + name: 'project_id', + 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: 'expense_category_id', + 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: 'spent_date', + 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: 'User Id', + name: 'user_id', + type: 'boolean', + default: true, + description: 'The ID of the user associated with this expense. Defaults to the ID of the currently authenticated user.' + }, + { + displayName: 'Units', + name: 'units', + type: 'string', + default: '', + description: 'The quantity of units to use in calculating the total_cost of the expense.' + }, + { + displayName: 'Total Cost', + name: 'total_cost', + type: 'string', + default: '', + description: 'The total amount of the expense.' + }, + { + displayName: 'Billable', + name: 'billable', + type: 'string', + default: '', + description: 'Whether this expense is billable or not. Defaults to true.' + }, + { + displayName: 'Notes', + name: 'notes', + type: 'string', + default: '', + description: 'Notes about the expense.' + }, + + ], + }, + + /* -------------------------------------------------------------------------- */ + /* 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: 'Project Id', + name: 'project_id', + type: 'string', + default: '', + description: 'The ID of the project associated with this expense.', + }, + { + 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: 'Spent Date', + name: 'spent_date', + type: 'dateTime', + default: '', + description: 'Date the expense occurred.', + }, + { + displayName: 'User Id', + name: 'user_id', + type: 'boolean', + default: true, + description: 'The ID of the user associated with this expense. Defaults to the ID of the currently authenticated user.' + }, + { + displayName: 'Units', + name: 'units', + type: 'string', + default: '', + description: 'The quantity of units to use in calculating the total_cost of the expense.' + }, + { + displayName: 'Total Cost', + name: 'total_cost', + type: 'string', + default: '', + description: 'The total amount of the expense.' + }, + { + displayName: 'Billable', + name: 'billable', + type: 'string', + default: '', + description: 'Whether this expense is billable or not. Defaults to true.' + }, + { + displayName: 'Notes', + name: 'notes', + type: 'string', + default: '', + description: 'Notes about the expense.' + }, + + ], + }, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Harvest/Harvest.node.ts b/packages/nodes-base/nodes/Harvest/Harvest.node.ts index a98921220..0584aeb31 100644 --- a/packages/nodes-base/nodes/Harvest/Harvest.node.ts +++ b/packages/nodes-base/nodes/Harvest/Harvest.node.ts @@ -649,7 +649,41 @@ export class Harvest implements INodeType { const responseData: IDataObject[] = await getAllResource.call(this, resource, i); returnData.push.apply(returnData, responseData); - } else if (operation === 'delete') { + } else if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = resource; + + body.project_id = this.getNodeParameter('project_id', i) as string; + body.expense_category_id = this.getNodeParameter('expense_category_id', i) as string; + body.spent_date = this.getNodeParameter('spent_date', i) as string; + + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'update') { + // ---------------------------------- + // createByDuration + // ---------------------------------- + + requestMethod = 'PATCH'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `${resource}/${id}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(qs, updateFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'delete') { // ---------------------------------- // delete // ---------------------------------- @@ -685,7 +719,38 @@ export class Harvest implements INodeType { const responseData: IDataObject[] = await getAllResource.call(this, resource, i); returnData.push.apply(returnData, responseData); - } else if (operation === 'delete') { + } else if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = resource; + + body.client_id = this.getNodeParameter('client_id', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'update') { + // ---------------------------------- + // createByDuration + // ---------------------------------- + + requestMethod = 'PATCH'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `${resource}/${id}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(qs, updateFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'delete') { // ---------------------------------- // delete // ---------------------------------- diff --git a/packages/nodes-base/nodes/Harvest/InvoiceDescription.ts b/packages/nodes-base/nodes/Harvest/InvoiceDescription.ts index b38e6a665..ebab65a53 100644 --- a/packages/nodes-base/nodes/Harvest/InvoiceDescription.ts +++ b/packages/nodes-base/nodes/Harvest/InvoiceDescription.ts @@ -23,6 +23,16 @@ export const invoiceOperations = [ value: 'getAll', description: 'Get data of all invoices', }, + { + name: 'Create', + value: 'create', + description: `Create a invoice`, + }, + { + name: 'Update', + value: 'update', + description: `Update a invoice`, + }, { name: 'Delete', value: 'delete',