diff --git a/packages/nodes-base/nodes/Salesmate/ActivityDescription.ts b/packages/nodes-base/nodes/Salesmate/ActivityDescription.ts new file mode 100644 index 0000000000..fe737729a7 --- /dev/null +++ b/packages/nodes-base/nodes/Salesmate/ActivityDescription.ts @@ -0,0 +1,627 @@ +import { INodeProperties } from 'n8n-workflow'; + +export const activityOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'activity', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + description: 'Create a activity', + }, + { + name: 'Update', + value: 'update', + description: 'Update a activity', + }, + { + name: 'Get', + value: 'get', + description: 'Get a activity', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all companies', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a activity', + }, + ], + default: 'create', + description: 'The operation to perform.', + }, +] as INodeProperties[]; + +export const activityFields = [ + +/* -------------------------------------------------------------------------- */ +/* activity:create */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Title', + name: 'title', + type: 'string', + default: '', + displayOptions: { + show: { + resource: [ + 'activity', + ], + operation: [ + 'create', + ], + }, + }, + required: true, + }, + { + displayName: 'Owner', + name: 'owner', + type: 'options', + default: '', + typeOptions: { + loadOptionsMethod: 'getUsers', + }, + displayOptions: { + show: { + resource: [ + 'activity', + ], + operation: [ + 'create', + ], + }, + }, + required: true, + }, + { + displayName: 'Type', + name: 'type', + type: 'string', + default: '', + displayOptions: { + show: { + resource: [ + 'activity', + ], + operation: [ + 'create', + ], + }, + }, + description: 'This field displays activity type such as call, meeting etc.', + required: true, + }, + { + displayName: 'RAW Data', + name: 'rawData', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'activity', + ], + operation: [ + 'create', + ], + }, + }, + default: false, + description: `If the data should include the fields details`, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'activity', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Description', + name: 'description', + typeOptions: { + alwaysOpenEditWindow: true, + }, + type: 'string', + default: '', + description: 'This field contains details related to the activity.', + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + default: '', + description: 'This field contains tags associated with an activity', + }, + { + displayName: 'Due Date', + name: 'dueDate', + type: 'dateTime', + default: '', + description: 'Expiry date of an activity.', + }, + { + displayName: 'Duration', + name: 'duration', + type: 'number', + default: '', + description: 'Time duration of an activity.', + }, + { + displayName: 'Is Calendar Invite', + name: 'isCalendarInvite', + type: 'boolean', + default: false, + description: 'This field is used to send calendar invite.', + }, + { + displayName: 'Is Completed', + name: 'isCompleted', + type: 'boolean', + default: false, + description: 'This field indicates whether the activity is completed or not.', + }, + ], + }, +/* -------------------------------------------------------------------------- */ +/* activity:update */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Activity ID', + name: 'id', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + resource: [ + 'activity', + ], + operation: [ + 'update', + ], + }, + }, + description: 'activity ID', + }, + { + displayName: 'RAW Data', + name: 'rawData', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'activity', + ], + operation: [ + 'update', + ], + }, + }, + default: false, + description: `If the data should include the fields details`, + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'activity', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + { + displayName: 'Title', + name: 'title', + type: 'string', + default: '', + }, + { + displayName: 'Type', + name: 'type', + type: 'string', + default: '', + }, + { + displayName: 'Owner', + name: 'owner', + type: 'string', + default: '', + }, + { + displayName: 'Description', + name: 'description', + typeOptions: { + alwaysOpenEditWindow: true, + }, + type: 'string', + default: '', + description: 'This field contains details related to the activity.', + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + default: '', + description: 'This field contains tags associated with an activity', + }, + { + displayName: 'Due Date', + name: 'dueDate', + type: 'dateTime', + default: '', + description: 'Expiry date of an activity.', + }, + { + displayName: 'Duration', + name: 'duration', + type: 'number', + default: '', + description: 'Time duration of an activity.', + }, + { + displayName: 'Is Calendar Invite', + name: 'isCalendarInvite', + type: 'boolean', + default: false, + description: 'This field is used to send calendar invite.', + }, + { + displayName: 'Is Completed', + name: 'isCompleted', + type: 'boolean', + default: false, + description: 'This field indicates whether the activity is completed or not.', + }, + ], + + }, +/* -------------------------------------------------------------------------- */ +/* activity:get */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Activity ID', + name: 'id', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + resource: [ + 'activity', + ], + operation: [ + 'get', + ], + }, + }, + description: 'activity ID', + }, + { + displayName: 'RAW Data', + name: 'rawData', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'activity', + ], + operation: [ + 'get', + ], + }, + }, + default: false, + description: `If the data should include the fields details`, + }, +/* -------------------------------------------------------------------------- */ +/* activity:getAll */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'activity', + ], + operation: [ + 'getAll', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + resource: [ + 'activity', + ], + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 25, + }, + default: 10, + description: 'How many results to return.', + }, + { + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'activity', + ], + }, + }, + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + resource: [ + 'activity', + ], + operation: [ + 'getAll', + ], + }, + }, + options: [ + { + displayName: 'Fields', + name: 'fields', + type: 'string', + default: '', + }, + { + displayName: 'Sort By', + name: 'sortBy', + type: 'string', + default: '', + }, + { + displayName: 'Sort Order', + name: 'sortOrder', + type: 'options', + options: [ + { + name: 'Asc', + value: 'asc', + }, + { + name: 'Desc', + value: 'desc', + }, + ], + default: 'desc', + description: 'Sort order', + } + ], + }, + { + displayName: 'Filters', + name: 'filtersJson', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'activity', + ], + jsonParameters: [ + true, + ], + }, + }, + }, + { + displayName: 'Filters', + name: 'filters', + placeholder: 'Add filter', + type: 'fixedCollection', + typeOptions: { + multipleValues: false, + }, + displayOptions: { + show: { + resource: [ + 'activity', + ], + operation: [ + 'getAll', + ], + jsonParameters: [ + false, + ], + }, + }, + default: {}, + options: [ + { + name: 'filtersUi', + displayName: 'Filters', + values: [ + { + displayName: 'Operator', + name: 'operator', + type: 'options', + options: [ + { + name: 'And', + value: 'AND', + }, + { + name: 'Or', + value: 'OR', + }, + ], + default: 'AND', + }, + { + displayName: 'Conditions', + name: 'conditions', + placeholder: 'Add Condition', + type: 'fixedCollection', + typeOptions: { + multipleValues: true, + }, + default: {}, + options: [ + { + name: 'conditionsUi', + displayName: 'Conditions', + values: [ + { + displayName: 'Field', + name: 'field', + type: 'options', + options: [ + { + name: 'Title', + value: 'title', + }, + { + name: 'Tags', + value: 'tags', + }, + ], + default: 'title', + }, + { + displayName: 'Condition', + name: 'condition', + type: 'options', + options: [ + { + name: 'Equals', + value: 'EQUALS', + }, + { + name: 'Not Equals', + value: 'NOT_EQUALS', + }, + { + name: 'Empty', + value: 'EMPTY', + }, + { + name: 'Not Empty', + value: 'NOT_EMPTY', + }, + { + name: 'CONTAINS', + value: 'Contains', + }, + { + name: 'Does Not Contains', + value: 'DOES_NOT_CONTAINS', + }, + { + name: 'Starts With', + value: 'STARTS_WITH', + }, + { + name: 'Ends With', + value: 'ENDS_WITH', + }, + ], + default: 'EQUALS', + description: 'Value of the property to set.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + } + ] + }, + ], + }, + ] + }, + ], + }, +/* -------------------------------------------------------------------------- */ +/* activity:delete */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Activity ID', + name: 'id', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + resource: [ + 'activity', + ], + operation: [ + 'delete', + ], + }, + }, + description: 'If more than one activity add them separated by ,', + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Salesmate/ActivityInterface.ts b/packages/nodes-base/nodes/Salesmate/ActivityInterface.ts new file mode 100644 index 0000000000..ab671d0b73 --- /dev/null +++ b/packages/nodes-base/nodes/Salesmate/ActivityInterface.ts @@ -0,0 +1,11 @@ +export interface IActivity { + title?: string; + owner?: number; + type?: string; + description?: string; + tags?: string; + dueDate?: number; + duration?: number; + isCalendarInvite?: boolean; + isCompleted?: boolean; +} diff --git a/packages/nodes-base/nodes/Salesmate/DealDescription.ts b/packages/nodes-base/nodes/Salesmate/DealDescription.ts new file mode 100644 index 0000000000..343c02b55a --- /dev/null +++ b/packages/nodes-base/nodes/Salesmate/DealDescription.ts @@ -0,0 +1,895 @@ +import { INodeProperties } from 'n8n-workflow'; + +export const dealOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'deal', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + description: 'Create a deal', + }, + { + name: 'Update', + value: 'update', + description: 'Update a deal', + }, + { + name: 'Get', + value: 'get', + description: 'Get a deal', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all companies', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a deal', + }, + ], + default: 'create', + description: 'The operation to perform.', + }, +] as INodeProperties[]; + +export const dealFields = [ + +/* -------------------------------------------------------------------------- */ +/* deal:create */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Title', + name: 'title', + type: 'string', + default: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + required: true, + }, + { + displayName: 'Owner', + name: 'owner', + type: 'options', + default: '', + typeOptions: { + loadOptionsMethod: 'getUsers', + }, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + required: true, + }, + { + displayName: 'Primary Contact', + name: 'primaryContact', + type: 'options', + default: '', + typeOptions: { + loadOptionsMethod: 'getContacts', + }, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + description: 'Primary contact for the deal.', + required: true, + }, + { + displayName: 'Pipeline', + name: 'pipeline', + type: 'options', + options: [ + { + name: 'Sales', + value: 'Sales', + }, + ], + default: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + required: true, + }, + { + displayName: 'Status', + name: 'status', + type: 'options', + default: 'Open', + options: [ + { + name: 'Open', + value: 'Open', + }, + { + name: 'Close', + value: 'Close', + }, + { + name: 'Lost', + value: 'Lost', + }, + ], + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + required: true, + }, + { + displayName: 'Stage', + name: 'stage', + type: 'options', + default: '', + options: [ + { + name: 'New (Untouched)', + value: 'New (Untouched)', + }, + { + name: 'Contacted', + value: 'Contacted', + }, + { + name: 'Qualified', + value: 'Qualified', + }, + { + name: 'Proposal Presented', + value: 'Proposal Presented', + }, + { + name: 'In Negotiation', + value: 'In Negotiation', + }, + ], + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + required: true, + }, + { + displayName: 'Currency', + name: 'currency', + type: 'string', + default: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + required: true, + }, + { + displayName: 'RAW Data', + name: 'rawData', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + default: false, + description: `If the data should include the fields details`, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Description', + name: 'description', + typeOptions: { + alwaysOpenEditWindow: true, + }, + type: 'string', + default: '', + description: 'This field contains details related to the deal.', + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + default: '', + description: 'This field contains tags associated with an deal', + }, + { + displayName: 'Primary Company', + name: 'primaryCompany', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getCompanies', + }, + default: '', + }, + { + displayName: 'Source', + name: 'source', + type: 'options', + options: [ + { + name: 'Ads', + value: 'Ads', + }, + { + name: 'Referrals', + value: 'Referrals', + }, + { + name: 'Website', + value: 'Website', + }, + { + name: 'Word of mouth', + value: 'Word of mouth', + }, + ], + default: 'Ads', + }, + { + displayName: 'Estimated Close Date', + name: 'estimatedCloseDate', + type: 'dateTime', + default: '', + }, + { + displayName: 'Deal Value', + name: 'dealValue', + type: 'number', + typeOptions: { + numberPrecision: 2, + }, + default: 0, + }, + { + displayName: 'Priority', + name: 'priority', + type: 'options', + default: 'Medium', + options: [ + { + name: 'High', + value: 'High', + }, + { + name: 'Medium', + value: 'Medium', + }, + { + name: 'Low', + value: 'Low', + }, + ], + }, + ], + }, +/* -------------------------------------------------------------------------- */ +/* deal:update */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Deal ID', + name: 'id', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + }, + }, + description: 'deal ID', + }, + { + displayName: 'RAW Data', + name: 'rawData', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + }, + }, + default: false, + description: `If the data should include the fields details`, + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + { + displayName: 'Title', + name: 'title', + type: 'string', + default: '', + }, + { + displayName: 'Owner', + name: 'owner', + type: 'options', + default: '', + typeOptions: { + loadOptionsMethod: 'getUsers', + }, + }, + { + displayName: 'Primary Contact', + name: 'primaryContact', + type: 'options', + default: '', + typeOptions: { + loadOptionsMethod: 'getContacts', + }, + }, + { + displayName: 'Pipeline', + name: 'pipeline', + type: 'options', + options: [ + { + name: 'Sales', + value: 'Sales', + }, + ], + default: '', + }, + { + displayName: 'Status', + name: 'status', + type: 'options', + default: 'Open', + options: [ + { + name: 'Open', + value: 'Open', + }, + { + name: 'Close', + value: 'Close', + }, + { + name: 'Lost', + value: 'Lost', + }, + ], + }, + { + displayName: 'Stage', + name: 'stage', + type: 'options', + default: '', + options: [ + { + name: 'New (Untouched)', + value: 'New (Untouched)', + }, + { + name: 'Contacted', + value: 'Contacted', + }, + { + name: 'Qualified', + value: 'Qualified', + }, + { + name: 'Proposal Presented', + value: 'Proposal Presented', + }, + { + name: 'In Negotiation', + value: 'In Negotiation', + }, + ], + }, + { + displayName: 'Currency', + name: 'currency', + type: 'string', + default: '', + }, + { + displayName: 'Description', + name: 'description', + typeOptions: { + alwaysOpenEditWindow: true, + }, + type: 'string', + default: '', + description: 'This field contains details related to the deal.', + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + default: '', + description: 'This field contains tags associated with an deal', + }, + { + displayName: 'Primary Company', + name: 'primaryCompany', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getCompanies', + }, + default: '', + }, + { + displayName: 'Source', + name: 'source', + type: 'options', + options: [ + { + name: 'Ads', + value: 'Ads', + }, + { + name: 'Referrals', + value: 'Referrals', + }, + { + name: 'Website', + value: 'Website', + }, + { + name: 'Word of mouth', + value: 'Word of mouth', + }, + ], + default: 'Ads', + }, + { + displayName: 'Estimated Close Date', + name: 'estimatedCloseDate', + type: 'dateTime', + default: '', + }, + { + displayName: 'Deal Value', + name: 'dealValue', + type: 'number', + typeOptions: { + numberPrecision: 2, + }, + default: 0, + }, + { + displayName: 'Priority', + name: 'priority', + type: 'options', + default: 'Medium', + options: [ + { + name: 'High', + value: 'High', + }, + { + name: 'Medium', + value: 'Medium', + }, + { + name: 'Low', + value: 'Low', + }, + ], + }, + ], + }, +/* -------------------------------------------------------------------------- */ +/* deal:get */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Deal ID', + name: 'id', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'get', + ], + }, + }, + description: 'deal ID', + }, + { + displayName: 'RAW Data', + name: 'rawData', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'get', + ], + }, + }, + default: false, + description: `If the data should include the fields details`, + }, +/* -------------------------------------------------------------------------- */ +/* deal:getAll */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'getAll', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 25, + }, + default: 10, + description: 'How many results to return.', + }, + { + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'deal', + ], + }, + }, + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'getAll', + ], + }, + }, + options: [ + { + displayName: 'Fields', + name: 'fields', + type: 'string', + default: '', + }, + { + displayName: 'Sort By', + name: 'sortBy', + type: 'string', + default: '', + }, + { + displayName: 'Sort Order', + name: 'sortOrder', + type: 'options', + options: [ + { + name: 'Asc', + value: 'asc', + }, + { + name: 'Desc', + value: 'desc', + }, + ], + default: 'desc', + description: 'Sort order', + } + ], + }, + { + displayName: 'Filters', + name: 'filtersJson', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'deal', + ], + jsonParameters: [ + true, + ], + }, + }, + }, + { + displayName: 'Filters', + name: 'filters', + placeholder: 'Add filter', + type: 'fixedCollection', + typeOptions: { + multipleValues: false, + }, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'getAll', + ], + jsonParameters: [ + false, + ], + }, + }, + default: {}, + options: [ + { + name: 'filtersUi', + displayName: 'Filters', + values: [ + { + displayName: 'Operator', + name: 'operator', + type: 'options', + options: [ + { + name: 'And', + value: 'AND', + }, + { + name: 'Or', + value: 'OR', + }, + ], + default: 'AND', + }, + { + displayName: 'Conditions', + name: 'conditions', + placeholder: 'Add Condition', + type: 'fixedCollection', + typeOptions: { + multipleValues: true, + }, + default: {}, + options: [ + { + name: 'conditionsUi', + displayName: 'Conditions', + values: [ + { + displayName: 'Field', + name: 'field', + type: 'options', + options: [ + { + name: 'Title', + value: 'title', + }, + { + name: 'Tags', + value: 'tags', + }, + { + name: 'Last Communication Mode', + value: 'lastCommunicationMode', + }, + ], + default: 'title', + }, + { + displayName: 'Condition', + name: 'condition', + type: 'options', + options: [ + { + name: 'Equals', + value: 'EQUALS', + }, + { + name: 'Not Equals', + value: 'NOT_EQUALS', + }, + { + name: 'Empty', + value: 'EMPTY', + }, + { + name: 'Not Empty', + value: 'NOT_EMPTY', + }, + { + name: 'CONTAINS', + value: 'Contains', + }, + { + name: 'Does Not Contains', + value: 'DOES_NOT_CONTAINS', + }, + { + name: 'Starts With', + value: 'STARTS_WITH', + }, + { + name: 'Ends With', + value: 'ENDS_WITH', + }, + ], + default: 'EQUALS', + description: 'Value of the property to set.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + } + ] + }, + ], + }, + ] + }, + ], + }, +/* -------------------------------------------------------------------------- */ +/* deal:delete */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Deal ID', + name: 'id', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'delete', + ], + }, + }, + description: 'If more than one deal add them separated by ,', + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Salesmate/DealInterface.ts b/packages/nodes-base/nodes/Salesmate/DealInterface.ts new file mode 100644 index 0000000000..7e4e1df106 --- /dev/null +++ b/packages/nodes-base/nodes/Salesmate/DealInterface.ts @@ -0,0 +1,16 @@ +export interface IDeal { + title?: string; + owner?: number; + pipeline?: string; + primaryContact?: number; + primaryCompany?: number; + status?: string; + stage?: string; + source?: string; + estimatedCloseDate?: string; + dealValue?: number; + currency?: string; + priority?: string; + description?: string; + tags?: string; +} diff --git a/packages/nodes-base/nodes/Salesmate/GenericFunctions.ts b/packages/nodes-base/nodes/Salesmate/GenericFunctions.ts index 4546113164..a84dbc95e2 100644 --- a/packages/nodes-base/nodes/Salesmate/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Salesmate/GenericFunctions.ts @@ -27,6 +27,7 @@ export async function salesmateApiRequest(this: IHookFunctions | IExecuteFunctio json: true }; if (!Object.keys(body).length) { + delete options.body; } try { return await this.helpers.request!(options); diff --git a/packages/nodes-base/nodes/Salesmate/Salesmate.node.ts b/packages/nodes-base/nodes/Salesmate/Salesmate.node.ts index 62be08e7e7..a57b8b7410 100644 --- a/packages/nodes-base/nodes/Salesmate/Salesmate.node.ts +++ b/packages/nodes-base/nodes/Salesmate/Salesmate.node.ts @@ -18,9 +18,23 @@ import { companyFields, companyOperations, } from './CompanyDescription'; +import { + activityFields, + activityOperations, +} from './ActivityDescription'; import { ICompany, } from './CompanyInterface'; + import { + IActivity, + } from './ActivityInterface'; + import { + IDeal, + } from './DealInterface'; +import { + dealFields, + dealOperations, + } from './DealDescription'; export class Salesmate implements INodeType { description: INodeTypeDescription = { @@ -49,16 +63,28 @@ export class Salesmate implements INodeType { name: 'resource', type: 'options', options: [ + { + name: 'Activity', + value: 'activity', + }, { name: 'Company', value: 'company', }, + { + name: 'Deal', + value: 'deal', + }, ], - default: 'company', + default: 'activity', description: 'Resource to consume.', }, ...companyOperations, + ...activityOperations, + ...dealOperations, ...companyFields, + ...activityFields, + ...dealFields, ], }; @@ -79,6 +105,44 @@ export class Salesmate implements INodeType { } return returnData; }, + // Get all the available contacs to display them to user so that he can + // select them easily + async getContacts(this: ILoadOptionsFunctions): Promise { + const returnData: INodePropertyOptions[] = []; + const qs: IDataObject = { + fields: ['name', 'id'], + query: {} + }; + const contacts = await salesmateApiRequest.call(this, 'POST', '/v2/contacts/search', qs); + for (const contact of contacts.Data.data) { + const contactName = contact.name; + const contactId = contact.id; + returnData.push({ + name: contactName, + value: contactId, + }); + } + return returnData; + }, + // Get all the available companies to display them to user so that he can + // select them easily + async getCompanies(this: ILoadOptionsFunctions): Promise { + const returnData: INodePropertyOptions[] = []; + const qs: IDataObject = { + fields: ['name', 'id'], + query: {} + }; + const companies = await salesmateApiRequest.call(this, 'POST', '/v2/companies/search', qs); + for (const company of companies.Data.data) { + const companyName = company.name; + const companyId = company.id; + returnData.push({ + name: companyName, + value: companyId, + }); + } + return returnData; + }, }, }; @@ -257,7 +321,7 @@ export class Salesmate implements INodeType { if (!jsonActive) { const filters: IDataObject[] = []; const filtersUi = (this.getNodeParameter('filters', i) as IDataObject).filtersUi as IDataObject; - if (filtersUi.conditions) { + if (filtersUi && filtersUi.conditions) { const conditions = filtersUi.conditions as IDataObject; if (conditions.conditionsUi) { for (const condition of conditions.conditionsUi as IDataObject[]) { @@ -272,11 +336,13 @@ export class Salesmate implements INodeType { } } } - //@ts-ignore - body.query.group = { - operator: filtersUi.operator, - rules: filters, - }; + if (filtersUi && filtersUi.operator) { + //@ts-ignore + body.query.group = { + operator: filtersUi.operator, + rules: filters, + }; + } } else { const json = validateJSON(this.getNodeParameter('filtersJson', i) as string); body = json; @@ -295,6 +361,334 @@ export class Salesmate implements INodeType { responseData = await salesmateApiRequest.call(this, 'DELETE', `/v1/companies/${companyId}`); } } + if (resource === 'activity') { + if (operation === 'create') { + const owner = this.getNodeParameter('owner', i) as number; + const title = this.getNodeParameter('title', i) as string; + const type = this.getNodeParameter('type', i) as string; + const rawData = this.getNodeParameter('rawData', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IActivity = { + title, + owner, + type, + }; + if (additionalFields.dueDate) { + body.dueDate = new Date(additionalFields.dueDate as string).getTime(); + } + if (additionalFields.duration) { + body.duration = additionalFields.duration as number; + } + if (additionalFields.isCalendarInvite) { + body.isCalendarInvite = additionalFields.isCalendarInvite as boolean; + } + if (additionalFields.isCompleted) { + body.isCompleted = additionalFields.isCompleted as boolean; + } + if (additionalFields.description) { + body.description = additionalFields.description as string; + } + if (additionalFields.tags) { + body.tags = additionalFields.tags as string; + } + responseData = await salesmateApiRequest.call(this, 'POST', '/v1/activities', body); + responseData = responseData.Data; + if (!rawData) { + delete responseData.detail; + } + } + if (operation === 'update') { + const activityId = this.getNodeParameter('id', i) as string; + const rawData = this.getNodeParameter('rawData', i) as boolean; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IActivity = {}; + if (updateFields.title) { + body.title = updateFields.title as string; + } + if (updateFields.type) { + body.type = updateFields.type as string; + } + if (updateFields.owner) { + body.owner = updateFields.owner as number; + } + if (updateFields.dueDate) { + body.dueDate = new Date(updateFields.dueDate as string).getTime(); + } + if (updateFields.duration) { + body.duration = updateFields.duration as number; + } + if (updateFields.isCalendarInvite) { + body.isCalendarInvite = updateFields.isCalendarInvite as boolean; + } + if (updateFields.isCompleted) { + body.isCompleted = updateFields.isCompleted as boolean; + } + if (updateFields.description) { + body.description = updateFields.description as string; + } + if (updateFields.tags) { + body.tags = updateFields.tags as string; + } + responseData = await salesmateApiRequest.call(this, 'PUT', `/v1/activities/${activityId}`, body); + responseData = responseData.Data; + if (!rawData) { + delete responseData.detail; + } + } + if (operation === 'get') { + const activityId = this.getNodeParameter('id', i) as string; + const rawData = this.getNodeParameter('rawData', i) as boolean; + responseData = await salesmateApiRequest.call(this, 'GET', `/v1/activities/${activityId}`); + responseData = responseData.Data; + if (!rawData) { + responseData = responseData.map((activity: IDataObject) => { + const aux: IDataObject = {}; + aux[activity.fieldName as string] = activity.value; + return aux; + }); + } + } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; + let body: IDataObject = { + query: { + group: { + }, + }, + }; + if (options.sortBy) { + qs.sortBy = options.sortBy as string; + } + if (options.sortOrder) { + qs.sortOrder = options.sortOrder as string; + } + if (options.fields) { + body.fields = (options.fields as string).split(',') as string[]; + } else { + throw new Error('You have to add at least one field'); + } + if (!jsonActive) { + const filters: IDataObject[] = []; + const filtersUi = (this.getNodeParameter('filters', i) as IDataObject).filtersUi as IDataObject; + if (filtersUi && filtersUi.conditions) { + const conditions = filtersUi.conditions as IDataObject; + if (conditions.conditionsUi) { + for (const condition of conditions.conditionsUi as IDataObject[]) { + const filter: IDataObject = {}; + filter.moduleName = 'Task'; + filter.field = { + fieldName: condition.field, + }; + filter.condition = condition.condition; + filter.data = condition.value; + filters.push(filter) + } + } + } + if (filtersUi && filtersUi.operator) { + //@ts-ignore + body.query.group = { + operator: filtersUi.operator, + rules: filters, + }; + } + } else { + const json = validateJSON(this.getNodeParameter('filtersJson', i) as string); + body = json; + } + if (returnAll) { + responseData = await salesmateApiRequestAllItems.call(this, 'Data', 'POST', '/v2/activities/search', body, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.rows = limit; + responseData = await salesmateApiRequest.call(this, 'POST', '/v2/activities/search', body, qs); + responseData = responseData.Data.data; + } + } + if (operation === 'delete') { + const activityId = this.getNodeParameter('id', i) as string; + responseData = await salesmateApiRequest.call(this, 'DELETE', `/v1/activities/${activityId}`); + } + } + if (resource === 'deal') { + if (operation === 'create') { + const title = this.getNodeParameter('title', i) as string; + const owner = this.getNodeParameter('owner', i) as number; + const primaryContact = this.getNodeParameter('primaryContact', i) as number; + const pipeline = this.getNodeParameter('pipeline', i) as string; + const status = this.getNodeParameter('status', i) as string; + const stage = this.getNodeParameter('stage', i) as string; + const currency = this.getNodeParameter('currency', i) as string; + const rawData = this.getNodeParameter('rawData', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDeal = { + title, + owner, + primaryContact, + pipeline, + status, + stage, + currency, + }; + if (additionalFields.description) { + body.description = additionalFields.description as string; + } + if (additionalFields.tags) { + body.tags = additionalFields.tags as string; + } + if (additionalFields.primaryCompany) { + body.primaryCompany = additionalFields.primaryCompany as number; + } + if (additionalFields.source) { + body.source = additionalFields.source as string; + } + if (additionalFields.estimatedCloseDate) { + body.estimatedCloseDate = additionalFields.estimatedCloseDate as string; + } + if (additionalFields.dealValue) { + body.dealValue = additionalFields.dealValue as number; + } + if (additionalFields.priority) { + body.priority = additionalFields.priority as string; + } + responseData = await salesmateApiRequest.call(this, 'POST', '/v1/deals', body); + responseData = responseData.Data; + if (!rawData) { + delete responseData.detail; + } + } + if (operation === 'update') { + const dealId = this.getNodeParameter('id', i) as string; + const rawData = this.getNodeParameter('rawData', i) as boolean; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDeal = {}; + if (updateFields.title) { + body.title = updateFields.title as string; + } + if (updateFields.owner) { + body.owner = updateFields.owner as number; + } + if (updateFields.primaryContact) { + body.primaryContact = updateFields.primaryContact as number; + } + if (updateFields.status) { + body.status = updateFields.status as string; + } + if (updateFields.currency) { + body.currency = updateFields.currency as string; + } + if (updateFields.stage) { + body.stage = updateFields.stage as string; + } + if (updateFields.pipeline) { + body.pipeline = updateFields.pipeline as string; + } + if (updateFields.description) { + body.description = updateFields.description as string; + } + if (updateFields.tags) { + body.tags = updateFields.tags as string; + } + if (updateFields.primaryCompany) { + body.primaryCompany = updateFields.primaryCompany as number; + } + if (updateFields.source) { + body.source = updateFields.source as string; + } + if (updateFields.estimatedCloseDate) { + body.estimatedCloseDate = updateFields.estimatedCloseDate as string; + } + if (updateFields.dealValue) { + body.dealValue = updateFields.dealValue as number; + } + if (updateFields.priority) { + body.priority = updateFields.priority as string; + } + responseData = await salesmateApiRequest.call(this, 'PUT', `/v1/deals/${dealId}`, body); + responseData = responseData.Data; + if (!rawData) { + delete responseData.detail; + } + } + if (operation === 'get') { + const dealId = this.getNodeParameter('id', i) as string; + const rawData = this.getNodeParameter('rawData', i) as boolean; + responseData = await salesmateApiRequest.call(this, 'GET', `/v1/deals/${dealId}`); + responseData = responseData.Data; + if (!rawData) { + responseData = responseData.map((deal: IDataObject) => { + const aux: IDataObject = {}; + aux[deal.fieldName as string] = deal.value; + return aux; + }); + } + } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; + let body: IDataObject = { + query: { + group: { + }, + }, + }; + if (options.sortBy) { + qs.sortBy = options.sortBy as string; + } + if (options.sortOrder) { + qs.sortOrder = options.sortOrder as string; + } + if (options.fields) { + body.fields = (options.fields as string).split(',') as string[]; + } else { + throw new Error('You have to add at least one field'); + } + if (!jsonActive) { + const filters: IDataObject[] = []; + const filtersUi = (this.getNodeParameter('filters', i) as IDataObject).filtersUi as IDataObject; + if (filtersUi && filtersUi.conditions) { + const conditions = filtersUi.conditions as IDataObject; + if (conditions.conditionsUi) { + for (const condition of conditions.conditionsUi as IDataObject[]) { + const filter: IDataObject = {}; + filter.moduleName = 'Task'; + filter.field = { + fieldName: condition.field, + }; + filter.condition = condition.condition; + filter.data = condition.value; + filters.push(filter) + } + } + } + if (filtersUi && filtersUi.operator) { + //@ts-ignore + body.query.group = { + operator: filtersUi.operator, + rules: filters, + }; + } + } else { + const json = validateJSON(this.getNodeParameter('filtersJson', i) as string); + body = json; + } + if (returnAll) { + responseData = await salesmateApiRequestAllItems.call(this, 'Data', 'POST', '/v2/deals/search', body, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.rows = limit; + responseData = await salesmateApiRequest.call(this, 'POST', '/v2/deals/search', body, qs); + responseData = responseData.Data.data; + } + } + if (operation === 'delete') { + const dealId = this.getNodeParameter('id', i) as string; + responseData = await salesmateApiRequest.call(this, 'DELETE', `/v1/deals/${dealId}`); + } + } if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]); } else {