diff --git a/packages/nodes-base/nodes/Harvest/ClientDescription.ts b/packages/nodes-base/nodes/Harvest/ClientDescription.ts index eccb910186..0ee743018b 100644 --- a/packages/nodes-base/nodes/Harvest/ClientDescription.ts +++ b/packages/nodes-base/nodes/Harvest/ClientDescription.ts @@ -158,6 +158,129 @@ export const clientFields = [ }, }, 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: 'is_active', + name: 'is_active', + type: 'string', + default: '', + description: 'Whether the client is active, or archived. Defaults to true.' + }, + { + displayName: 'address', + name: 'address', + type: 'string', + default: '', + description: ' A textual representation of the client’s 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 client’s currency will be used. See a list of supported currencies' + }, + ], + }, + + /* -------------------------------------------------------------------------- */ + /* 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: 'name', + name: 'name', + type: 'string', + default: '', + description: 'Whether the client is active, or archived. Defaults to true.' + }, + { + displayName: 'is_active', + name: 'is_active', + type: 'string', + default: '', + description: 'Whether the client is active, or archived. Defaults to true.' + }, + { + displayName: 'address', + name: 'address', + type: 'string', + default: '', + description: ' A textual representation of the client’s 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 client’s currency will be used. See a list of supported currencies' + }, + ], + }, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Harvest/ContactDescription.ts b/packages/nodes-base/nodes/Harvest/ContactDescription.ts index 0fda65bf6e..1532809f51 100644 --- a/packages/nodes-base/nodes/Harvest/ContactDescription.ts +++ b/packages/nodes-base/nodes/Harvest/ContactDescription.ts @@ -1,6 +1,6 @@ import { INodeProperties } from "n8n-workflow"; -const resource = [ 'contacts' ]; +const resource = ['contacts']; export const contactOperations = [ { @@ -47,117 +47,305 @@ export const contactOperations = [ export const contactFields = [ -/* -------------------------------------------------------------------------- */ -/* contact:getAll */ -/* -------------------------------------------------------------------------- */ + /* -------------------------------------------------------------------------- */ + /* contact:getAll */ + /* -------------------------------------------------------------------------- */ -{ - displayName: 'Return All', - name: 'returnAll', - type: 'boolean', - displayOptions: { - show: { - resource, - operation: [ - 'getAll', - ], + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource, + operation: [ + 'getAll', + ], + }, }, + default: false, + description: 'Returns a list of your user contacts.', }, - default: false, - description: 'Returns a list of your user contacts.', -}, -{ - displayName: 'Limit', - name: 'limit', - type: 'number', - displayOptions: { - show: { - resource, - operation: [ - 'getAll', - ], - returnAll: [ - false, - ], + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + resource, + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, }, - }, - typeOptions: { - minValue: 1, - maxValue: 100, - }, - default: 100, - description: 'How many results to return.', -}, -{ - displayName: 'Filters', - name: 'filters', - type: 'collection', - placeholder: 'Add Filter', - default: {}, - displayOptions: { - show: { - resource, - operation: [ - 'getAll', - ], + typeOptions: { + minValue: 1, + maxValue: 100, }, + default: 100, + description: 'How many results to return.', }, - options: [ - { - displayName: 'Is Active', - name: 'is_active', - type: 'boolean', - default: '', - description: 'Pass true to only return active clients and false to return inactive clients.', + { + displayName: 'Filters', + name: 'filters', + type: 'collection', + placeholder: 'Add Filter', + default: {}, + displayOptions: { + show: { + resource, + operation: [ + 'getAll', + ], + }, }, - { - displayName: 'Updated Since', - name: 'updated_since', - type: 'dateTime', - default: '', - description: 'Only return clients that have been updated since the given date and time.', - } - ] -}, + options: [ + { + displayName: 'Is Active', + name: 'is_active', + type: 'boolean', + default: '', + description: 'Pass true 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, + /* -------------------------------------------------------------------------- */ + /* 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.', }, - 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, + /* -------------------------------------------------------------------------- */ + /* 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: 'first_name', + type: 'string', + displayOptions: { + show: { + operation: [ + 'create', + ], + resource, + }, + }, + default: '', + required: true, + description: 'The first name of the contact.', + }, + { + displayName: 'client_id', + name: 'client_id', + 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: 'last_name', + name: 'last_name', + type: 'string', + default: '', + description: 'The last name of the contact.' + }, + { + displayName: 'title', + name: 'title', + type: 'string', + default: '', + description: 'The title of the contact.' + }, + { + displayName: 'email', + name: 'email', + type: 'string', + default: '', + description: 'The contact’s email address.' + }, + { + displayName: 'phone_office', + name: 'phone_office', + type: 'string', + default: '', + description: 'The contact’s office phone number.' + }, + { + displayName: 'phone_mobile', + name: 'phone_mobile', + type: 'string', + default: '', + description: 'The contact’s mobile phone number.' + }, + { + displayName: 'fax', + name: 'fax', + type: 'string', + default: '', + description: 'The contact’s fax number.' + }, + ], + }, + + /* -------------------------------------------------------------------------- */ + /* 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: '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: 'title', + name: 'title', + type: 'string', + default: '', + description: 'The title of the contact.' + }, + { + displayName: 'email', + name: 'email', + type: 'string', + default: '', + description: 'The contact’s email address.' + }, + { + displayName: 'phone_office', + name: 'phone_office', + type: 'string', + default: '', + description: 'The contact’s office phone number.' + }, + { + displayName: 'phone_mobile', + name: 'phone_mobile', + type: 'string', + default: '', + description: 'The contact’s mobile phone number.' + }, + { + displayName: 'fax', + name: 'fax', + type: 'string', + default: '', + description: 'The contact’s fax number.' + }, + ], }, - description: 'The ID of the contact you want to delete.', -} ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Harvest/GenericFunctions.ts b/packages/nodes-base/nodes/Harvest/GenericFunctions.ts index 6adf097b30..c0eced039c 100644 --- a/packages/nodes-base/nodes/Harvest/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Harvest/GenericFunctions.ts @@ -50,6 +50,7 @@ export async function harvestApiRequest( if (Object.keys(options.body).length === 0) { delete options.body; } + console.log(options) try { const result = await this.helpers.request!(options); diff --git a/packages/nodes-base/nodes/Harvest/Harvest.node.ts b/packages/nodes-base/nodes/Harvest/Harvest.node.ts index 0584aeb319..2c0eac3e66 100644 --- a/packages/nodes-base/nodes/Harvest/Harvest.node.ts +++ b/packages/nodes-base/nodes/Harvest/Harvest.node.ts @@ -35,7 +35,7 @@ async function getAllResource(this: IExecuteFunctions, resource: string, i: numb Object.assign(qs, additionalFields); let responseData: IDataObject = {}; - if(returnAll) { + if (returnAll) { responseData[resource] = await harvestApiRequestAllItems.call(this, requestMethod, qs, endpoint, resource); } else { const limit = this.getNodeParameter('limit', i) as string; @@ -306,6 +306,37 @@ export class Harvest implements INodeType { const responseData: IDataObject[] = await getAllResource.call(this, resource, i); returnData.push.apply(returnData, responseData); + } else if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = resource; + + body.name = this.getNodeParameter('name', 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') { + // ---------------------------------- + // update + // ---------------------------------- + + 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 @@ -342,7 +373,7 @@ export class Harvest implements INodeType { const responseData: IDataObject[] = await getAllResource.call(this, resource, i); returnData.push.apply(returnData, responseData); - } else if (operation === 'create') { + } else if (operation === 'create') { // ---------------------------------- // create // ---------------------------------- @@ -362,7 +393,7 @@ export class Harvest implements INodeType { const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); returnData.push(responseData); - } else if (operation === 'update') { + } else if (operation === 'update') { // ---------------------------------- // update // ---------------------------------- @@ -377,7 +408,7 @@ export class Harvest implements INodeType { const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); returnData.push(responseData); - } else if (operation === 'delete') { + } else if (operation === 'delete') { // ---------------------------------- // delete // ---------------------------------- @@ -444,9 +475,9 @@ export class Harvest implements INodeType { const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); returnData.push(responseData); - } else if (operation === 'update') { + } else if (operation === 'update') { // ---------------------------------- - // createByDuration + // update // ---------------------------------- requestMethod = 'PATCH'; @@ -459,7 +490,7 @@ export class Harvest implements INodeType { const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); returnData.push(responseData); - } else if (operation === 'delete') { + } else if (operation === 'delete') { // ---------------------------------- // delete // ---------------------------------- @@ -470,7 +501,7 @@ export class Harvest implements INodeType { const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); returnData.push(responseData); - } else { + } else { throw new Error(`The resource "${resource}" is not known!`); } } else if (resource === 'contacts') { @@ -495,6 +526,38 @@ export class Harvest implements INodeType { const responseData: IDataObject[] = await getAllResource.call(this, resource, i); returnData.push.apply(returnData, responseData); + } else if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = resource; + + body.client_id = this.getNodeParameter('client_id', i) as string; + body.first_name = this.getNodeParameter('first_name', 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') { + // ---------------------------------- + // update + // ---------------------------------- + + 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 @@ -506,7 +569,7 @@ export class Harvest implements INodeType { const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); returnData.push(responseData); - } else { + } else { throw new Error(`The resource "${resource}" is not known!`); } } else if (resource === 'companies') { @@ -546,7 +609,7 @@ 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 === 'delete') { // ---------------------------------- // delete // ---------------------------------- @@ -582,7 +645,7 @@ export class Harvest implements INodeType { const responseData: IDataObject[] = await getAllResource.call(this, resource, i); returnData.push.apply(returnData, responseData); - } else if (operation === 'create') { + } else if (operation === 'create') { // ---------------------------------- // create // ---------------------------------- @@ -598,9 +661,9 @@ export class Harvest implements INodeType { const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); returnData.push(responseData); - } else if (operation === 'update') { + } else if (operation === 'update') { // ---------------------------------- - // createByDuration + // update // ---------------------------------- requestMethod = 'PATCH'; @@ -613,7 +676,7 @@ export class Harvest implements INodeType { const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); returnData.push(responseData); - } else if (operation === 'delete') { + } else if (operation === 'delete') { // ---------------------------------- // delete // ---------------------------------- @@ -624,7 +687,7 @@ export class Harvest implements INodeType { const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); returnData.push(responseData); - } else { + } else { throw new Error(`The resource "${resource}" is not known!`); } } else if (resource === 'expenses') { @@ -649,7 +712,7 @@ export class Harvest implements INodeType { const responseData: IDataObject[] = await getAllResource.call(this, resource, i); returnData.push.apply(returnData, responseData); - } else if (operation === 'create') { + } else if (operation === 'create') { // ---------------------------------- // create // ---------------------------------- @@ -668,9 +731,9 @@ export class Harvest implements INodeType { const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); returnData.push(responseData); - } else if (operation === 'update') { + } else if (operation === 'update') { // ---------------------------------- - // createByDuration + // update // ---------------------------------- requestMethod = 'PATCH'; @@ -683,7 +746,7 @@ export class Harvest implements INodeType { const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); returnData.push(responseData); - } else if (operation === 'delete') { + } else if (operation === 'delete') { // ---------------------------------- // delete // ---------------------------------- @@ -694,7 +757,7 @@ export class Harvest implements INodeType { const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); returnData.push(responseData); - } else { + } else { throw new Error(`The resource "${resource}" is not known!`); } } else if (resource === 'estimates') { @@ -719,7 +782,7 @@ export class Harvest implements INodeType { const responseData: IDataObject[] = await getAllResource.call(this, resource, i); returnData.push.apply(returnData, responseData); - } else if (operation === 'create') { + } else if (operation === 'create') { // ---------------------------------- // create // ---------------------------------- @@ -735,9 +798,9 @@ export class Harvest implements INodeType { const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); returnData.push(responseData); - } else if (operation === 'update') { + } else if (operation === 'update') { // ---------------------------------- - // createByDuration + // update // ---------------------------------- requestMethod = 'PATCH'; @@ -750,7 +813,7 @@ export class Harvest implements INodeType { const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); returnData.push(responseData); - } else if (operation === 'delete') { + } else if (operation === 'delete') { // ---------------------------------- // delete // ---------------------------------- @@ -761,7 +824,7 @@ export class Harvest implements INodeType { const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); returnData.push(responseData); - } else { + } else { throw new Error(`The resource "${resource}" is not known!`); } } else {