diff --git a/packages/nodes-base/credentials/ZohoOAuth2Api.credentials.ts b/packages/nodes-base/credentials/ZohoOAuth2Api.credentials.ts index 53372b603b..b2c8f44b16 100644 --- a/packages/nodes-base/credentials/ZohoOAuth2Api.credentials.ts +++ b/packages/nodes-base/credentials/ZohoOAuth2Api.credentials.ts @@ -59,6 +59,22 @@ export class ZohoOAuth2Api implements ICredentialType { default: 'https://accounts.zoho.com/oauth/v2/token', required: true, }, + { + displayName: 'Region', + name: 'region', + type: 'options' as NodePropertyTypes, + default: 'europe', + options: [ + { + name: 'Europe', + value: 'europe', + }, + { + name: 'United States', + value: 'unitedStates', + }, + ], + }, { displayName: 'Scope', name: 'scope', diff --git a/packages/nodes-base/nodes/Zoho/GenericFunctions.ts b/packages/nodes-base/nodes/Zoho/GenericFunctions.ts index d21c84a9a3..882b009fef 100644 --- a/packages/nodes-base/nodes/Zoho/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Zoho/GenericFunctions.ts @@ -1,50 +1,86 @@ -import { OptionsWithUri } from 'request'; import { IExecuteFunctions, - IExecuteSingleFunctions, - ILoadOptionsFunctions, + IHookFunctions, } from 'n8n-core'; + import { - IDataObject, NodeApiError + IDataObject, + NodeApiError, + NodeOperationError, } from 'n8n-workflow'; -export async function zohoApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise { // tslint:disable-line:no-any +import { + OptionsWithUri, +} from 'request'; + +import { + flow, +} from 'lodash'; + +export async function zohoApiRequest( + this: IExecuteFunctions | IHookFunctions, + method: string, + endpoint: string, + body: IDataObject = {}, + qs: IDataObject = {}, + uri?: string, +) { + const operation = this.getNodeParameter('operation', 0) as string; + + const { region } = this.getCredentials('zohoOAuth2Api') as { region: 'europe' | 'unitedStates' }; + const tld = getTld(region); + const options: OptionsWithUri = { - headers: { - 'Content-Type': 'application/json', - }, - method, body: { data: [ body, ], }, + method, qs, - uri: uri || `https://www.zohoapis.com/crm/v2${resource}`, + uri: uri ?? `https://www.zohoapis.${tld}/crm/v2${endpoint}`, json: true, }; + + if (!Object.keys(body).length) { + delete options.body; + } + + if (!Object.keys(qs).length) { + delete options.qs; + } + try { - //@ts-ignore - return await this.helpers.requestOAuth2.call(this, 'zohoOAuth2Api', options); + console.log(JSON.stringify(options.body.data, null, 2)); + const responseData = await this.helpers.requestOAuth2.call(this, 'zohoOAuth2Api', options); + return operation === 'getAll' ? responseData : responseData.data; } catch (error) { throw new NodeApiError(this.getNode(), error); } } -export async function zohoApiRequestAllItems(this: IExecuteFunctions | ILoadOptionsFunctions, propertyName: string ,method: string, endpoint: string, body: any = {}, query: IDataObject = {}): Promise { // tslint:disable-line:no-any - +/** + * Make an authenticated API request to Zoho CRM API and return all items. + */ +export async function zohoApiRequestAllItems( + this: IHookFunctions | IExecuteFunctions, + method: string, + endpoint: string, + body: IDataObject, + qs: IDataObject, +) { const returnData: IDataObject[] = []; let responseData; let uri: string | undefined; - query.per_page = 200; - query.page = 0; + qs.per_page = 200; + qs.page = 0; do { - responseData = await zohoApiRequest.call(this, method, endpoint, body, query, uri); + responseData = await zohoApiRequest.call(this, method, endpoint, body, qs, uri); uri = responseData.info.more_records; - returnData.push.apply(returnData, responseData[propertyName]); - query.page++; + returnData.push.apply(returnData, responseData['data']); + qs.page++; } while ( responseData.info.more_records !== undefined && responseData.info.more_records === true @@ -52,3 +88,78 @@ export async function zohoApiRequestAllItems(this: IExecuteFunctions | ILoadOpti return returnData; } + +/** + * Handle a Zoho CRM API listing by returning all items or up to a limit. + */ +export async function handleListing( + this: IExecuteFunctions, + method: string, + endpoint: string, + body: IDataObject = {}, + qs: IDataObject = {}, +) { + let responseData; + + const returnAll = this.getNodeParameter('returnAll', 0); + + if (returnAll) { + return await zohoApiRequestAllItems.call(this, method, endpoint, body, qs); + } + + const limit = this.getNodeParameter('limit', 0) as number; + responseData = await zohoApiRequestAllItems.call(this, method, endpoint, body, qs); + return responseData.slice(0, limit); +} + +// ---------------------------------------- +// field adjusters +// ---------------------------------------- + +/** + * Place a location field's contents at the top level of the payload. + */ +const adjustLocationFields = (locationType: LocationType) => (allFields: IDataObject) => { + const locationField = allFields[locationType]; + if (!locationField || !hasAddressFields(locationField)) return allFields; + + return { ...omit(locationType, allFields), ...locationField.address_fields }; +}; + +const adjustAddressFields = adjustLocationFields('Address'); +const adjustBillingAddressFields = adjustLocationFields('Billing_Address'); +const adjustMailingAddressFields = adjustLocationFields('Mailing_Address'); +const adjustShippingAddressFields = adjustLocationFields('Shipping_Address'); +const adjustOtherAddressFields = adjustLocationFields('Other_Address'); + +export const adjustAccountFields = flow(adjustBillingAddressFields, adjustShippingAddressFields); +export const adjustContactFields = flow(adjustMailingAddressFields, adjustOtherAddressFields); +export const adjustInvoiceFields = flow(adjustBillingAddressFields, adjustShippingAddressFields); // TODO: product details +export const adjustLeadFields = adjustAddressFields; +export const adjustPurchaseOrderFields = adjustInvoiceFields; +export const adjustQuoteFields = adjustInvoiceFields; +export const adjustSalesOrderFields = adjustInvoiceFields; + +// ---------------------------------------- +// helpers +// ---------------------------------------- + +export const omit = (keyToOmit: string, { [keyToOmit]: _, ...omittedPropObj }) => omittedPropObj; + +function hasAddressFields(locationField: unknown): locationField is LocationField { + if (typeof locationField !== 'object' || locationField === null) return false; + return locationField.hasOwnProperty('address_fields'); +} + +const getTld = (region: 'europe' | 'unitedStates') => + ({ europe: 'eu', unitedStates: 'com' }[region]); + +// ---------------------------------------- +// types +// ---------------------------------------- + +type LocationType = 'Address' | 'Billing_Address' | 'Mailing_Address' | 'Shipping_Address' | 'Other_Address'; + +type LocationField = { + address_fields: { [key in LocationType]: string }; +}; diff --git a/packages/nodes-base/nodes/Zoho/ZohoCrm.node.ts b/packages/nodes-base/nodes/Zoho/ZohoCrm.node.ts index 2e2a36bee6..3e52b682c6 100644 --- a/packages/nodes-base/nodes/Zoho/ZohoCrm.node.ts +++ b/packages/nodes-base/nodes/Zoho/ZohoCrm.node.ts @@ -4,40 +4,54 @@ import { import { IDataObject, - ILoadOptionsFunctions, INodeExecutionData, - INodePropertyOptions, INodeType, INodeTypeDescription, } from 'n8n-workflow'; import { + adjustAccountFields, + adjustContactFields, + adjustInvoiceFields, + adjustLeadFields, + adjustPurchaseOrderFields, + adjustQuoteFields, + adjustSalesOrderFields, + handleListing, zohoApiRequest, - zohoApiRequestAllItems, } from './GenericFunctions'; import { + accountFields, + accountOperations, + contactFields, + contactOperations, + dealFields, + dealOperations, + invoiceFields, + invoiceOperations, leadFields, leadOperations, -} from './LeadDescription'; - -import { - IAddress, - ILead, -} from './LeadInterface'; + purchaseOrderFields, + purchaseOrderOperations, + quoteFields, + quoteOperations, + salesOrderFields, + salesOrderOperations, +} from './descriptions'; export class ZohoCrm implements INodeType { description: INodeTypeDescription = { - displayName: 'Zoho CRM', - name: 'zohoCrm', - icon: 'file:zohoCrm.png', - subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', - group: ['input'], + displayName: 'Zoho', + name: 'zoho', + icon: 'file:zoho.svg', + group: ['transform'], version: 1, - description: 'Consume Zoho CRM API.', + subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', + description: 'Consume the Zoho API', defaults: { - name: 'Zoho CRM', - color: '#CE2232', + name: 'Zoho', + color: '\#CE2232', }, inputs: ['main'], outputs: ['main'], @@ -53,400 +67,746 @@ export class ZohoCrm implements INodeType { name: 'resource', type: 'options', options: [ + { + name: 'Account', + value: 'account', + }, + { + name: 'Contact', + value: 'contact', + }, + { + name: 'Deal', + value: 'deal', + }, + { + name: 'Invoice', + value: 'invoice', + }, { name: 'Lead', value: 'lead', }, + { + name: 'Purchase Order', + value: 'purchaseOrder', + }, + { + name: 'Quote', + value: 'quote', + }, + { + name: 'Sales Order', + value: 'salesOrder', + }, ], - default: 'lead', - description: 'The resource to operate on.', + default: 'account', + description: 'Resource to consume', }, + ...accountOperations, + ...accountFields, + ...contactOperations, + ...contactFields, + ...dealOperations, + ...dealFields, + ...invoiceOperations, + ...invoiceFields, ...leadOperations, ...leadFields, + ...purchaseOrderOperations, + ...purchaseOrderFields, + ...quoteOperations, + ...quoteFields, + ...salesOrderOperations, + ...salesOrderFields, ], }; - methods = { - loadOptions: { - // Get all the available users to display them to user so that he can - // select them easily - async getUsers(this: ILoadOptionsFunctions): Promise { - const returnData: INodePropertyOptions[] = []; - const { users } = await zohoApiRequest.call(this, 'GET', '/users', {}, { type: 'AllUsers' }); - for (const user of users) { - const userName = `${user.first_name} ${user.last_name}`; - const userId = user.profile.id; - returnData.push({ - name: userName, - value: userId, - }); - } - return returnData; - }, - // Get all the available accounts to display them to user so that he can - // select them easily - async getAccounts(this: ILoadOptionsFunctions): Promise { - const returnData: INodePropertyOptions[] = []; - const qs: IDataObject = {}; - qs.sort_by = 'Created_Time'; - qs.sort_order = 'desc'; - const { data } = await zohoApiRequest.call(this, 'GET', '/accounts', {}, qs); - for (const account of data) { - const accountName = account.Account_Name; - const accountId = account.id; - returnData.push({ - name: accountName, - value: accountId, - }); - } - return returnData; - }, - // Get all the available lead statuses to display them to user so that he can - // select them easily - async getLeadStatuses(this: ILoadOptionsFunctions): Promise { - const returnData: INodePropertyOptions[] = []; - const qs: IDataObject = {}; - qs.module = 'leads'; - const { fields } = await zohoApiRequest.call(this, 'GET', '/settings/fields', {}, qs); - for (const field of fields) { - if (field.api_name === 'Lead_Status') { - for (const value of field.pick_list_values) { - const valueName = value.display_value; - const valueId = value.actual_value; - returnData.push({ - name: valueName, - value: valueId, - }); - return returnData; - } - } - } - return returnData; - }, - // Get all the available lead sources to display them to user so that he can - // select them easily - async getLeadSources(this: ILoadOptionsFunctions): Promise { - const returnData: INodePropertyOptions[] = []; - const qs: IDataObject = {}; - qs.module = 'leads'; - const { fields } = await zohoApiRequest.call(this, 'GET', '/settings/fields', {}, qs); - for (const field of fields) { - if (field.api_name === 'Lead_Source') { - for (const value of field.pick_list_values) { - const valueName = value.display_value; - const valueId = value.actual_value; - returnData.push({ - name: valueName, - value: valueId, - }); - return returnData; - } - } - } - return returnData; - }, - // Get all the available industries to display them to user so that he can - // select them easily - async getIndustries(this: ILoadOptionsFunctions): Promise { - const returnData: INodePropertyOptions[] = []; - const qs: IDataObject = {}; - qs.module = 'leads'; - const { fields } = await zohoApiRequest.call(this, 'GET', '/settings/fields', {}, qs); - for (const field of fields) { - if (field.api_name === 'Industry') { - for (const value of field.pick_list_values) { - const valueName = value.display_value; - const valueId = value.actual_value; - returnData.push({ - name: valueName, - value: valueId, - }); - return returnData; - } - } - } - return returnData; - }, - // Get all the available lead fields to display them to user so that he can - // select them easily - async getLeadFields(this: ILoadOptionsFunctions): Promise { - const returnData: INodePropertyOptions[] = []; - const qs: IDataObject = {}; - qs.module = 'leads'; - const { fields } = await zohoApiRequest.call(this, 'GET', '/settings/fields', {}, qs); - for (const field of fields) { - returnData.push({ - name: field.field_label, - value: field.api_name, - }); - } - return returnData; - }, - }, - }; - async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); const returnData: IDataObject[] = []; - const length = items.length as unknown as number; - const qs: IDataObject = {}; + + const resource = this.getNodeParameter('resource', 0) as string; + const operation = this.getNodeParameter('operation', 0) as string; + let responseData; - for (let i = 0; i < length; i++) { - const resource = this.getNodeParameter('resource', 0) as string; - const operation = this.getNodeParameter('operation', 0) as string; - if (resource === 'lead') { - //https://www.zoho.com/crm/developer/docs/api/insert-records.html + + for (let i = 0; i < items.length; i++) { + + // https://www.zoho.com/crm/developer/docs/api/insert-records.html + // https://www.zoho.com/crm/developer/docs/api/get-records.html + // https://www.zoho.com/crm/developer/docs/api/update-specific-record.html + // https://www.zoho.com/crm/developer/docs/api/delete-specific-record.html + + if (resource === 'account') { + + // ********************************************************************** + // account + // ********************************************************************** + + // https://www.zoho.com/crm/developer/docs/api/v2/accounts-response.html + if (operation === 'create') { - const lastName = this.getNodeParameter('lastName', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: ILead = { - Last_Name: lastName, + + // ---------------------------------------- + // account: create + // ---------------------------------------- + + const body: IDataObject = { + Account_Name: this.getNodeParameter('accountName', i), }; - if (additionalFields.owner) { - body.Lead_Owner = additionalFields.owner as string; - } - if (additionalFields.company) { - body.Company = additionalFields.company as string; - } - if (additionalFields.firstName) { - body.First_Name = additionalFields.firstName as string; - } - if (additionalFields.email) { - body.Email = additionalFields.email as string; - } - if (additionalFields.title) { - body.Designation = additionalFields.title as string; - } - if (additionalFields.phone) { - body.Phone = additionalFields.phone as string; - } - if (additionalFields.mobile) { - body.Mobile = additionalFields.mobile as string; - } - if (additionalFields.leadStatus) { - body.Lead_Status = additionalFields.leadStatus as string; - } - if (additionalFields.fax) { - body.Fax = additionalFields.fax as string; - } - if (additionalFields.website) { - body.Website = additionalFields.website as string; - } - if (additionalFields.leadSource) { - body.Lead_Source = additionalFields.leadSource as string; - } - if (additionalFields.industry) { - body.Industry = additionalFields.industry as string; - } - if (additionalFields.numberOfEmployees) { - body.No_of_Employees = additionalFields.numberOfEmployees as number; - } - if (additionalFields.annualRevenue) { - body.Annual_Revenue = additionalFields.annualRevenue as number; - } - if (additionalFields.emailOptOut) { - body.Email_Opt_Out = additionalFields.emailOptOut as boolean; - } - if (additionalFields.skypeId) { - body.Skype_ID = additionalFields.skypeId as string; - } - if (additionalFields.salutation) { - body.Salutation = additionalFields.salutation as string; - } - if (additionalFields.secondaryEmail) { - body.Secondary_Email = additionalFields.secondaryEmail as string; - } - if (additionalFields.twitter) { - body.Twitter = additionalFields.twitter as string; - } - if (additionalFields.isRecordDuplicate) { - body.Is_Record_Duplicate = additionalFields.isRecordDuplicate as boolean; - } - if (additionalFields.description) { - body.Description = additionalFields.description as string; - } - const address = (this.getNodeParameter('addressUi', i) as IDataObject).addressValues as IAddress; - if (address) { - if (address.country) { - body.Country = address.country as string; - } - if (address.city) { - body.City = address.city as string; - } - if (address.state) { - body.State = address.state as string; - } - if (address.street) { - body.Street = address.street as string; - } - if (address.zipCode) { - body.Zip_Code = address.zipCode as string; - } - } - responseData = await zohoApiRequest.call(this, 'POST', '/leads', body); - responseData = responseData.data; - if (responseData.length) { - responseData = responseData[0].details; - } - } - //https://www.zoho.com/crm/developer/docs/api/update-specific-record.html - if (operation === 'update') { - const leadId = this.getNodeParameter('leadId', i) as string; const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: ILead = {}; - if (additionalFields.lastName) { - body.Last_Name = additionalFields.lastName as string; - } - if (additionalFields.owner) { - body.Lead_Owner = additionalFields.owner as string; - } - if (additionalFields.company) { - body.Company = additionalFields.company as string; - } - if (additionalFields.firstName) { - body.First_Name = additionalFields.firstName as string; - } - if (additionalFields.email) { - body.Email = additionalFields.email as string; - } - if (additionalFields.title) { - body.Designation = additionalFields.title as string; - } - if (additionalFields.phone) { - body.Phone = additionalFields.phone as string; - } - if (additionalFields.mobile) { - body.Mobile = additionalFields.mobile as string; - } - if (additionalFields.leadStatus) { - body.Lead_Status = additionalFields.leadStatus as string; - } - if (additionalFields.fax) { - body.Fax = additionalFields.fax as string; - } - if (additionalFields.website) { - body.Website = additionalFields.website as string; - } - if (additionalFields.leadSource) { - body.Lead_Source = additionalFields.leadSource as string; - } - if (additionalFields.industry) { - body.Industry = additionalFields.industry as string; - } - if (additionalFields.numberOfEmployees) { - body.No_of_Employees = additionalFields.numberOfEmployees as number; - } - if (additionalFields.annualRevenue) { - body.Annual_Revenue = additionalFields.annualRevenue as number; - } - if (additionalFields.emailOptOut) { - body.Email_Opt_Out = additionalFields.emailOptOut as boolean; - } - if (additionalFields.skypeId) { - body.Skype_ID = additionalFields.skypeId as string; - } - if (additionalFields.salutation) { - body.Salutation = additionalFields.salutation as string; - } - if (additionalFields.secondaryEmail) { - body.Secondary_Email = additionalFields.secondaryEmail as string; - } - if (additionalFields.twitter) { - body.Twitter = additionalFields.twitter as string; - } - if (additionalFields.isRecordDuplicate) { - body.Is_Record_Duplicate = additionalFields.isRecordDuplicate as boolean; - } - if (additionalFields.description) { - body.Description = additionalFields.description as string; - } - const address = (this.getNodeParameter('addressUi', i) as IDataObject).addressValues as IAddress; - if (address) { - if (address.country) { - body.Country = address.country as string; - } - if (address.city) { - body.City = address.city as string; - } - if (address.state) { - body.State = address.state as string; - } - if (address.street) { - body.Street = address.street as string; - } - if (address.zipCode) { - body.Zip_Code = address.zipCode as string; - } - } - responseData = await zohoApiRequest.call(this, 'PUT', `/leads/${leadId}`, body); - responseData = responseData.data; - if (responseData.length) { - responseData = responseData[0].details; - } - } - //https://www.zoho.com/crm/developer/docs/api/update-specific-record.html - if (operation === 'get') { - const leadId = this.getNodeParameter('leadId', i) as string; - responseData = await zohoApiRequest.call(this, 'GET', `/leads/${leadId}`); - if (responseData !== undefined) { - responseData = responseData.data; + if (Object.keys(additionalFields).length) { + Object.assign(body, adjustAccountFields(additionalFields)); } + responseData = await zohoApiRequest.call(this, 'POST', '/accounts', body); + + } else if (operation === 'delete') { + + // ---------------------------------------- + // account: delete + // ---------------------------------------- + + const accountId = this.getNodeParameter('accountId', i); + + const endpoint = `/accounts/${accountId}`; + responseData = await zohoApiRequest.call(this, 'DELETE', endpoint); + + } else if (operation === 'get') { + + // ---------------------------------------- + // account: get + // ---------------------------------------- + + const accountId = this.getNodeParameter('accountId', i); + + const endpoint = `/accounts/${accountId}`; + responseData = await zohoApiRequest.call(this, 'GET', endpoint); + + } else if (operation === 'getAll') { + + // ---------------------------------------- + // account: getAll + // ---------------------------------------- + + const body: IDataObject = {}; + const filters = this.getNodeParameter('filters', i) as IDataObject; + + if (Object.keys(filters).length) { + Object.assign(body, filters); + } + + responseData = await handleListing.call(this, 'GET', '/accounts', body); + + } else if (operation === 'update') { + + // ---------------------------------------- + // account: update + // ---------------------------------------- + + const body: IDataObject = {}; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (Object.keys(updateFields).length) { + Object.assign(body, adjustAccountFields(updateFields)); + } + + const accountId = this.getNodeParameter('accountId', i); + + const endpoint = `/accounts/${accountId}`; + responseData = await zohoApiRequest.call(this, 'PUT', endpoint, body); + } - //https://www.zoho.com/crm/developer/docs/api/get-records.html - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.fields) { - qs.fields = (options.fields as string[]).join(','); + + } else if (resource === 'contact') { + + // ********************************************************************** + // contact + // ********************************************************************** + + // https://www.zoho.com/crm/developer/docs/api/v2/contacts-response.html + + if (operation === 'create') { + + // ---------------------------------------- + // contact: create + // ---------------------------------------- + + const body: IDataObject = { + Last_Name: this.getNodeParameter('Last_Name', i), + }; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (Object.keys(additionalFields).length) { + Object.assign(body, adjustContactFields(additionalFields)); } - if (options.approved) { - qs.approved = options.approved as boolean; + + responseData = await zohoApiRequest.call(this, 'POST', '/contacts', body); + + } else if (operation === 'delete') { + + // ---------------------------------------- + // contact: delete + // ---------------------------------------- + + const contactId = this.getNodeParameter('contactId', i); + + const endpoint = `/contacts/${contactId}`; + responseData = await zohoApiRequest.call(this, 'DELETE', endpoint); + + } else if (operation === 'get') { + + // ---------------------------------------- + // contact: get + // ---------------------------------------- + + const contactId = this.getNodeParameter('contactId', i); + + const endpoint = `/contacts/${contactId}`; + responseData = await zohoApiRequest.call(this, 'GET', endpoint); + + } else if (operation === 'getAll') { + + // ---------------------------------------- + // contact: getAll + // ---------------------------------------- + + const body: IDataObject = {}; + const filters = this.getNodeParameter('filters', i) as IDataObject; + + if (Object.keys(filters).length) { + Object.assign(body, filters); } - if (options.converted) { - qs.converted = options.converted as boolean; - } - if (options.includeChild) { - qs.include_child = options.includeChild as boolean; - } - if (options.sortOrder) { - qs.sort_order = options.sortOrder as string; - } - if (options.sortBy) { - qs.sort_by = options.sortBy as string; - } - if (options.territoryId) { - qs.territory_id = options.territoryId as string; - } - if (returnAll) { - responseData = await zohoApiRequestAllItems.call(this, 'data', 'GET', '/leads', {}, qs); - } else { - qs.per_page = this.getNodeParameter('limit', i) as number; - responseData = await zohoApiRequest.call(this, 'GET', '/leads', {}, qs); - responseData = responseData.data; + + responseData = await handleListing.call(this, 'GET', '/contacts', body); + + } else if (operation === 'update') { + + // ---------------------------------------- + // contact: update + // ---------------------------------------- + + const body: IDataObject = {}; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (Object.keys(updateFields).length) { + Object.assign(body, adjustContactFields(updateFields)); } + + const contactId = this.getNodeParameter('contactId', i); + + const endpoint = `/contacts/${contactId}`; + responseData = await zohoApiRequest.call(this, 'PUT', endpoint, body); + } - //https://www.zoho.com/crm/developer/docs/api/delete-specific-record.html - if (operation === 'delete') { - const leadId = this.getNodeParameter('leadId', i) as string; + + } else if (resource === 'deal') { + + // ********************************************************************** + // deal + // ********************************************************************** + + // https://www.zoho.com/crm/developer/docs/api/v2/deals-response.html + + if (operation === 'create') { + + // ---------------------------------------- + // deal: create + // ---------------------------------------- + + const body: IDataObject = { + Deal_Name: this.getNodeParameter('Deal_Name', i), + Stage: this.getNodeParameter('Stage', i), + }; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (Object.keys(additionalFields).length) { + Object.assign(body, additionalFields); + } + + responseData = await zohoApiRequest.call(this, 'POST', '/deals', body); + + } else if (operation === 'delete') { + + // ---------------------------------------- + // deal: delete + // ---------------------------------------- + + const dealId = this.getNodeParameter('dealId', i); + + responseData = await zohoApiRequest.call(this, 'DELETE', `/deals/${dealId}`); + + } else if (operation === 'get') { + + // ---------------------------------------- + // deal: get + // ---------------------------------------- + + const dealId = this.getNodeParameter('dealId', i); + + responseData = await zohoApiRequest.call(this, 'GET', `/deals/${dealId}`); + + } else if (operation === 'getAll') { + + // ---------------------------------------- + // deal: getAll + // ---------------------------------------- + + const body: IDataObject = {}; + const filters = this.getNodeParameter('filters', i) as IDataObject; + + if (Object.keys(filters).length) { + Object.assign(body, filters); + } + + responseData = await handleListing.call(this, 'GET', '/deals', body); + + } else if (operation === 'update') { + + // ---------------------------------------- + // deal: update + // ---------------------------------------- + + const body: IDataObject = {}; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (Object.keys(updateFields).length) { + Object.assign(body, updateFields); + } + + const dealId = this.getNodeParameter('dealId', i); + + responseData = await zohoApiRequest.call(this, 'PUT', `/deals/${dealId}`, body); + + } + + } else if (resource === 'invoice') { + + // ********************************************************************** + // invoice + // ********************************************************************** + + // https://www.zoho.com/crm/developer/docs/api/v2/invoices-response.html + + if (operation === 'create') { + + // ---------------------------------------- + // invoice: create + // ---------------------------------------- + + const body: IDataObject = { + Product_Details: this.getNodeParameter('Product_Details', i), + Subject: this.getNodeParameter('Subject', i), + }; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (Object.keys(additionalFields).length) { + Object.assign(body, adjustInvoiceFields(additionalFields)); + } + + responseData = await zohoApiRequest.call(this, 'POST', '/invoices', body); + + } else if (operation === 'delete') { + + // ---------------------------------------- + // invoice: delete + // ---------------------------------------- + + const invoiceId = this.getNodeParameter('invoiceId', i); + + const endpoint = `/invoices/${invoiceId}`; + responseData = await zohoApiRequest.call(this, 'DELETE', endpoint); + + } else if (operation === 'get') { + + // ---------------------------------------- + // invoice: get + // ---------------------------------------- + + const invoiceId = this.getNodeParameter('invoiceId', i); + + const endpoint = `/invoices/${invoiceId}`; + responseData = await zohoApiRequest.call(this, 'GET', endpoint); + + } else if (operation === 'getAll') { + + // ---------------------------------------- + // invoice: getAll + // ---------------------------------------- + + const body: IDataObject = {}; + const filters = this.getNodeParameter('filters', i) as IDataObject; + + if (Object.keys(filters).length) { + Object.assign(body, filters); + } + + responseData = await handleListing.call(this, 'GET', '/invoices', body); + + } else if (operation === 'update') { + + // ---------------------------------------- + // invoice: update + // ---------------------------------------- + + const body: IDataObject = {}; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (Object.keys(updateFields).length) { + Object.assign(body, adjustInvoiceFields(updateFields)); + } + + const invoiceId = this.getNodeParameter('invoiceId', i); + + const endpoint = `/invoices/${invoiceId}`; + responseData = await zohoApiRequest.call(this, 'PUT', endpoint, body); + + } + + } else if (resource === 'lead') { + + // ********************************************************************** + // lead + // ********************************************************************** + + // https://www.zoho.com/crm/developer/docs/api/v2/leads-response.html + + if (operation === 'create') { + + // ---------------------------------------- + // lead: create + // ---------------------------------------- + + const body: IDataObject = { + Company: this.getNodeParameter('Company', i), + Last_Name: this.getNodeParameter('Last_Name', i), + }; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (Object.keys(additionalFields).length) { + Object.assign(body, adjustLeadFields(additionalFields)); + } + + responseData = await zohoApiRequest.call(this, 'POST', '/leads', body); + + } else if (operation === 'delete') { + + // ---------------------------------------- + // lead: delete + // ---------------------------------------- + + const leadId = this.getNodeParameter('leadId', i); + responseData = await zohoApiRequest.call(this, 'DELETE', `/leads/${leadId}`); - responseData = responseData.data; + + } else if (operation === 'get') { + + // ---------------------------------------- + // lead: get + // ---------------------------------------- + + const leadId = this.getNodeParameter('leadId', i); + + responseData = await zohoApiRequest.call(this, 'GET', `/leads/${leadId}`); + + } else if (operation === 'getAll') { + + // ---------------------------------------- + // lead: getAll + // ---------------------------------------- + + const body: IDataObject = {}; + const filters = this.getNodeParameter('filters', i) as IDataObject; + + if (Object.keys(filters).length) { + Object.assign(body, filters); + } + + responseData = await handleListing.call(this, 'GET', '/leads', body); + + } else if (operation === 'update') { + + // ---------------------------------------- + // lead: update + // ---------------------------------------- + + const body: IDataObject = {}; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (Object.keys(updateFields).length) { + Object.assign(body, adjustLeadFields(updateFields)); + } + + const leadId = this.getNodeParameter('leadId', i); + + responseData = await zohoApiRequest.call(this, 'PUT', `/leads/${leadId}`, body); + } - //https://www.zoho.com/crm/developer/docs/api/field-meta.html - if (operation === 'getFields') { - qs.module = 'leads'; - responseData = await zohoApiRequest.call(this, 'GET', '/settings/fields', {}, qs); - responseData = responseData.fields; + + } else if (resource === 'purchaseOrder') { + + // ********************************************************************** + // purchaseOrder + // ********************************************************************** + + // https://www.zoho.com/crm/developer/docs/api/v2/purchase-orders-response.html + + if (operation === 'create') { + + // ---------------------------------------- + // purchaseOrder: create + // ---------------------------------------- + + const body: IDataObject = { + Subject: this.getNodeParameter('Subject', i), + Vendor_Name: this.getNodeParameter('Vendor_Name', i), + }; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (Object.keys(additionalFields).length) { + Object.assign(body, adjustPurchaseOrderFields(additionalFields)); + } + + responseData = await zohoApiRequest.call(this, 'POST', '/purchaseorders', body); + + } else if (operation === 'delete') { + + // ---------------------------------------- + // purchaseOrder: delete + // ---------------------------------------- + + const purchaseOrderId = this.getNodeParameter('purchaseOrderId', i); + + const endpoint = `/purchaseorders/${purchaseOrderId}`; + responseData = await zohoApiRequest.call(this, 'DELETE', endpoint); + + } else if (operation === 'get') { + + // ---------------------------------------- + // purchaseOrder: get + // ---------------------------------------- + + const purchaseOrderId = this.getNodeParameter('purchaseOrderId', i); + + const endpoint = `/purchaseorders/${purchaseOrderId}`; + responseData = await zohoApiRequest.call(this, 'GET', endpoint); + + } else if (operation === 'getAll') { + + // ---------------------------------------- + // purchaseOrder: getAll + // ---------------------------------------- + + const body: IDataObject = {}; + const filters = this.getNodeParameter('filters', i) as IDataObject; + + if (Object.keys(filters).length) { + Object.assign(body, filters); + } + + responseData = await handleListing.call(this, 'GET', '/purchaseorders', body); + + } else if (operation === 'update') { + + // ---------------------------------------- + // purchaseOrder: update + // ---------------------------------------- + + const body: IDataObject = {}; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (Object.keys(updateFields).length) { + Object.assign(body, adjustPurchaseOrderFields(updateFields)); + } + + const purchaseOrderId = this.getNodeParameter('purchaseOrderId', i); + + const endpoint = `/purchaseorders/${purchaseOrderId}`; + responseData = await zohoApiRequest.call(this, 'PUT', endpoint, body); + } + + } else if (resource === 'quote') { + + // ********************************************************************** + // quote + // ********************************************************************** + + // https://www.zoho.com/crm/developer/docs/api/v2/quotes-response.html + + if (operation === 'create') { + + // ---------------------------------------- + // quote: create + // ---------------------------------------- + + const body: IDataObject = { + Product_Details: this.getNodeParameter('Product_Details', i), + Subject: this.getNodeParameter('Subject', i), + }; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (Object.keys(additionalFields).length) { + Object.assign(body, adjustQuoteFields(additionalFields)); + } + + responseData = await zohoApiRequest.call(this, 'POST', '/quotes', body); + + } else if (operation === 'delete') { + + // ---------------------------------------- + // quote: delete + // ---------------------------------------- + + const quoteId = this.getNodeParameter('quoteId', i); + + responseData = await zohoApiRequest.call(this, 'DELETE', `/quotes/${quoteId}`); + + } else if (operation === 'get') { + + // ---------------------------------------- + // quote: get + // ---------------------------------------- + + const quoteId = this.getNodeParameter('quoteId', i); + + responseData = await zohoApiRequest.call(this, 'GET', `/quotes/${quoteId}`); + + } else if (operation === 'getAll') { + + // ---------------------------------------- + // quote: getAll + // ---------------------------------------- + + const body: IDataObject = {}; + const filters = this.getNodeParameter('filters', i) as IDataObject; + + if (Object.keys(filters).length) { + Object.assign(body, filters); + } + + responseData = await handleListing.call(this, 'GET', '/quotes', body); + + } else if (operation === 'update') { + + // ---------------------------------------- + // quote: update + // ---------------------------------------- + + const body: IDataObject = {}; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (Object.keys(updateFields).length) { + Object.assign(body, adjustQuoteFields(updateFields)); + } + + const quoteId = this.getNodeParameter('quoteId', i); + + responseData = await zohoApiRequest.call(this, 'PUT', `/quotes/${quoteId}`, body); + + } + + } else if (resource === 'salesOrder') { + + // ********************************************************************** + // salesOrder + // ********************************************************************** + + // https://www.zoho.com/crm/developer/docs/api/v2/sales-orders-response.html + + if (operation === 'create') { + + // ---------------------------------------- + // salesOrder: create + // ---------------------------------------- + + const body: IDataObject = { + Account_Name: this.getNodeParameter('Account_Name', i), + Subject: this.getNodeParameter('Subject', i), + }; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (Object.keys(additionalFields).length) { + Object.assign(body, adjustSalesOrderFields(additionalFields)); + } + + responseData = await zohoApiRequest.call(this, 'POST', '/salesorders', body); + + } else if (operation === 'delete') { + + // ---------------------------------------- + // salesOrder: delete + // ---------------------------------------- + + const salesOrderId = this.getNodeParameter('salesOrderId', i); + + const endpoint = `/salesorders/${salesOrderId}`; + responseData = await zohoApiRequest.call(this, 'DELETE', endpoint); + + } else if (operation === 'get') { + + // ---------------------------------------- + // salesOrder: get + // ---------------------------------------- + + const salesOrderId = this.getNodeParameter('salesOrderId', i); + + const endpoint = `/salesorders/${salesOrderId}`; + responseData = await zohoApiRequest.call(this, 'GET', endpoint); + + } else if (operation === 'getAll') { + + // ---------------------------------------- + // salesOrder: getAll + // ---------------------------------------- + + const body: IDataObject = {}; + const filters = this.getNodeParameter('filters', i) as IDataObject; + + if (Object.keys(filters).length) { + Object.assign(body, filters); + } + + responseData = await handleListing.call(this, 'GET', '/salesorders', body); + + } else if (operation === 'update') { + + // ---------------------------------------- + // salesOrder: update + // ---------------------------------------- + + const body: IDataObject = {}; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (Object.keys(updateFields).length) { + Object.assign(body, adjustSalesOrderFields(updateFields)); + } + + const salesOrderId = this.getNodeParameter('salesOrderId', i); + + const endpoint = `/salesorders/${salesOrderId}`; + responseData = await zohoApiRequest.call(this, 'PUT', endpoint, body); + + } + } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + + Array.isArray(responseData) + ? returnData.push(...responseData) + : returnData.push(responseData); + } + return [this.helpers.returnJsonArray(returnData)]; } } diff --git a/packages/nodes-base/nodes/Zoho/descriptions/AccountDescription.ts b/packages/nodes-base/nodes/Zoho/descriptions/AccountDescription.ts new file mode 100644 index 0000000000..51bb018675 --- /dev/null +++ b/packages/nodes-base/nodes/Zoho/descriptions/AccountDescription.ts @@ -0,0 +1,366 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +import { + billingAddress, + makeGetAllFields, + shippingAddress, +} from './SharedFields'; + +export const accountOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'account', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + }, + { + name: 'Delete', + value: 'delete', + }, + { + name: 'Get', + value: 'get', + }, + { + name: 'Get All', + value: 'getAll', + }, + { + name: 'Update', + value: 'update', + }, + ], + default: 'create', + description: 'Operation to perform', + }, +] as INodeProperties[]; + +export const accountFields = [ + // ---------------------------------------- + // account: create + // ---------------------------------------- + { + displayName: 'Account Name', + name: 'accountName', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'account', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'account', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Account Number', + name: 'Account_Number', + type: 'string', + default: '', + }, + { + displayName: 'Account Site', + name: 'Account_Site', + type: 'string', + default: '', + description: 'Name of the account’s location, e.g. Headquarters or London.', + }, + { + displayName: 'Account Type', + name: 'Account_Type', + type: 'string', + default: '', + }, + { + displayName: 'Annual Revenue', + name: 'Annual_Revenue', + type: 'string', + default: '', + }, + billingAddress, + { + displayName: 'Contact Details', + name: 'Contact_Details', + type: 'string', + default: '', + }, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Employees', + name: 'Employees', + type: 'number', + default: '', + description: 'Number of employees in the account’s company.', + }, + { + displayName: 'Exchange Rate', + name: 'Exchange_Rate', + type: 'string', + default: '', + description: 'Exchange rate of the default currency to the home currency.', + }, + { + displayName: 'Fax', + name: 'Fax', + type: 'string', + default: '', + }, + { + displayName: 'Industry', + name: 'Industry', + type: 'string', + default: '', + }, + { + displayName: 'Phone', + name: 'Phone', + type: 'string', + default: '', + }, + shippingAddress, + { + displayName: 'Ticker Symbol', + name: 'Ticker_Symbol', + type: 'string', + default: '', + }, + { + displayName: 'Website', + name: 'Website', + type: 'string', + default: '', + }, + ], + }, + + // ---------------------------------------- + // account: delete + // ---------------------------------------- + { + displayName: 'Account ID', + name: 'accountId', + description: 'ID of the account to delete.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'account', + ], + operation: [ + 'delete', + ], + }, + }, + }, + + // ---------------------------------------- + // account: get + // ---------------------------------------- + { + displayName: 'Account ID', + name: 'accountId', + description: 'ID of the account to retrieve.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'account', + ], + operation: [ + 'get', + ], + }, + }, + }, + + // ---------------------------------------- + // account: getAll + // ---------------------------------------- + ...makeGetAllFields('account'), + + // ---------------------------------------- + // account: update + // ---------------------------------------- + { + displayName: 'Account ID', + name: 'accountId', + description: 'ID of the account to update.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'account', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'account', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + { + displayName: 'Account Name', + name: 'Account_Name', + type: 'string', + default: '', + }, + { + displayName: 'Account Number', + name: 'Account_Number', + type: 'string', + default: '', + }, + { + displayName: 'Account Site', + name: 'Account_Site', + type: 'string', + default: '', + description: 'Name of the account’s location, e.g. Headquarters or London.', + }, + { + displayName: 'Account Type', + name: 'Account_Type', + type: 'string', + default: '', + }, + { + displayName: 'Annual Revenue', + name: 'Annual_Revenue', + type: 'string', + default: '', + }, + billingAddress, + { + displayName: 'Contact Details', + name: 'Contact_Details', + type: 'string', + default: '', + }, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Employees', + name: 'Employees', + type: 'number', + default: '', + description: 'Number of employees in the account’s company.', + }, + { + displayName: 'Exchange Rate', + name: 'Exchange_Rate', + type: 'string', + default: '', + description: 'Exchange rate of the default currency to the home currency.', + }, + { + displayName: 'Fax', + name: 'Fax', + type: 'string', + default: '', + }, + { + displayName: 'Industry', + name: 'Industry', + type: 'string', + default: '', + }, + { + displayName: 'Phone', + name: 'Phone', + type: 'string', + default: '', + }, + shippingAddress, + { + displayName: 'Ticker Symbol', + name: 'Ticker_Symbol', + type: 'string', + default: '', + }, + { + displayName: 'Website', + name: 'Website', + type: 'string', + default: '', + }, + ], + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Zoho/descriptions/ContactDescription.ts b/packages/nodes-base/nodes/Zoho/descriptions/ContactDescription.ts new file mode 100644 index 0000000000..692aa06b20 --- /dev/null +++ b/packages/nodes-base/nodes/Zoho/descriptions/ContactDescription.ts @@ -0,0 +1,426 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +import { + mailingAddress, + makeGetAllFields, + otherAddress, +} from './SharedFields'; + +export const contactOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'contact', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + }, + { + name: 'Delete', + value: 'delete', + }, + { + name: 'Get', + value: 'get', + }, + { + name: 'Get All', + value: 'getAll', + }, + { + name: 'Update', + value: 'update', + }, + ], + default: 'create', + description: 'Operation to perform', + }, +] as INodeProperties[]; + +export const contactFields = [ + // ---------------------------------------- + // contact: create + // ---------------------------------------- + { + displayName: 'Last Name', + name: 'lastName', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Assistant', + name: 'Assistant', + type: 'string', + default: '', + description: 'Name of the contact’s assistant.', + }, + { + displayName: 'Assistant’s Phone', + name: 'Asst_Phone', + type: 'string', + default: '', + description: 'Phone number of the contact’s assistant.', + }, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Date of Birth', + name: 'Date_of_Birth', + type: 'string', + default: '', + }, + { + displayName: 'Department', + name: 'Department', + type: 'string', + default: '', + description: 'Company department to which the contact belongs.', + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Email', + name: 'Email', + type: 'string', + default: '', + }, + { + displayName: 'Fax', + name: 'Fax', + type: 'string', + default: '', + }, + { + displayName: 'First Name', + name: 'First_Name', + type: 'string', + default: '', + }, + { + displayName: 'Full Name', + name: 'Full_Name', + type: 'string', + default: '', + }, + { + displayName: 'Home Phone', + name: 'Home_Phone', + type: 'string', + default: '', + }, + mailingAddress, + { + displayName: 'Mobile', + name: 'Mobile', + type: 'string', + default: '', + }, + otherAddress, + { + displayName: 'Other Phone', + name: 'Other_Phone', + type: 'string', + default: '', + }, + { + displayName: 'Phone', + name: 'Phone', + type: 'string', + default: '', + }, + { + displayName: 'Salutation', + name: 'Salutation', + type: 'string', + default: '', + }, + { + displayName: 'Secondary Email', + name: 'Secondary_Email', + type: 'string', + default: '', + }, + { + displayName: 'Skype ID', + name: 'Skype_ID', + type: 'string', + default: '', + }, + { + displayName: 'Title', + name: 'Title', + type: 'string', + default: '', + description: 'Position of the contact at their company.', + }, + { + displayName: 'Twitter', + name: 'Twitter', + type: 'string', + default: '', + }, + ], + }, + + // ---------------------------------------- + // contact: delete + // ---------------------------------------- + { + displayName: 'Contact ID', + name: 'contactId', + description: 'ID of the contact to delete.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'delete', + ], + }, + }, + }, + + // ---------------------------------------- + // contact: get + // ---------------------------------------- + { + displayName: 'Contact ID', + name: 'contactId', + description: 'ID of the contact to retrieve.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'get', + ], + }, + }, + }, + + // ---------------------------------------- + // contact: getAll + // ---------------------------------------- + ...makeGetAllFields('contact'), + + // ---------------------------------------- + // contact: update + // ---------------------------------------- + { + displayName: 'Contact ID', + name: 'contactId', + description: 'ID of the contact to update.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + { + displayName: 'Assistant', + name: 'Assistant', + type: 'string', + default: '', + }, + { + displayName: 'Assistant’s Phone', + name: 'Asst_Phone', + type: 'string', + default: '', + description: 'Phone number of the contact’s assistant.', + }, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Date of Birth', + name: 'Date_of_Birth', + type: 'string', + default: '', + }, + { + displayName: 'Department', + name: 'Department', + type: 'string', + default: '', + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Email', + name: 'Email', + type: 'string', + default: '', + }, + { + displayName: 'Fax', + name: 'Fax', + type: 'string', + default: '', + }, + { + displayName: 'First Name', + name: 'First_Name', + type: 'string', + default: '', + }, + { + displayName: 'Full Name', + name: 'Full_Name', + type: 'string', + default: '', + }, + { + displayName: 'Home Phone', + name: 'Home_Phone', + type: 'string', + default: '', + }, + { + displayName: 'Last Name', + name: 'Last_Name', + type: 'string', + default: '', + }, + mailingAddress, + { + displayName: 'Mobile', + name: 'Mobile', + type: 'string', + default: '', + }, + otherAddress, + { + displayName: 'Other Phone', + name: 'Other_Phone', + type: 'string', + default: '', + }, + { + displayName: 'Phone', + name: 'Phone', + type: 'string', + default: '', + }, + { + displayName: 'Salutation', + name: 'Salutation', + type: 'string', + default: '', + }, + { + displayName: 'Secondary Email', + name: 'Secondary_Email', + type: 'string', + default: '', + }, + { + displayName: 'Skype ID', + name: 'Skype_ID', + type: 'string', + default: '', + }, + { + displayName: 'Title', + name: 'Title', + type: 'string', + default: '', + description: 'Position of the contact at their company.', + }, + { + displayName: 'Twitter', + name: 'Twitter', + type: 'string', + default: '', + }, + ], + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Zoho/descriptions/DealDescription.ts b/packages/nodes-base/nodes/Zoho/descriptions/DealDescription.ts new file mode 100644 index 0000000000..5c5ed6dab9 --- /dev/null +++ b/packages/nodes-base/nodes/Zoho/descriptions/DealDescription.ts @@ -0,0 +1,329 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +import { + makeGetAllFields, +} from './SharedFields'; + +export const dealOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'deal', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + }, + { + name: 'Delete', + value: 'delete', + }, + { + name: 'Get', + value: 'get', + }, + { + name: 'Get All', + value: 'getAll', + }, + { + name: 'Update', + value: 'update', + }, + ], + default: 'create', + description: 'Operation to perform', + }, +] as INodeProperties[]; + +export const dealFields = [ + // ---------------------------------------- + // deal: create + // ---------------------------------------- + { + displayName: 'Deal Name', + name: 'dealName', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Stage', + name: 'stage', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Amount', + name: 'Amount', + type: 'number', + default: '', + description: 'Monetary amount of the deal.', + }, + { + displayName: 'Closing Date', + name: 'Closing_Date', + type: 'string', + default: '', + }, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Lead Conversion Time', + name: 'Lead_Conversion_Time', + type: 'number', + default: '', + description: 'Averge number of days to convert the lead into a deal.', + }, + { + displayName: 'Next Step', + name: 'Next_Step', + type: 'string', + default: '', + description: 'Description of the next step in the sales process.', + }, + { + displayName: 'Overall Sales Duration', + name: 'Overall_Sales_Duration', + type: 'number', + default: '', + description: 'Averge number of days to convert the lead into a deal and to win the deal.', + }, + { + displayName: 'Probability', + name: 'Probability', + type: 'string', + default: '', + description: 'Probability of deal closure.', + }, + { + displayName: 'Sales Cycle Duration', + name: 'Sales_Cycle_Duration', + type: 'string', + default: '', + description: 'Averge number of days for the deal to be won.', + }, + ], + }, + + // ---------------------------------------- + // deal: delete + // ---------------------------------------- + { + displayName: 'Deal ID', + name: 'dealId', + description: 'ID of the deal to delete.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'delete', + ], + }, + }, + }, + + // ---------------------------------------- + // deal: get + // ---------------------------------------- + { + displayName: 'Deal ID', + name: 'dealId', + description: 'ID of the deal to retrieve.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'get', + ], + }, + }, + }, + + // ---------------------------------------- + // deal: getAll + // ---------------------------------------- + ...makeGetAllFields('deal'), + + // ---------------------------------------- + // deal: update + // ---------------------------------------- + { + displayName: 'Deal ID', + name: 'dealId', + description: 'ID of the deal to update.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + { + displayName: 'Amount', + name: 'Amount', + type: 'number', + default: '', + description: 'Monetary amount of the deal.', + }, + { + displayName: 'Closing Date', + name: 'Closing_Date', + type: 'string', + default: '', + }, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Deal Name', + name: 'Deal_Name', + type: 'string', + default: '', + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Lead Conversion Time', + name: 'Lead_Conversion_Time', + type: 'number', + default: '', + description: 'Averge number of days to convert the lead into a deal.', + }, + { + displayName: 'Next Step', + name: 'Next_Step', + type: 'string', + default: '', + description: 'Description of the next step in the sales process.', + }, + { + displayName: 'Overall Sales Duration', + name: 'Overall_Sales_Duration', + type: 'number', + default: '', + description: 'Averge number of days to convert the lead into a deal and to win the deal.', + }, + { + displayName: 'Probability', + name: 'Probability', + type: 'string', + default: '', + description: 'Probability of deal closure.', + }, + { + displayName: 'Sales Cycle Duration', + name: 'Sales_Cycle_Duration', + type: 'string', + default: '', + description: 'Averge number of days to win the deal.', + }, + { + displayName: 'Stage', + name: 'Stage', + type: 'string', + default: '', + }, + ], + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Zoho/descriptions/InvoiceDescription.ts b/packages/nodes-base/nodes/Zoho/descriptions/InvoiceDescription.ts new file mode 100644 index 0000000000..b058c3b8e0 --- /dev/null +++ b/packages/nodes-base/nodes/Zoho/descriptions/InvoiceDescription.ts @@ -0,0 +1,425 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +import { + billingAddress, + makeGetAllFields, + productDetails, + shippingAddress, +} from './SharedFields'; + +export const invoiceOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'invoice', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + }, + { + name: 'Delete', + value: 'delete', + }, + { + name: 'Get', + value: 'get', + }, + { + name: 'Get All', + value: 'getAll', + }, + { + name: 'Update', + value: 'update', + }, + ], + default: 'create', + description: 'Operation to perform', + }, +] as INodeProperties[]; + +export const invoiceFields = [ + // ---------------------------------------- + // invoice: create + // ---------------------------------------- + { + displayName: 'Product Details', + name: 'productDetails', + type: '', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'invoice', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Subject', + name: 'subject', + description: 'Subject or title of the invoice.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'invoice', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'invoice', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Account Name', + name: 'Account_Name', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Account Name Field', + options: [ + { + displayName: 'Account Name Fields', + name: 'account_name_fields', + values: [ + { + displayName: 'ID', + name: 'id', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Adjustment', + name: 'Adjustment', + type: 'number', + default: '', + description: 'Adjustment in the grand total, if any.', + }, + billingAddress, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Due Date', + name: 'Due_Date', + type: 'string', + default: '', + }, + { + displayName: 'Exchange Rate', + name: 'Exchange_Rate', + type: 'string', + default: '', + description: 'Exchange rate of the default currency to the home currency.', + }, + { + displayName: 'Grand Total', + name: 'Grand_Total', + type: 'number', + default: '', + description: 'Total amount for the product after deducting tax and discounts.', + }, + { + displayName: 'Invoice Date', + name: 'Invoice_Date', + type: 'string', + default: '', + }, + { + displayName: 'Invoice Number', + name: 'Invoice_Number', + type: 'string', + default: '', + }, + { + displayName: 'Sales Commission', + name: 'Sales_Commission', + type: 'string', + default: '', + description: 'Commission of sales person on deal closure.', + }, + shippingAddress, + { + displayName: 'Status', + name: 'Status', + type: 'string', + default: '', + }, + { + displayName: 'Sub Total', + name: 'Sub_Total', + type: 'number', + default: '', + description: 'Total amount for the product excluding tax.', + }, + { + displayName: 'Tax', + name: 'Tax', + type: 'number', + default: '', + description: 'Tax amount as the sum of sales tax and value-added tax.', + }, + { + displayName: 'Terms and Conditions', + name: 'Terms_and_Conditions', + type: 'string', + default: '', + description: 'Terms and conditions associated with the invoice.', + }, + ], + }, + + // ---------------------------------------- + // invoice: delete + // ---------------------------------------- + { + displayName: 'Invoice ID', + name: 'invoiceId', + description: 'ID of the invoice to delete.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'invoice', + ], + operation: [ + 'delete', + ], + }, + }, + }, + + // ---------------------------------------- + // invoice: get + // ---------------------------------------- + { + displayName: 'Invoice ID', + name: 'invoiceId', + description: 'ID of the invoice to retrieve.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'invoice', + ], + operation: [ + 'get', + ], + }, + }, + }, + + // ---------------------------------------- + // invoice: getAll + // ---------------------------------------- + ...makeGetAllFields('invoice'), + + // ---------------------------------------- + // invoice: update + // ---------------------------------------- + { + displayName: 'Invoice ID', + name: 'invoiceId', + description: 'ID of the invoice to update.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'invoice', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'invoice', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + { + displayName: 'Account Name', + name: 'Account_Name', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Account Name Field', + options: [ + { + displayName: 'Account Name Fields', + name: 'account_name_fields', + values: [ + { + displayName: 'ID', + name: 'id', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Adjustment', + name: 'Adjustment', + type: 'number', + default: '', + description: 'Adjustment in the grand total, if any.', + }, + billingAddress, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Due Date', + name: 'Due_Date', + type: 'string', + default: '', + }, + { + displayName: 'Exchange Rate', + name: 'Exchange_Rate', + type: 'string', + default: '', + description: 'Exchange rate of the default currency to the home currency.', + }, + { + displayName: 'Grand Total', + name: 'Grand_Total', + type: 'number', + default: '', + description: 'Total amount for the product after deducting tax and discounts.', + }, + { + displayName: 'Invoice Date', + name: 'Invoice_Date', + type: 'string', + default: '', + }, + { + displayName: 'Invoice Number', + name: 'Invoice_Number', + type: 'string', + default: '', + }, + productDetails, + { + displayName: 'Sales Commission', + name: 'Sales_Commission', + type: 'string', + default: '', + description: 'Commission of sales person on deal closure.', + }, + shippingAddress, + { + displayName: 'Status', + name: 'Status', + type: 'string', + default: '', + }, + { + displayName: 'Sub Total', + name: 'Sub_Total', + type: 'number', + default: '', + description: 'Total amount for the product excluding tax.', + }, + { + displayName: 'Subject', + name: 'Subject', + type: 'string', + default: '', + description: 'Subject or title of the invoice.', + }, + { + displayName: 'Tax', + name: 'Tax', + type: 'number', + default: '', + description: 'Tax amount as the sum of sales tax and value-added tax.', + }, + { + displayName: 'Terms and Conditions', + name: 'Terms_and_Conditions', + type: 'string', + default: '', + description: 'Terms and conditions associated with the invoice.', + }, + ], + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Zoho/descriptions/LeadDescription.ts b/packages/nodes-base/nodes/Zoho/descriptions/LeadDescription.ts new file mode 100644 index 0000000000..9f7a4370e1 --- /dev/null +++ b/packages/nodes-base/nodes/Zoho/descriptions/LeadDescription.ts @@ -0,0 +1,466 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +import { + address, + makeGetAllFields, +} from './SharedFields'; + +export const leadOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'lead', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + }, + { + name: 'Delete', + value: 'delete', + }, + { + name: 'Get', + value: 'get', + }, + { + name: 'Get All', + value: 'getAll', + }, + { + name: 'Update', + value: 'update', + }, + ], + default: 'create', + description: 'Operation to perform', + }, +] as INodeProperties[]; + +export const leadFields = [ + // ---------------------------------------- + // lead: create + // ---------------------------------------- + { + displayName: 'Company', + name: 'Company', + description: 'Company at which the lead works.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Last Name', + name: 'Last_Name', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + address, + { + displayName: 'Annual Revenue', + name: 'Annual_Revenue', + type: 'number', + default: '', + description: 'Annual revenue of the lead’s company.', + }, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Designation', + name: 'Designation', + type: 'string', + default: '', + description: 'Position of the lead at their company.', + }, + { + displayName: 'Email', + name: 'Email', + type: 'string', + default: '', + }, + { + displayName: 'Fax', + name: 'Fax', + type: 'string', + default: '', + }, + { + displayName: 'First Name', + name: 'First_Name', + type: 'string', + default: '', + }, + { + displayName: 'Full Name', + name: 'Full_Name', + type: 'string', + default: '', + }, + { + displayName: 'Industry', + name: 'Industry', + type: 'string', + default: '', + description: 'Industry to which the lead belongs.', + }, + { + displayName: 'Industry Type', + name: 'Industry_Type', + type: 'string', + default: '', + description: 'Type of industry to which the lead belongs.', + }, + { + displayName: 'Lead Source', + name: 'Lead_Source', + type: 'string', + default: '', + description: 'Source from which the lead was created.', + }, + { + displayName: 'Lead Status', + name: 'Lead_Status', + type: 'string', + default: '', + }, + { + displayName: 'Mobile', + name: 'Mobile', + type: 'string', + default: '', + }, + { + displayName: 'Number of Employees', + name: 'No_of_Employees', + type: 'number', + default: '', + description: 'Number of employees in the lead’s company.', + }, + { + displayName: 'Phone', + name: 'Phone', + type: 'string', + default: '', + }, + { + displayName: 'Salutation', + name: 'Salutation', + type: 'string', + default: '', + }, + { + displayName: 'Secondary Email', + name: 'Secondary_Email', + type: 'string', + default: '', + }, + { + displayName: 'Skype ID', + name: 'Skype_ID', + type: 'string', + default: '', + }, + { + displayName: 'Twitter', + name: 'Twitter', + type: 'string', + default: '', + }, + { + displayName: 'Website', + name: 'Website', + type: 'string', + default: '', + }, + ], + }, + + // ---------------------------------------- + // lead: delete + // ---------------------------------------- + { + displayName: 'Lead ID', + name: 'leadId', + description: 'ID of the lead to delete.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'delete', + ], + }, + }, + }, + + // ---------------------------------------- + // lead: get + // ---------------------------------------- + { + displayName: 'Lead ID', + name: 'leadId', + description: 'ID of the lead to retrieve.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'get', + ], + }, + }, + }, + + // ---------------------------------------- + // lead: getAll + // ---------------------------------------- + ...makeGetAllFields('lead'), + + // ---------------------------------------- + // lead: update + // ---------------------------------------- + { + displayName: 'Lead ID', + name: 'leadId', + description: 'ID of the lead to update.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + address, + { + displayName: 'Annual Revenue', + name: 'Annual_Revenue', + type: 'number', + default: '', + description: 'Annual revenue of the lead’s company.', + }, + { + displayName: 'Company', + name: 'Company', + type: 'string', + default: '', + description: 'Company at which the lead works.', + }, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Designation', + name: 'Designation', + type: 'string', + default: '', + description: 'Position of the lead at their company.', + }, + { + displayName: 'Email', + name: 'Email', + type: 'string', + default: '', + }, + { + displayName: 'Fax', + name: 'Fax', + type: 'string', + default: '', + }, + { + displayName: 'First Name', + name: 'First_Name', + type: 'string', + default: '', + }, + { + displayName: 'Full Name', + name: 'Full_Name', + type: 'string', + default: '', + }, + { + displayName: 'Industry', + name: 'Industry', + type: 'string', + default: '', + description: 'Industry to which the lead belongs.', + }, + { + displayName: 'Industry Type', + name: 'Industry_Type', + type: 'string', + default: '', + description: 'Type of industry to which the lead belongs.', + }, + { + displayName: 'Last Name', + name: 'Last_Name', + type: 'string', + default: '', + }, + { + displayName: 'Lead Source', + name: 'Lead_Source', + type: 'string', + default: '', + description: 'Source from which the lead was created.', + }, + { + displayName: 'Lead Status', + name: 'Lead_Status', + type: 'string', + default: '', + }, + { + displayName: 'Mobile', + name: 'Mobile', + type: 'string', + default: '', + }, + { + displayName: 'Number of Employees', + name: 'No_of_Employees', + type: 'number', + default: '', + description: 'Number of employees in the lead’s company.', + }, + { + displayName: 'Phone', + name: 'Phone', + type: 'string', + default: '', + }, + { + displayName: 'Salutation', + name: 'Salutation', + type: 'string', + default: '', + }, + { + displayName: 'Secondary Email', + name: 'Secondary_Email', + type: 'string', + default: '', + }, + { + displayName: 'Skype ID', + name: 'Skype_ID', + type: 'string', + default: '', + }, + { + displayName: 'Twitter', + name: 'Twitter', + type: 'string', + default: '', + }, + { + displayName: 'Website', + name: 'Website', + type: 'string', + default: '', + }, + ], + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Zoho/descriptions/PurchaseOrderDescription.ts b/packages/nodes-base/nodes/Zoho/descriptions/PurchaseOrderDescription.ts new file mode 100644 index 0000000000..80c39b6dcd --- /dev/null +++ b/packages/nodes-base/nodes/Zoho/descriptions/PurchaseOrderDescription.ts @@ -0,0 +1,499 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +import { + billingAddress, + makeGetAllFields, + productDetails, + shippingAddress, +} from './SharedFields'; + +export const purchaseOrderOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'purchaseOrder', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + }, + { + name: 'Delete', + value: 'delete', + }, + { + name: 'Get', + value: 'get', + }, + { + name: 'Get All', + value: 'getAll', + }, + { + name: 'Update', + value: 'update', + }, + ], + default: 'create', + description: 'Operation to perform', + }, +] as INodeProperties[]; + +export const purchaseOrderFields = [ + // ---------------------------------------- + // purchaseOrder: create + // ---------------------------------------- + { + displayName: 'Subject', + name: 'subject', + description: 'Subject or title of the purchase order.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'purchaseOrder', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Vendor Name', + name: 'vendorName', + type: '', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'purchaseOrder', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'purchaseOrder', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Adjustment', + name: 'Adjustment', + type: 'number', + default: '', + description: 'Adjustment in the grand total, if any.', + }, + { + displayName: 'Billing Address', + name: 'Billing_Address', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Billing Address Field', + options: [ + { + displayName: 'Billing Address Fields', + name: 'billing_address_fields', + values: [ + { + displayName: 'Billing City', + name: 'Billing_City', + type: 'string', + default: '', + }, + { + displayName: 'Billing Code', + name: 'Billing_Code', + type: 'string', + default: '', + }, + { + displayName: 'Billing Country', + name: 'Billing_Country', + type: 'string', + default: '', + }, + { + displayName: 'Billing State', + name: 'Billing_State', + type: 'string', + default: '', + }, + { + displayName: 'Billing Street', + name: 'Billing_Street', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Carrier', + name: 'Carrier', + type: 'string', + default: '', + description: 'Name of the carrier.', + }, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Discount', + name: 'Discount', + type: 'number', + default: '', + }, + { + displayName: 'Due Date', + name: 'Due_Date', + type: 'string', + default: '', + }, + { + displayName: 'Exchange Rate', + name: 'Exchange_Rate', + type: 'string', + default: '', + description: 'Exchange rate of the default currency to the home currency.', + }, + { + displayName: 'Grand Total', + name: 'Grand_Total', + type: 'number', + default: '', + description: 'Total amount for the product after deducting tax and discounts.', + }, + { + displayName: 'PO Date', + name: 'PO_Date', + type: 'string', + default: '', + description: 'Date on which the purchase order was issued.', + }, + { + displayName: 'PO Number', + name: 'PO_Number', + type: 'string', + default: '', + description: 'ID of the purchase order after creating a case.', + }, + productDetails, + { + displayName: 'Sales Commission', + name: 'Sales_Commission', + type: 'string', + default: '', + description: 'Commission of sales person on deal closure.', + }, + shippingAddress, + { + displayName: 'Status', + name: 'Status', + type: 'string', + default: '', + description: 'Status of the purchase order.', + }, + { + displayName: 'Sub Total', + name: 'Sub_Total', + type: 'number', + default: '', + description: 'Total amount for the product excluding tax.', + }, + { + displayName: 'Tax', + name: 'Tax', + type: 'number', + default: '', + description: 'Tax amount as the sum of sales tax and value-added tax.', + }, + { + displayName: 'Terms and Conditions', + name: 'Terms_and_Conditions', + type: 'string', + default: '', + description: 'Terms and conditions associated with the purchase order.', + }, + { + displayName: 'Tracking Number', + name: 'Tracking_Number', + type: 'string', + default: '', + }, + ], + }, + + // ---------------------------------------- + // purchaseOrder: delete + // ---------------------------------------- + { + displayName: 'Purchase Order ID', + name: 'purchaseOrderId', + description: 'ID of the purchase order to delete.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'purchaseOrder', + ], + operation: [ + 'delete', + ], + }, + }, + }, + + // ---------------------------------------- + // purchaseOrder: get + // ---------------------------------------- + { + displayName: 'Purchase Order ID', + name: 'purchaseOrderId', + description: 'ID of the purchase order to retrieve.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'purchaseOrder', + ], + operation: [ + 'get', + ], + }, + }, + }, + + // ---------------------------------------- + // purchaseOrder: getAll + // ---------------------------------------- + ...makeGetAllFields('purchaseOrder'), + + // ---------------------------------------- + // purchaseOrder: update + // ---------------------------------------- + { + displayName: 'Purchase Order ID', + name: 'purchaseOrderId', + description: 'ID of the purchase order to update.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'purchaseOrder', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'purchaseOrder', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + { + displayName: 'Adjustment', + name: 'Adjustment', + type: 'number', + default: '', + description: 'Adjustment in the grand total, if any.', + }, + billingAddress, + { + displayName: 'Carrier', + name: 'Carrier', + type: 'string', + default: '', + description: 'Name of the carrier.', + }, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Discount', + name: 'Discount', + type: 'number', + default: '', + }, + { + displayName: 'Due Date', + name: 'Due_Date', + type: 'string', + default: '', + }, + { + displayName: 'Exchange Rate', + name: 'Exchange_Rate', + type: 'string', + default: '', + description: 'Exchange rate of the default currency to the home currency.', + }, + { + displayName: 'Grand Total', + name: 'Grand_Total', + type: 'number', + default: '', + description: 'Total amount for the product after deducting tax and discounts.', + }, + { + displayName: 'PO Date', + name: 'PO_Date', + type: 'string', + default: '', + description: 'Date on which the purchase order was issued.', + }, + { + displayName: 'PO Number', + name: 'PO_Number', + type: 'string', + default: '', + description: 'ID of the purchase order after creating a case.', + }, + productDetails, + { + displayName: 'Sales Commission', + name: 'Sales_Commission', + type: 'string', + default: '', + description: 'Commission of sales person on deal closure.', + }, + shippingAddress, + { + displayName: 'Status', + name: 'Status', + type: 'string', + default: '', + description: 'Status of the purchase order.', + }, + { + displayName: 'Sub Total', + name: 'Sub_Total', + type: 'number', + default: '', + description: 'Total amount for the product excluding tax.', + }, + { + displayName: 'Subject', + name: 'Subject', + type: 'string', + default: '', + description: 'Subject or title of the purchase order.', + }, + { + displayName: 'Tax', + name: 'Tax', + type: 'number', + default: '', + description: 'Tax amount as the sum of sales tax and value-added tax.', + }, + { + displayName: 'Terms and Conditions', + name: 'Terms_and_Conditions', + type: 'string', + default: '', + description: 'Terms and conditions associated with the purchase order.', + }, + { + displayName: 'Tracking Number', + name: 'Tracking_Number', + type: 'string', + default: '', + }, + { + displayName: 'Vendor Name', + name: 'Vendor_Name', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Vendor Name Field', + options: [ + { + displayName: 'Vendor Name Fields', + name: 'vendor_name_fields', + values: [ + { + displayName: 'ID', + name: 'id', + type: 'string', + default: '', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + }, + ], + }, + ], + }, + ], + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Zoho/descriptions/QuoteDescription.ts b/packages/nodes-base/nodes/Zoho/descriptions/QuoteDescription.ts new file mode 100644 index 0000000000..d22235202f --- /dev/null +++ b/packages/nodes-base/nodes/Zoho/descriptions/QuoteDescription.ts @@ -0,0 +1,373 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +import { + billingAddress, + makeGetAllFields, + productDetails, + shippingAddress, +} from './SharedFields'; + +export const quoteOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'quote', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + }, + { + name: 'Delete', + value: 'delete', + }, + { + name: 'Get', + value: 'get', + }, + { + name: 'Get All', + value: 'getAll', + }, + { + name: 'Update', + value: 'update', + }, + ], + default: 'create', + description: 'Operation to perform', + }, +] as INodeProperties[]; + +export const quoteFields = [ + // ---------------------------------------- + // quote: create + // ---------------------------------------- + { + displayName: 'Product Details', + name: 'productDetails', + type: '', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'quote', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Subject', + name: 'subject', + description: 'Subject or title of the quote.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'quote', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'quote', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Adjustment', + name: 'Adjustment', + type: 'number', + default: '', + description: 'Adjustment in the grand total, if any.', + }, + billingAddress, + { + displayName: 'Carrier', + name: 'Carrier', + type: 'string', + default: '', + }, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Exchange Rate', + name: 'Exchange_Rate', + type: 'string', + default: '', + description: 'Exchange rate of the default currency to the home currency.', + }, + { + displayName: 'Grand Total', + name: 'Grand_Total', + type: 'number', + default: '', + description: 'Total amount for the product after deducting tax and discounts.', + }, + { + displayName: 'Quote Stage', + name: 'Quote_Stage', + type: 'string', + default: '', + }, + shippingAddress, + { + displayName: 'Sub Total', + name: 'Sub_Total', + type: 'number', + default: '', + description: 'Total amount for the product excluding tax.', + }, + { + displayName: 'Tax', + name: 'Tax', + type: 'number', + default: '', + description: 'Total amount as the sum of sales tax and value-added tax.', + }, + { + displayName: 'Team', + name: 'Team', + type: 'string', + default: '', + description: 'Team for whom the quote is created.', + }, + { + displayName: 'Terms and Conditions', + name: 'Terms_and_Conditions', + type: 'string', + default: '', + description: 'Terms and conditions associated with the quote.', + }, + { + displayName: 'Valid Till', + name: 'Valid_Till', + type: 'string', + default: '', + description: 'Date until when the quote is valid.', + }, + ], + }, + + // ---------------------------------------- + // quote: delete + // ---------------------------------------- + { + displayName: 'Quote ID', + name: 'quoteId', + description: 'ID of the quote to delete.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'quote', + ], + operation: [ + 'delete', + ], + }, + }, + }, + + // ---------------------------------------- + // quote: get + // ---------------------------------------- + { + displayName: 'Quote ID', + name: 'quoteId', + description: 'ID of the quote to retrieve.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'quote', + ], + operation: [ + 'get', + ], + }, + }, + }, + + // ---------------------------------------- + // quote: getAll + // ---------------------------------------- + ...makeGetAllFields('quote'), + + // ---------------------------------------- + // quote: update + // ---------------------------------------- + { + displayName: 'Quote ID', + name: 'quoteId', + description: 'ID of the quote to update.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'quote', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'quote', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + { + displayName: 'Adjustment', + name: 'Adjustment', + type: 'number', + default: '', + description: 'Adjustment in the grand total, if any.', + }, + billingAddress, + { + displayName: 'Carrier', + name: 'Carrier', + type: 'string', + default: '', + }, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Exchange Rate', + name: 'Exchange_Rate', + type: 'string', + default: '', + description: 'Exchange rate of the default currency to the home currency.', + }, + { + displayName: 'Grand Total', + name: 'Grand_Total', + type: 'number', + default: '', + description: 'Total amount for the product after deducting tax and discounts.', + }, + productDetails, + { + displayName: 'Quote Stage', + name: 'Quote_Stage', + type: 'string', + default: '', + }, + shippingAddress, + { + displayName: 'Sub Total', + name: 'Sub_Total', + type: 'number', + default: '', + description: 'Total amount for the product excluding tax.', + }, + { + displayName: 'Subject', + name: 'Subject', + type: 'string', + default: '', + description: 'Subject or title of the quote.', + }, + { + displayName: 'Tax', + name: 'Tax', + type: 'number', + default: '', + description: 'Tax amount as the sum of sales tax and value-added tax.', + }, + { + displayName: 'Team', + name: 'Team', + type: 'string', + default: '', + description: 'Team for whom the quote is created.', + }, + { + displayName: 'Terms and Conditions', + name: 'Terms_and_Conditions', + type: 'string', + default: '', + description: 'Terms and conditions associated with the quote.', + }, + { + displayName: 'Valid Till', + name: 'Valid_Till', + type: 'string', + default: '', + description: 'Date until when the quote is valid.', + }, + ], + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Zoho/descriptions/SalesOrderDescription.ts b/packages/nodes-base/nodes/Zoho/descriptions/SalesOrderDescription.ts new file mode 100644 index 0000000000..271dd19c2b --- /dev/null +++ b/packages/nodes-base/nodes/Zoho/descriptions/SalesOrderDescription.ts @@ -0,0 +1,549 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +import { + billingAddress, + makeGetAllFields, + productDetails, + shippingAddress, +} from './SharedFields'; + +export const salesOrderOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'salesOrder', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + }, + { + name: 'Delete', + value: 'delete', + }, + { + name: 'Get', + value: 'get', + }, + { + name: 'Get All', + value: 'getAll', + }, + { + name: 'Update', + value: 'update', + }, + ], + default: 'create', + description: 'Operation to perform', + }, +] as INodeProperties[]; + +export const salesOrderFields = [ + // ---------------------------------------- + // salesOrder: create + // ---------------------------------------- + { + displayName: 'Account Name', + name: 'accountName', + type: '', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'salesOrder', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Subject', + name: 'subject', + description: 'Subject or title of the sales order.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'salesOrder', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'salesOrder', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Adjustment', + name: 'Adjustment', + type: 'number', + default: '', + description: 'Adjustment in the grand total, if any.', + }, + billingAddress, + { + displayName: 'Carrier', + name: 'Carrier', + type: 'string', + default: '', + description: 'Name of the carrier.', + }, + { + displayName: 'Contact Name', + name: 'Contact_Name', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Contact Name Field', + options: [ + { + displayName: 'Contact Name Fields', + name: 'contact_name_fields', + values: [ + { + displayName: 'ID', + name: 'id', + type: 'string', + default: '', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Deal Name', + name: 'Deal_Name', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Deal Name Field', + options: [ + { + displayName: 'Deal Name Fields', + name: 'deal_name_fields', + values: [ + { + displayName: 'ID', + name: 'id', + type: 'string', + default: '', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Discount', + name: 'Discount', + type: 'number', + default: '', + }, + { + displayName: 'Due Date', + name: 'Due_Date', + type: 'string', + default: '', + }, + { + displayName: 'Exchange Rate', + name: 'Exchange_Rate', + type: 'string', + default: '', + description: 'Exchange rate of the default currency to the home currency.', + }, + { + displayName: 'Grand Total', + name: 'Grand_Total', + type: 'number', + default: '', + description: 'Total amount for the product after deducting tax and discounts.', + }, + productDetails, + { + displayName: 'Purchase Order', + name: 'Purchase_Order', + type: 'string', + default: '', + }, + { + displayName: 'SO Number', + name: 'SO_Number', + type: 'string', + default: '', + description: 'ID of the sales order after creating a case.', + }, + { + displayName: 'Sales Commission', + name: 'Sales_Commission', + type: 'string', + default: '', + description: 'Commission of sales person on deal closure.', + }, + shippingAddress, + { + displayName: 'Status', + name: 'Status', + type: 'string', + default: '', + description: 'Status of the sales order.', + }, + { + displayName: 'Sub Total', + name: 'Sub_Total', + type: 'number', + default: '', + description: 'Total amount for the product excluding tax.', + }, + { + displayName: 'Tax', + name: 'Tax', + type: 'number', + default: '', + description: 'Tax amount as the sum of sales tax and value-added tax.', + }, + { + displayName: 'Terms and Conditions', + name: 'Terms_and_Conditions', + type: 'string', + default: '', + description: 'Terms and conditions associated with the purchase order.', + }, + ], + }, + + // ---------------------------------------- + // salesOrder: delete + // ---------------------------------------- + { + displayName: 'Sales Order ID', + name: 'salesOrderId', + description: 'ID of the sales order to delete.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'salesOrder', + ], + operation: [ + 'delete', + ], + }, + }, + }, + + // ---------------------------------------- + // salesOrder: get + // ---------------------------------------- + { + displayName: 'salesOrder ID', + name: 'salesOrderId', + description: 'ID of the sales order to retrieve.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'salesOrder', + ], + operation: [ + 'get', + ], + }, + }, + }, + + // ---------------------------------------- + // salesOrder: getAll + // ---------------------------------------- + ...makeGetAllFields('salesOrder'), + + // ---------------------------------------- + // salesOrder: update + // ---------------------------------------- + { + displayName: 'Sales Order ID', + name: 'salesOrderId', + description: 'ID of the sales order to update.', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'salesOrder', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'salesOrder', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + { + displayName: 'Account Name', + name: 'Account_Name', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Account Name Field', + options: [ + { + displayName: 'Account Name Fields', + name: 'account_name_fields', + values: [ + { + displayName: 'ID', + name: 'id', + type: 'string', + default: '', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Adjustment', + name: 'Adjustment', + type: 'number', + default: '', + description: 'Adjustment in the grand total, if any.', + }, + billingAddress, + { + displayName: 'Carrier', + name: 'Carrier', + type: 'string', + default: '', + description: 'Name of the carrier.', + }, + { + displayName: 'Contact Name', + name: 'Contact_Name', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Contact Name Field', + options: [ + { + displayName: 'Contact Name Fields', + name: 'contact_name_fields', + values: [ + { + displayName: 'ID', + name: 'id', + type: 'string', + default: '', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Currency', + name: 'Currency', + type: 'string', + default: '', + description: 'Symbol of the currency in which revenue is generated.', + }, + { + displayName: 'Deal Name', + name: 'Deal_Name', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Deal Name Field', + options: [ + { + displayName: 'Deal Name Fields', + name: 'deal_name_fields', + values: [ + { + displayName: 'ID', + name: 'id', + type: 'string', + default: '', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Description', + name: 'Description', + type: 'string', + default: '', + }, + { + displayName: 'Discount', + name: 'Discount', + type: 'number', + default: '', + }, + { + displayName: 'Due Date', + name: 'Due_Date', + type: 'string', + default: '', + }, + { + displayName: 'Exchange Rate', + name: 'Exchange_Rate', + type: 'string', + default: '', + description: 'Exchange rate of the default currency to the home currency.', + }, + { + displayName: 'Grand Total', + name: 'Grand_Total', + type: 'number', + default: '', + description: 'Total amount for the product after deducting tax and discounts.', + }, + productDetails, + { + displayName: 'Purchase Order', + name: 'Purchase_Order', + type: 'string', + default: '', + }, + { + displayName: 'SO Number', + name: 'SO_Number', + type: 'string', + default: '', + description: 'ID of the sales order after creating a case.', + }, + { + displayName: 'Sales Commission', + name: 'Sales_Commission', + type: 'string', + default: '', + description: 'Commission of sales person on deal closure.', + }, + shippingAddress, + { + displayName: 'Status', + name: 'Status', + type: 'string', + default: '', + description: 'Status of the sales order.', + }, + { + displayName: 'Sub Total', + name: 'Sub_Total', + type: 'number', + default: '', + description: 'Total amount for the product excluding tax.', + }, + { + displayName: 'Subject', + name: 'Subject', + type: 'string', + default: '', + description: 'Subject or title of the sales order.', + }, + { + displayName: 'Tax', + name: 'Tax', + type: 'number', + default: '', + description: 'Tax amount as the sum of sales tax and value-added tax.', + }, + { + displayName: 'Terms and Conditions', + name: 'Terms_and_Conditions', + type: 'string', + default: '', + description: 'Terms and conditions associated with the purchase order.', + }, + ], + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Zoho/descriptions/SharedFields.ts b/packages/nodes-base/nodes/Zoho/descriptions/SharedFields.ts new file mode 100644 index 0000000000..2d08dff666 --- /dev/null +++ b/packages/nodes-base/nodes/Zoho/descriptions/SharedFields.ts @@ -0,0 +1,381 @@ +export const billingAddress = { + displayName: 'Billing Address', + name: 'Billing_Address', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Billing Address Field', + options: [ + { + displayName: 'Billing Address Fields', + name: 'address_fields', + values: [ + { + displayName: 'Billing City', + name: 'Billing_City', + type: 'string', + default: '', + }, + { + displayName: 'Billing Code', + name: 'Billing_Code', + type: 'string', + default: '', + }, + { + displayName: 'Billing Country', + name: 'Billing_Country', + type: 'string', + default: '', + }, + { + displayName: 'Billing State', + name: 'Billing_State', + type: 'string', + default: '', + }, + { + displayName: 'Billing Street', + name: 'Billing_Street', + type: 'string', + default: '', + }, + ], + }, + ], +}; + +export const shippingAddress = { + displayName: 'Shipping Address', + name: 'Shipping_Address', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Shipping Address Field', + options: [ + { + displayName: 'Shipping Address Fields', + name: 'address_fields', + values: [ + { + displayName: 'Shipping City', + name: 'Shipping_City', + type: 'string', + default: '', + }, + { + displayName: 'Shipping Code', + name: 'Shipping_Code', + type: 'string', + default: '', + }, + { + displayName: 'Shipping Country', + name: 'Shipping_Country', + type: 'string', + default: '', + }, + { + displayName: 'Shipping State', + name: 'Shipping_State', + type: 'string', + default: '', + }, + { + displayName: 'Shipping Street', + name: 'Shipping_Street', + type: 'string', + default: '', + }, + ], + }, + ], +}; + +export const mailingAddress = { + displayName: 'Mailing Address', + name: 'Mailing_Address', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Mailing Address Field', + options: [ + { + displayName: 'Mailing Address Fields', + name: 'address_fields', + values: [ + { + displayName: 'Mailing City', + name: 'Mailing_City', + type: 'string', + default: '', + }, + { + displayName: 'Mailing Country', + name: 'Mailing_Country', + type: 'string', + default: '', + }, + { + displayName: 'Mailing State', + name: 'Mailing_State', + type: 'string', + default: '', + }, + { + displayName: 'Mailing Street', + name: 'Mailing_Street', + type: 'string', + default: '', + }, + { + displayName: 'Mailing Zip', + name: 'Mailing_Zip', + type: 'string', + default: '', + }, + ], + }, + ], +}; + +export const otherAddress = { + displayName: 'Other Address', + name: 'Other_Address', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Other Address Field', + options: [ + { + displayName: 'Other Address Fields', + name: 'address_fields', + values: [ + { + displayName: 'Other City', + name: 'Other_City', + type: 'string', + default: '', + }, + { + displayName: 'Other State', + name: 'Other_State', + type: 'string', + default: '', + }, + { + displayName: 'Other Street', + name: 'Other_Street', + type: 'string', + default: '', + }, + { + displayName: 'Other Zip', + name: 'Other_Zip', + type: 'string', + default: '', + }, + ], + }, + ], +}; + +export const address = { + displayName: 'Address', + name: 'Address', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Address Field', + options: [ + { + displayName: 'Address Fields', + name: 'address_fields', + values: [ + { + displayName: 'City', + name: 'City', + type: 'string', + default: '', + }, + { + displayName: 'Country', + name: 'Country', + type: 'string', + default: '', + }, + { + displayName: 'State', + name: 'State', + type: 'string', + default: '', + }, + { + displayName: 'Street', + name: 'Street', + type: 'string', + default: '', + }, + { + displayName: 'Zip Code', + name: 'Zip_Code', + type: 'string', + default: '', + }, + ], + }, + ], +}; + +export const productDetails = { + displayName: 'Product Details', + name: 'Product_Details', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Product Details Field', + options: [ + { + displayName: 'Product Details Fields', + name: 'product_details_fields', + values: [ + { + displayName: 'Tax', + name: 'Tax', + type: 'string', + default: '', + }, + { + displayName: 'Book', + name: 'book', + type: 'string', + default: '', + }, + { + displayName: 'List Price', + name: 'list_price', + type: 'string', + default: '', + }, + { + displayName: 'Net Total', + name: 'net_total', + type: 'string', + default: '', + }, + { + displayName: 'Product', + name: 'product', + type: 'string', + default: '', + }, + { + displayName: 'Product Description', + name: 'product_description', + type: 'string', + default: '', + }, + { + displayName: 'Quantity', + name: 'quantity', + type: 'string', + default: '', + }, + { + displayName: 'Quantity in Stock', + name: 'quantity_in_stock', + type: 'string', + default: '', + }, + { + displayName: 'Total', + name: 'total', + type: 'string', + default: '', + }, + { + displayName: 'Total After Discount', + name: 'total_after_discount', + type: 'string', + default: '', + }, + { + displayName: 'Unit Price', + name: 'unit_price', + type: 'string', + default: '', + }, + ], + }, + ], +}; + +const pluralize = (resource: string) => (isCamelCase(resource) ? splitCamelCased(resource) : resource) + 's'; + +const isCamelCase = (resource: string) => /([a-z])([A-Z])/.test(resource); + +const splitCamelCased = (resource: string) => resource.replace(/([a-z])([A-Z])/, '$1 $2').toLowerCase(); + +export const makeGetAllFields = (resource: string) => [ + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + default: false, + description: 'Return all results.', + displayOptions: { + show: { + resource: [ + resource, + ], + operation: [ + 'getAll', + ], + }, + }, + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + default: 5, + description: 'The number of results to return.', + typeOptions: { + minValue: 1, + maxValue: 1000, + }, + displayOptions: { + show: { + resource: [ + resource, + ], + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + }, + }, + { + displayName: 'Filters', + name: 'filters', + type: 'collection', + placeholder: 'Add Filter', + default: {}, + displayOptions: { + show: { + resource: [ + resource, + ], + operation: [ + 'getAll', + ], + }, + }, + options: [ + { + displayName: 'IDs', + name: 'id', + type: 'string', + default: '', + description: `Comma-separated list of IDs to filter the ${pluralize(resource)} by.`, + }, + ], + }, +]; diff --git a/packages/nodes-base/nodes/Zoho/descriptions/index.ts b/packages/nodes-base/nodes/Zoho/descriptions/index.ts new file mode 100644 index 0000000000..da1a75750a --- /dev/null +++ b/packages/nodes-base/nodes/Zoho/descriptions/index.ts @@ -0,0 +1,8 @@ +export * from './AccountDescription'; +export * from './ContactDescription'; +export * from './DealDescription'; +export * from './InvoiceDescription'; +export * from './LeadDescription'; +export * from './PurchaseOrderDescription'; +export * from './QuoteDescription'; +export * from './SalesOrderDescription'; diff --git a/packages/nodes-base/nodes/Zoho/zoho.svg b/packages/nodes-base/nodes/Zoho/zoho.svg new file mode 100644 index 0000000000..23f76d2e59 --- /dev/null +++ b/packages/nodes-base/nodes/Zoho/zoho.svg @@ -0,0 +1 @@ + diff --git a/packages/nodes-base/nodes/Zoho/zohoCrm.png b/packages/nodes-base/nodes/Zoho/zohoCrm.png deleted file mode 100644 index 8d541a4514..0000000000 Binary files a/packages/nodes-base/nodes/Zoho/zohoCrm.png and /dev/null differ