From d3a2456de9c4a46a0c7dbb211b9aac16b55761f7 Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Mon, 16 Mar 2020 23:26:27 +0100 Subject: [PATCH] :zap: Fix some InvoiceNinja-Node issues --- ...ials.ts => InvoiceNinjaApi.credentials.ts} | 10 +- .../InvoiceNinjaCloudApi.credentials.ts | 17 -- .../nodes/InvoiceNinja/ClientDescription.ts | 10 +- .../nodes/InvoiceNinja/ClientInterface.ts | 2 +- .../nodes/InvoiceNinja/ExpenseDescription.ts | 18 ++- .../nodes/InvoiceNinja/GenericFunctions.ts | 28 ++-- .../nodes/InvoiceNinja/InvoiceDescription.ts | 12 +- .../nodes/InvoiceNinja/InvoiceNinja.node.ts | 151 +++++++----------- .../nodes/InvoiceNinja/InvoiceNinja.png | Bin 4699 -> 0 bytes .../InvoiceNinja/InvoiceNinjaTrigger.node.ts | 52 ++---- .../nodes/InvoiceNinja/PaymentDescription.ts | 10 +- .../nodes/InvoiceNinja/QuoteDescription.ts | 20 +-- .../nodes/InvoiceNinja/TaskDescription.ts | 10 +- .../nodes/InvoiceNinja/invoiceNinja.png | Bin 0 -> 1109 bytes packages/nodes-base/package.json | 3 +- 15 files changed, 129 insertions(+), 214 deletions(-) rename packages/nodes-base/credentials/{invoiceNinjaServerApi.credentials.ts => InvoiceNinjaApi.credentials.ts} (63%) delete mode 100644 packages/nodes-base/credentials/InvoiceNinjaCloudApi.credentials.ts delete mode 100644 packages/nodes-base/nodes/InvoiceNinja/InvoiceNinja.png create mode 100644 packages/nodes-base/nodes/InvoiceNinja/invoiceNinja.png diff --git a/packages/nodes-base/credentials/invoiceNinjaServerApi.credentials.ts b/packages/nodes-base/credentials/InvoiceNinjaApi.credentials.ts similarity index 63% rename from packages/nodes-base/credentials/invoiceNinjaServerApi.credentials.ts rename to packages/nodes-base/credentials/InvoiceNinjaApi.credentials.ts index 906b638921..d79c23859e 100644 --- a/packages/nodes-base/credentials/invoiceNinjaServerApi.credentials.ts +++ b/packages/nodes-base/credentials/InvoiceNinjaApi.credentials.ts @@ -3,15 +3,15 @@ import { NodePropertyTypes, } from 'n8n-workflow'; -export class InvoiceNinjaServerApi implements ICredentialType { - name = 'invoiceNinjaServerApi'; +export class InvoiceNinjaApi implements ICredentialType { + name = 'invoiceNinjaApi'; displayName = 'Invoice Ninja API'; properties = [ { - displayName: 'Domain', - name: 'domain', + displayName: 'URL', + name: 'url', type: 'string' as NodePropertyTypes, - default: '', + default: 'https://app.invoiceninja.com', }, { displayName: 'API Token', diff --git a/packages/nodes-base/credentials/InvoiceNinjaCloudApi.credentials.ts b/packages/nodes-base/credentials/InvoiceNinjaCloudApi.credentials.ts deleted file mode 100644 index f9ecdad0e4..0000000000 --- a/packages/nodes-base/credentials/InvoiceNinjaCloudApi.credentials.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { - ICredentialType, - NodePropertyTypes, -} from 'n8n-workflow'; - -export class InvoiceNinjaCloudApi implements ICredentialType { - name = 'invoiceNinjaCloudApi'; - displayName = 'Invoice Ninja API'; - properties = [ - { - displayName: 'API Token', - name: 'apiToken', - type: 'string' as NodePropertyTypes, - default: '', - }, - ]; -} diff --git a/packages/nodes-base/nodes/InvoiceNinja/ClientDescription.ts b/packages/nodes-base/nodes/InvoiceNinja/ClientDescription.ts index e10c751183..4a9a467d8d 100644 --- a/packages/nodes-base/nodes/InvoiceNinja/ClientDescription.ts +++ b/packages/nodes-base/nodes/InvoiceNinja/ClientDescription.ts @@ -18,6 +18,11 @@ export const clientOperations = [ value: 'create', description: 'Create a new client', }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a client', + }, { name: 'Get', value: 'get', @@ -28,11 +33,6 @@ export const clientOperations = [ value: 'getAll', description: 'Get data of all clients', }, - { - name: 'Delete', - value: 'delete', - description: 'Delete a client', - } ], default: 'create', description: 'The operation to perform.', diff --git a/packages/nodes-base/nodes/InvoiceNinja/ClientInterface.ts b/packages/nodes-base/nodes/InvoiceNinja/ClientInterface.ts index 998ad2138a..0590068e9a 100644 --- a/packages/nodes-base/nodes/InvoiceNinja/ClientInterface.ts +++ b/packages/nodes-base/nodes/InvoiceNinja/ClientInterface.ts @@ -8,7 +8,7 @@ export interface IContact { } export interface IClient { - contacts?: IContact[], + contacts?: IContact[]; name?: string; address1?: string; address2?: string; diff --git a/packages/nodes-base/nodes/InvoiceNinja/ExpenseDescription.ts b/packages/nodes-base/nodes/InvoiceNinja/ExpenseDescription.ts index 39e1c61bb1..3bf3f6977e 100644 --- a/packages/nodes-base/nodes/InvoiceNinja/ExpenseDescription.ts +++ b/packages/nodes-base/nodes/InvoiceNinja/ExpenseDescription.ts @@ -18,21 +18,21 @@ export const expenseOperations = [ value: 'create', description: 'Create a new expense', }, + { + name: 'Delete', + value: 'delete', + description: 'Delete an expense', + }, { name: 'Get', value: 'get', - description: 'Get data of a expense', + description: 'Get data of an expense', }, { name: 'Get All', value: 'getAll', description: 'Get data of all expenses', }, - { - name: 'Delete', - value: 'delete', - description: 'Delete a expense', - } ], default: 'create', description: 'The operation to perform.', @@ -60,6 +60,12 @@ export const expenseFields = [ }, }, options: [ + { + displayName: 'Amount', + name: 'amount', + type: 'number', + default: 0, + }, { displayName: 'Billable', name: 'billable', diff --git a/packages/nodes-base/nodes/InvoiceNinja/GenericFunctions.ts b/packages/nodes-base/nodes/InvoiceNinja/GenericFunctions.ts index 2eeea9f596..9d690807c2 100644 --- a/packages/nodes-base/nodes/InvoiceNinja/GenericFunctions.ts +++ b/packages/nodes-base/nodes/InvoiceNinja/GenericFunctions.ts @@ -13,29 +13,21 @@ import { import { get } from 'lodash'; -export async function invoiceninjaApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, query?: IDataObject, uri?: string): Promise { // tslint:disable-line:no-any - let token; - let endpoint; - const cloudCredentials = this.getCredentials('invoiceNinjaCloudApi'); - const serverCredentials = this.getCredentials('invoiceNinjaServerApi'); - if (cloudCredentials === undefined && serverCredentials === undefined) { +export async function invoiceNinjaApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: any = {}, query?: IDataObject, uri?: string): Promise { // tslint:disable-line:no-any + const credentials = this.getCredentials('invoiceNinjaApi'); + if (credentials === undefined) { throw new Error('No credentials got returned!'); } - if (cloudCredentials !== undefined) { - endpoint = 'https://app.invoiceninja.com'; - token = cloudCredentials!.apiToken; - } else { - endpoint = serverCredentials!.domain; - token = serverCredentials!.apiToken; - } + + const baseUrl = credentials!.url || 'https://app.invoiceninja.com'; const options: OptionsWithUri = { headers: { Accept: 'application/json', - 'X-Ninja-Token': token, + 'X-Ninja-Token': credentials.apiToken, }, method, qs: query, - uri: uri || `${endpoint}/api/v1${resource}`, + uri: uri || `${baseUrl}/api/v1${endpoint}`, body, json: true }; @@ -54,7 +46,7 @@ export async function invoiceninjaApiRequest(this: IHookFunctions | IExecuteFunc } } -export async function invoiceninjaApiRequestAllItems(this: IExecuteFunctions | ILoadOptionsFunctions, propertyName: string, method: string, endpoint: string, body: any = {}, query: IDataObject = {}): Promise { // tslint:disable-line:no-any +export async function invoiceNinjaApiRequestAllItems(this: IExecuteFunctions | ILoadOptionsFunctions, propertyName: string, method: string, endpoint: string, body: any = {}, query: IDataObject = {}): Promise { // tslint:disable-line:no-any const returnData: IDataObject[] = []; @@ -63,8 +55,8 @@ export async function invoiceninjaApiRequestAllItems(this: IExecuteFunctions | I query.per_page = 100; do { - responseData = await invoiceninjaApiRequest.call(this, method, endpoint, body, query, uri); - let next = get(responseData, 'meta.pagination.links.next') as string | undefined; + responseData = await invoiceNinjaApiRequest.call(this, method, endpoint, body, query, uri); + const next = get(responseData, 'meta.pagination.links.next') as string | undefined; if (next) { uri = next; } diff --git a/packages/nodes-base/nodes/InvoiceNinja/InvoiceDescription.ts b/packages/nodes-base/nodes/InvoiceNinja/InvoiceDescription.ts index de5a17f974..51ace0215c 100644 --- a/packages/nodes-base/nodes/InvoiceNinja/InvoiceDescription.ts +++ b/packages/nodes-base/nodes/InvoiceNinja/InvoiceDescription.ts @@ -18,6 +18,11 @@ export const invoiceOperations = [ value: 'create', description: 'Create a new invoice', }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a invoice', + }, { name: 'Email', value: 'email', @@ -33,11 +38,6 @@ export const invoiceOperations = [ value: 'getAll', description: 'Get data of all invoices', }, - { - name: 'Delete', - value: 'delete', - description: 'Delete a invoice', - } ], default: 'create', description: 'The operation to perform.', @@ -175,7 +175,7 @@ export const invoiceFields = [ default: '', }, { - displayName: 'Po Number', + displayName: 'PO Number', name: 'poNumber', type: 'string', default: '', diff --git a/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinja.node.ts b/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinja.node.ts index 5c996e0384..b1be5bdcd0 100644 --- a/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinja.node.ts +++ b/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinja.node.ts @@ -3,23 +3,23 @@ import { } from 'n8n-core'; import { IDataObject, - INodeTypeDescription, INodeExecutionData, - INodeType, ILoadOptionsFunctions, INodePropertyOptions, + INodeType, + INodeTypeDescription, } from 'n8n-workflow'; import { - invoiceninjaApiRequest, - invoiceninjaApiRequestAllItems, + invoiceNinjaApiRequest, + invoiceNinjaApiRequestAllItems, } from './GenericFunctions'; import { + clientFields, clientOperations, - clientFields } from './ClientDescription'; import { + invoiceFields, invoiceOperations, - invoiceFields } from './InvoiceDescription'; import { IClient, @@ -33,29 +33,29 @@ import { IItem, } from './invoiceInterface'; import { + taskFields, taskOperations, - taskFields } from './TaskDescription'; import { ITask, } from './TaskInterface'; import { + paymentFields, paymentOperations, - paymentFields } from './PaymentDescription'; import { IPayment, } from './PaymentInterface'; import { + expenseFields, expenseOperations, - expenseFields } from './ExpenseDescription'; import { IExpense, } from './ExpenseInterface'; import { + quoteFields, quoteOperations, - quoteFields } from './QuoteDescription'; import { IQuote, @@ -78,45 +78,11 @@ export class InvoiceNinja implements INodeType { outputs: ['main'], credentials: [ { - name: 'invoiceNinjaCloudApi', + name: 'invoiceNinjaApi', required: true, - displayOptions: { - show: { - invoiceNinjaVersion: [ - 'cloud', - ], - }, - }, - }, - { - name: 'invoiceNinjaServerApi', - required: true, - displayOptions: { - show: { - invoiceNinjaVersion: [ - 'server', - ], - }, - }, }, ], properties: [ - { - displayName: 'Version', - name: 'invoiceNinjaVersion', - type: 'options', - options: [ - { - name: 'Cloud', - value: 'cloud', - }, - { - name: 'Server (Self Hosted)', - value: 'server', - }, - ], - default: 'cloud', - }, { displayName: 'Resource', name: 'resource', @@ -171,7 +137,7 @@ export class InvoiceNinja implements INodeType { // select them easily async getClients(this: ILoadOptionsFunctions): Promise { const returnData: INodePropertyOptions[] = []; - const clients = await invoiceninjaApiRequestAllItems.call(this, 'data', 'GET', '/clients'); + const clients = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/clients'); for (const client of clients) { const clientName = client.display_name; const clientId = client.id; @@ -186,7 +152,7 @@ export class InvoiceNinja implements INodeType { // select them easily async getProjects(this: ILoadOptionsFunctions): Promise { const returnData: INodePropertyOptions[] = []; - const projects = await invoiceninjaApiRequestAllItems.call(this, 'data', 'GET', '/projects'); + const projects = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/projects'); for (const project of projects) { const projectName = project.name; const projectId = project.id; @@ -201,7 +167,7 @@ export class InvoiceNinja implements INodeType { // select them easily async getInvoices(this: ILoadOptionsFunctions): Promise { const returnData: INodePropertyOptions[] = []; - const invoices = await invoiceninjaApiRequestAllItems.call(this, 'data', 'GET', '/invoices'); + const invoices = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/invoices'); for (const invoice of invoices) { const invoiceName = invoice.invoice_number; const invoiceId = invoice.id; @@ -230,7 +196,7 @@ export class InvoiceNinja implements INodeType { // select them easily async getVendors(this: ILoadOptionsFunctions): Promise { const returnData: INodePropertyOptions[] = []; - const vendors = await invoiceninjaApiRequestAllItems.call(this, 'data', 'GET', '/vendors'); + const vendors = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/vendors'); for (const vendor of vendors) { const vendorName = vendor.name; const vendorId = vendor.id; @@ -245,7 +211,7 @@ export class InvoiceNinja implements INodeType { // select them easily async getExpenseCategories(this: ILoadOptionsFunctions): Promise { const returnData: INodePropertyOptions[] = []; - const categories = await invoiceninjaApiRequestAllItems.call(this, 'data', 'GET', '/expense_categories'); + const categories = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/expense_categories'); for (const category of categories) { const categoryName = category.name; const categoryId = category.id; @@ -306,8 +272,8 @@ export class InvoiceNinja implements INodeType { last_name: contactValue.lastName as string, email: contactValue.email as string, phone: contactValue.phone as string, - } - contacts.push(contact) + }; + contacts.push(contact); } body.contacts = contacts; } @@ -329,7 +295,7 @@ export class InvoiceNinja implements INodeType { body.postal_code = billingAddressValue.postalCode as string; body.country_id = parseInt(billingAddressValue.countryCode as string, 10); } - responseData = await invoiceninjaApiRequest.call(this, 'POST', '/clients', body); + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/clients', body); responseData = responseData.data; } if (operation === 'get') { @@ -338,7 +304,7 @@ export class InvoiceNinja implements INodeType { if (options.include) { qs.include = options.include as string; } - responseData = await invoiceninjaApiRequest.call(this, 'GET', `/clients/${clientId}`, {}, qs); + responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/clients/${clientId}`, {}, qs); responseData = responseData.data; } if (operation === 'getAll') { @@ -348,16 +314,16 @@ export class InvoiceNinja implements INodeType { qs.include = options.include as string; } if (returnAll === true) { - responseData = await invoiceninjaApiRequestAllItems.call(this, 'data', 'GET', '/clients', {}, qs); + responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/clients', {}, qs); } else { qs.per_page = this.getNodeParameter('limit', 0) as number; - responseData = await invoiceninjaApiRequest.call(this, 'GET', '/clients', {}, qs); + responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/clients', {}, qs); responseData = responseData.data; } } if (operation === 'delete') { const clientId = this.getNodeParameter('clientId', i) as string; - responseData = await invoiceninjaApiRequest.call(this, 'DELETE', `/clients/${clientId}`); + responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/clients/${clientId}`); responseData = responseData.data; } } @@ -444,17 +410,17 @@ export class InvoiceNinja implements INodeType { tax_rate2: itemValue.taxRate2 as number, tax_name1: itemValue.taxName1 as string, tax_name2: itemValue.taxName2 as string, - } - items.push(item) + }; + items.push(item); } body.invoice_items = items; } - responseData = await invoiceninjaApiRequest.call(this, 'POST', '/invoices', body); + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/invoices', body); responseData = responseData.data; } if (operation === 'email') { const invoiceId = this.getNodeParameter('invoiceId', i) as string; - responseData = await invoiceninjaApiRequest.call(this, 'POST', '/email_invoice', { id: invoiceId }); + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/email_invoice', { id: invoiceId }); } if (operation === 'get') { const invoiceId = this.getNodeParameter('invoiceId', i) as string; @@ -462,7 +428,7 @@ export class InvoiceNinja implements INodeType { if (options.include) { qs.include = options.include as string; } - responseData = await invoiceninjaApiRequest.call(this, 'GET', `/invoices/${invoiceId}`, {}, qs); + responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/invoices/${invoiceId}`, {}, qs); responseData = responseData.data; } if (operation === 'getAll') { @@ -475,16 +441,16 @@ export class InvoiceNinja implements INodeType { qs.invoice_number = options.invoiceNumber as string; } if (returnAll === true) { - responseData = await invoiceninjaApiRequestAllItems.call(this, 'data', 'GET', '/invoices', {}, qs); + responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/invoices', {}, qs); } else { qs.per_page = this.getNodeParameter('limit', 0) as number; - responseData = await invoiceninjaApiRequest.call(this, 'GET', '/invoices', {}, qs); + responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/invoices', {}, qs); responseData = responseData.data; } } if (operation === 'delete') { const invoiceId = this.getNodeParameter('invoiceId', i) as string; - responseData = await invoiceninjaApiRequest.call(this, 'DELETE', `/invoices/${invoiceId}`); + responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/invoices/${invoiceId}`); responseData = responseData.data; } } @@ -519,13 +485,13 @@ export class InvoiceNinja implements INodeType { to = new Date(logValue.endDate as string).getTime()/1000 as number; } if (logValue.duration) { - to = from + (logValue.duration as number * 3600) + to = from + (logValue.duration as number * 3600); } logs.push([from as number, to as number]); } body.time_log = JSON.stringify(logs); } - responseData = await invoiceninjaApiRequest.call(this, 'POST', '/tasks', body); + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/tasks', body); responseData = responseData.data; } if (operation === 'get') { @@ -534,7 +500,7 @@ export class InvoiceNinja implements INodeType { if (options.include) { qs.include = options.include as string; } - responseData = await invoiceninjaApiRequest.call(this, 'GET', `/tasks/${taskId}`, {}, qs); + responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/tasks/${taskId}`, {}, qs); responseData = responseData.data; } if (operation === 'getAll') { @@ -544,16 +510,16 @@ export class InvoiceNinja implements INodeType { qs.include = options.include as string; } if (returnAll === true) { - responseData = await invoiceninjaApiRequestAllItems.call(this, 'data', 'GET', '/tasks', {}, qs); + responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/tasks', {}, qs); } else { qs.per_page = this.getNodeParameter('limit', 0) as number; - responseData = await invoiceninjaApiRequest.call(this, 'GET', '/tasks', {}, qs); + responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/tasks', {}, qs); responseData = responseData.data; } } if (operation === 'delete') { const taskId = this.getNodeParameter('taskId', i) as string; - responseData = await invoiceninjaApiRequest.call(this, 'DELETE', `/tasks/${taskId}`); + responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/tasks/${taskId}`); responseData = responseData.data; } } @@ -575,7 +541,7 @@ export class InvoiceNinja implements INodeType { if (additionalFields.privateNotes) { body.private_notes = additionalFields.privateNotes as string; } - responseData = await invoiceninjaApiRequest.call(this, 'POST', '/payments', body); + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/payments', body); responseData = responseData.data; } if (operation === 'get') { @@ -584,7 +550,7 @@ export class InvoiceNinja implements INodeType { if (options.include) { qs.include = options.include as string; } - responseData = await invoiceninjaApiRequest.call(this, 'GET', `/payments/${paymentId}`, {}, qs); + responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/payments/${paymentId}`, {}, qs); responseData = responseData.data; } if (operation === 'getAll') { @@ -594,16 +560,16 @@ export class InvoiceNinja implements INodeType { qs.include = options.include as string; } if (returnAll === true) { - responseData = await invoiceninjaApiRequestAllItems.call(this, 'data', 'GET', '/payments', {}, qs); + responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/payments', {}, qs); } else { qs.per_page = this.getNodeParameter('limit', 0) as number; - responseData = await invoiceninjaApiRequest.call(this, 'GET', '/payments', {}, qs); + responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/payments', {}, qs); responseData = responseData.data; } } if (operation === 'delete') { const paymentId = this.getNodeParameter('paymentId', i) as string; - responseData = await invoiceninjaApiRequest.call(this, 'DELETE', `/payments/${paymentId}`); + responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/payments/${paymentId}`); responseData = responseData.data; } } @@ -611,6 +577,9 @@ export class InvoiceNinja implements INodeType { if (operation === 'create') { const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; const body: IExpense = {}; + if (additionalFields.amount) { + body.amount = additionalFields.amount as number; + } if (additionalFields.billable) { body.should_be_invoiced = additionalFields.billable as boolean; } @@ -659,27 +628,27 @@ export class InvoiceNinja implements INodeType { if (additionalFields.vendor) { body.vendor_id = additionalFields.vendor as number; } - responseData = await invoiceninjaApiRequest.call(this, 'POST', '/expenses', body); + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/expenses', body); responseData = responseData.data; } if (operation === 'get') { const expenseId = this.getNodeParameter('expenseId', i) as string; - responseData = await invoiceninjaApiRequest.call(this, 'GET', `/expenses/${expenseId}`, {}, qs); + responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/expenses/${expenseId}`, {}, qs); responseData = responseData.data; } if (operation === 'getAll') { const returnAll = this.getNodeParameter('returnAll', 0) as boolean; if (returnAll === true) { - responseData = await invoiceninjaApiRequestAllItems.call(this, 'data', 'GET', '/payments', {}, qs); + responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/expenses', {}, qs); } else { qs.per_page = this.getNodeParameter('limit', 0) as number; - responseData = await invoiceninjaApiRequest.call(this, 'GET', '/payments', {}, qs); + responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/expenses', {}, qs); responseData = responseData.data; } } if (operation === 'delete') { const expenseId = this.getNodeParameter('expenseId', i) as string; - responseData = await invoiceninjaApiRequest.call(this, 'DELETE', `/expenses/${expenseId}`); + responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/expenses/${expenseId}`); responseData = responseData.data; } } @@ -752,8 +721,8 @@ export class InvoiceNinja implements INodeType { if (additionalFields.paid) { body.paid = additionalFields.paid as number; } - if (additionalFields.emailQoute) { - body.email_invoice = additionalFields.emailQoute as boolean; + if (additionalFields.emailQuote) { + body.email_invoice = additionalFields.emailQuote as boolean; } const invoceItemsValues = (this.getNodeParameter('invoiceItemsUi', i) as IDataObject).invoiceItemsValues as IDataObject[]; if (invoceItemsValues) { @@ -768,17 +737,17 @@ export class InvoiceNinja implements INodeType { tax_rate2: itemValue.taxRate2 as number, tax_name1: itemValue.taxName1 as string, tax_name2: itemValue.taxName2 as string, - } - items.push(item) + }; + items.push(item); } body.invoice_items = items; } - responseData = await invoiceninjaApiRequest.call(this, 'POST', '/invoices', body); + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/invoices', body); responseData = responseData.data; } if (operation === 'email') { const quoteId = this.getNodeParameter('quoteId', i) as string; - responseData = await invoiceninjaApiRequest.call(this, 'POST', '/email_invoice', { id: quoteId }); + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/email_invoice', { id: quoteId }); } if (operation === 'get') { const quoteId = this.getNodeParameter('quoteId', i) as string; @@ -786,7 +755,7 @@ export class InvoiceNinja implements INodeType { if (options.include) { qs.include = options.include as string; } - responseData = await invoiceninjaApiRequest.call(this, 'GET', `/invoices/${quoteId}`, {}, qs); + responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/invoices/${quoteId}`, {}, qs); responseData = responseData.data; } if (operation === 'getAll') { @@ -799,16 +768,16 @@ export class InvoiceNinja implements INodeType { qs.invoice_number = options.invoiceNumber as string; } if (returnAll === true) { - responseData = await invoiceninjaApiRequestAllItems.call(this, 'data', 'GET', '/quotes', {}, qs); + responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/quotes', {}, qs); } else { qs.per_page = this.getNodeParameter('limit', 0) as number; - responseData = await invoiceninjaApiRequest.call(this, 'GET', '/quotes', {}, qs); + responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/quotes', {}, qs); responseData = responseData.data; } } if (operation === 'delete') { const quoteId = this.getNodeParameter('quoteId', i) as string; - responseData = await invoiceninjaApiRequest.call(this, 'DELETE', `/invoices/${quoteId}`); + responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/invoices/${quoteId}`); responseData = responseData.data; } } diff --git a/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinja.png b/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinja.png deleted file mode 100644 index d35e3050c7e7614a300525049ed97b51a7e73340..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4699 zcmY*d2Q-{(yPX)lM2jwZjWTMYGmJKB9Axy-MjJEA2qU76HbL}Gkmx~l36VsvAtAab zQ9=+5Aqe^9oOAzs@4MF9_P3wC-{)KFeZI9mys5D+4JA7z005xT*Mpc{%_@I7IqB7? z^lR4dY9e+68-W3U`Xs7fjwDxm9%nr>BLE;+2mlC=0szjgpzuuqAV3NL_y)g<$_4;f zeDd4w{t=?^(X;Xg0Iv7^>DMyEu5$nY*Q`9uVHlW^p^`J&Thh@5?c^#M|a>VjOvbypbq>r65(lzZptb>pw7vkLPa+#!HnCW@O5vh4yphk(ZQ{l;TsPV*0%KzWAt`Y?Oc>Mqou<(xN8s2}@;rpe{#(d7_f}GEJ zqu~M>n7u_+{Vd4>` zG$CPc?Wd}3vZ7wd2pT}kMsnmYHs0s?ZEk)Pz~;)K#5+4X8O+;T%qz{b{l1RYV7bWl zb%{n|^wV!`4W#flpmwcK3GpD8?c?2C9r!8b4LS!02gm+}jtBQ%D7T`YH)Z43AIiEU zA8k!+Yf~(~^4A?LP~?w&d~+hWO8vYVv%P4S`{q|ex}=@;#KQbE1cVkPHQcE2q~B~P zHE`XmbDXnX4+jjA$am0~wxT|#w!;@~Hf#^;fij380k#ipEFjzDj`I_*3+_ZV{@uCe zG_#Y4cET4y`vZ07w_~CyB2pE= zvwOMw#Hh8-u`!eJ;_he8P9^pQN;2Mk)Rp!fZ7mx^tGL{-%_cWtAxq64H8G^doa&MR z4ng2ryN;^qG}7Ug**QTMhH&^konu6^zy8#hH*&37CvJmaryAlc{2sI98}Cc4Od^$Ak+5 zAdNf|wjhd+s!m$eA0DsLrc$K970UAVA1vYB3+(#D z?Tg^xQ^)u0gDJ9ZPY?24s6loOklT(#`yeyOuC?S*`u@_&m!L8Ud%8u-wM+@k$@{_? zbxg|M&g`4bg<O;BQ zp~>&8n@hN+UcO_O7XU0%6{j{q-fAhF(_?0i562iHUb)FeUe`9rFryu&jJf%tJ#bH* zgg87#&Fxv1J%bL9hf)E*$!aN3&b6 z_0pe;`R1sQevKX;eHu;W+FfQe`W3o99M7$(rS7Xwv?O5cBw*ZwT?W=UF}7f3z3zaf zYP<-p!-%<7FSp~}dAGCUt!G=T92*^>7u0<(BPuIBMhd6L#u9ESPazlTI(ZPTri#z~ z$(U7Q3QfNoSB0i=?d-$KB4N z2w(x)rO3bB7_rh7jX3%KnRFY=fF$1A@*9hr$&NU1zN&R@bFJQa6^V{ovAK11Qr#-` z_4T*H`A8_;pIo~*&wHkul$GHbOPT&Now6O-vFzN42+E($Q#J21 z#O}!f(O0+j&c055%)M&ZN{I4<<7)ilM>2m2ncSAp)XZ1euO5jySfzO|m3CA>xvwe8 z*XA+x!U5eEdX(bW-w4Dud(Ms<7AQ^j^z^VQfQ;*Zha4uRm51cW#F$0jQe2u96*s97 zY{_DmGvytK0FoU6pRx$iRT)sUhW@a?`6M#8ctQuOt(%8jUX2Z?w_&7xeSM9AA-sRF zDw7ITR>ErYyXiQ}<|J%dMt0_!hdI^nk8pNti}IPf1Y`D|h@eZu0l3L7;>jx4`#Uo! z6^RcYoaEkF3hEvlGgkHANJxt<(50lMomSaVnbP7K0CiW6l2QGX2k2nHRCD#E>OQMM z>@qHK6U$vBRG1wzDwxMQC6gh%*|SV@wxJB$h^YF~@!*FaK{ly8p1lcv8KT7`0G|R6 zuIm*p_Vo927*-&@FT66IrTcXA=1uQezZf18Ek6>Ze9U1u2)8D%_OZO2!wnVs)#3&z zMIY|d3kQd`w?8s5-xjQncRmkOHi@|DOPF%n2Et-%jk$vgLAF05;GO+_wld@mqWDb)Qd~=e; z*jKD4cr9TX7gwZrU$l)#H->9I3&2{K%wwk%ka`VB23;S@kS|=1F393Mpem^?G$~M% zP%HQ4|BNMvzmLkxxXp1Go1*4<r#^-Up&=<3*Dh$-kfX^!7m& z6{s;cUJF9=60LM_9P+8GI|?B`JINTh*hCXdWE19qzFzHz@ZmZds+qEb!8RG*pNmw? z^ogXG2s_r_p2sa7^OkRA3%nZ>S|P|@DP-vBI?F+EhO4v2q9y!rmP?3{gx9g^IEIE} zt?$S7koc-&`%2JDnSsCuR%H_V-mH9DcM)Xb?cL|c6qY18w;#5t0RKwyE`d~K>Z(~i zzL`{NnfkN4maXHVFhB<4Ia5~*>5||8S`^+1dt+W>X>_UT_V~8W1k-TJyGIjLvh8gc zYNe5PJ?4!FBP;63oA}~7?j=o4O->`fT{-lr-GIE(3$!Qa8q__=|_qdEC!CRlYP1nv{-Wkp^xHodP@CN(+@-gXl!?=mLNVGbP zOt=;~+ZYe}{MNL>(MSPk2^Fm#8$_`+QDlf&n1RGN;aLkO&6OK%Y^3tIkNn*HGSFMm zu9c)J4Nwthe1h4{Q$w1&1xfsLbW!UcTctD=OO6(%AU(@><1}_(x?oX}zvFV+#Y%Ju z{lNzMv2tihL4(Xsa*O0K40f-aqN%@4n+S^=TRXt#o9Tr#gPobHcMZ?yD|_NuP=oeF zw_A3*3j$N^&R>hXuo|eIB!51NX(~4=s8T*9rlQq33BCVLY70L*73pdvrWlic<}|%b zzH<%cZ3c9HW7CSt4g3;C(ZJ&B9m^oTWHn{uWE`I;OyiV{Kg8 zo#+UK*?l8D4mtNOzr5|kZdq&VF(aC}FpMQKME1n((=KTJtckmy?N4z(OJIAZR_CSmrX4ye^Rup884#?l+=4bK0XHxAjejiSUxgwkf&(qP zFto#2lHPSVr@HM5=fMQ-JH|QX2A0*PycWX8bz&d)?B0aDiXd4BTp*{!{eSK|P9q1a zte+a%|MDRl<-@p2>niLvcB|*e^zOv2EhtZ)bsyn!X!`}5EQ|r9UL`^eEaWc(o?AXP zpN)5T_#dzG17-T*xYb}q=*ho0R(MjI+kM6=4g<8_FsKBE?iYcD5W~!F`LZJ5 z(7fBIY7-5QcZ_Y=XkRQ8N(q6~%&mCNxEP1itW}*%u>3%I>e0WAw_?N6tc>A&K?~}!e zCtBtXho!w7!XM(|;vkM9tTM*%y$KU_ix&JO3%c#)A?FReCB>LNxTchLN;k$Cn+<7| zUM4w(OEk?(wp26syuZ93rZ%-#O|6m)(3oGF8akZes)E%&mBU@AGF~S$`DMjV@{#`i zi;xwa@g#EGP+ST>NvFyI&fAVsa?*p97)FYjk7klZTk}PB8A`$^17f54nQ8la2Wb>; zsdu}s-yRlOZb)~RP2|mPP&n74!smGi*I%S^^A=D`ok?qW=g6IwO!>C2a}qjlN-JxOJnx+;K^Urk7$X$p+e8BAJ9zEZ*33F#x@p0Zyw zkyF2n8hA(f!SAJ?u;mf7I@2MV49%D6p&#yk;Nc?*@zT-~WLa=fb{R}%1k}Y~jd!w5 zV$)ZPM)Rx3=dvG~s;Ax~aK=-3F%yLm8(6fY-Q#S}=*w1$Uo>6M7BT?R3P2%3&EGBX42RutmQ2QX__&P_KxRqY!;1jN8CoP0QB#{TT?K2{?tj?PH za7NL9uqJLWDD4hDJa;m5;pCoK8y^tJs(Z^W*Gbr6O5*72GW|l_dm)i3_9AzACDVnv z{cF7r#e_1?xBkW(zwSVZugAOeTW85*1P4TxSv`yNSoF-D4!05= zwD4vvEy?xQN;GF`58lDDAF8-rR4h}Z3gZ=w=_6C^79Nw(==u~|Z?u8GCSHBRs>3@atw1ja*hz zj_4tj*T<&&gwf7!tgHF+BPTv}J~Cx0-zIb&@_IxOxtiUwumKfT5+TL>$VM@!*?#_Vx`>2i^;N;f|N;u(bFZXtWFXI{3GuVsfcu>EA Yli1bnW98{Le}3WUYa2sqHQ|x}0Zy~9-v9sr diff --git a/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinjaTrigger.node.ts b/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinjaTrigger.node.ts index 924b3947dc..f84982c0f1 100644 --- a/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinjaTrigger.node.ts +++ b/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinjaTrigger.node.ts @@ -10,7 +10,7 @@ import { } from 'n8n-workflow'; import { - invoiceninjaApiRequest, + invoiceNinjaApiRequest, } from './GenericFunctions'; export class InvoiceNinjaTrigger implements INodeType { @@ -29,26 +29,8 @@ export class InvoiceNinjaTrigger implements INodeType { outputs: ['main'], credentials: [ { - name: 'invoiceNinjaCloudApi', + name: 'invoiceNinjaApi', required: true, - displayOptions: { - show: { - invoiceNinjaVersion: [ - 'cloud', - ], - }, - }, - }, - { - name: 'invoiceNinjaServerApi', - required: true, - displayOptions: { - show: { - invoiceNinjaVersion: [ - 'server', - ], - }, - }, }, ], webhooks: [ @@ -60,45 +42,29 @@ export class InvoiceNinjaTrigger implements INodeType { }, ], properties: [ - { - displayName: 'Version', - name: 'invoiceNinjaVersion', - type: 'options', - options: [ - { - name: 'Cloud', - value: 'cloud', - }, - { - name: 'Server (Self Hosted)', - value: 'server', - }, - ], - default: 'cloud', - }, { displayName: 'Event', name: 'event', type: 'options', options: [ { - name: 'client.created', + name: 'Client Created', value: 'create_client', }, { - name: 'invoce.created', + name: 'Invoice Created', value: 'create_invoice', }, { - name: 'payment.created', + name: 'Payment Created', value: 'create_payment', }, { - name: 'quote.created', + name: 'Quote Created', value: 'create_quote', }, { - name: 'vendor.created', + name: 'Vendor Created', value: 'create_vendor', }, ], @@ -126,7 +92,7 @@ export class InvoiceNinjaTrigger implements INodeType { event, }; - const responseData = await invoiceninjaApiRequest.call(this, 'POST', endpoint, body); + const responseData = await invoiceNinjaApiRequest.call(this, 'POST', endpoint, body); if (responseData.id === undefined) { // Required data is missing so was not successful @@ -145,7 +111,7 @@ export class InvoiceNinjaTrigger implements INodeType { const endpoint = `/hooks/${webhookData.webhookId}`; try { - await invoiceninjaApiRequest.call(this, 'DELETE', endpoint); + await invoiceNinjaApiRequest.call(this, 'DELETE', endpoint); } catch (e) { return false; } diff --git a/packages/nodes-base/nodes/InvoiceNinja/PaymentDescription.ts b/packages/nodes-base/nodes/InvoiceNinja/PaymentDescription.ts index e3e2763f14..baa24a495a 100644 --- a/packages/nodes-base/nodes/InvoiceNinja/PaymentDescription.ts +++ b/packages/nodes-base/nodes/InvoiceNinja/PaymentDescription.ts @@ -18,6 +18,11 @@ export const paymentOperations = [ value: 'create', description: 'Create a new payment', }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a payment', + }, { name: 'Get', value: 'get', @@ -28,11 +33,6 @@ export const paymentOperations = [ value: 'getAll', description: 'Get data of all payments', }, - { - name: 'Delete', - value: 'delete', - description: 'Delete a payment', - } ], default: 'create', description: 'The operation to perform.', diff --git a/packages/nodes-base/nodes/InvoiceNinja/QuoteDescription.ts b/packages/nodes-base/nodes/InvoiceNinja/QuoteDescription.ts index 5bdf4ab87d..142cbcd782 100644 --- a/packages/nodes-base/nodes/InvoiceNinja/QuoteDescription.ts +++ b/packages/nodes-base/nodes/InvoiceNinja/QuoteDescription.ts @@ -18,6 +18,11 @@ export const quoteOperations = [ value: 'create', description: 'Create a new quote', }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a quote', + }, { name: 'Email', value: 'email', @@ -33,11 +38,6 @@ export const quoteOperations = [ value: 'getAll', description: 'Get data of all quotes', }, - { - name: 'Delete', - value: 'delete', - description: 'Delete a quote', - } ], default: 'create', description: 'The operation to perform.', @@ -117,8 +117,8 @@ export const quoteFields = [ default: '', }, { - displayName: 'Email Qoute', - name: 'emailQoute', + displayName: 'Email Quote', + name: 'emailQuote', type: 'boolean', default: false, }, @@ -135,7 +135,7 @@ export const quoteFields = [ default: '', }, { - displayName: 'Qoute Status', + displayName: 'Quote Status', name: 'quoteStatus', type: 'options', options: [ @@ -351,7 +351,7 @@ export const quoteFields = [ /* quote:get */ /* -------------------------------------------------------------------------- */ { - displayName: 'Qoute ID', + displayName: 'Quote ID', name: 'quoteId', type: 'string', required: true, @@ -459,7 +459,7 @@ export const quoteFields = [ }, options: [ { - displayName: 'Qoute Number', + displayName: 'Quote Number', name: 'quoteNumber', type: 'string', default: '', diff --git a/packages/nodes-base/nodes/InvoiceNinja/TaskDescription.ts b/packages/nodes-base/nodes/InvoiceNinja/TaskDescription.ts index a3c608fc9e..f03ffb9bb6 100644 --- a/packages/nodes-base/nodes/InvoiceNinja/TaskDescription.ts +++ b/packages/nodes-base/nodes/InvoiceNinja/TaskDescription.ts @@ -18,6 +18,11 @@ export const taskOperations = [ value: 'create', description: 'Create a new task', }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a task', + }, { name: 'Get', value: 'get', @@ -28,11 +33,6 @@ export const taskOperations = [ value: 'getAll', description: 'Get data of all tasks', }, - { - name: 'Delete', - value: 'delete', - description: 'Delete a task', - } ], default: 'create', description: 'The operation to perform.', diff --git a/packages/nodes-base/nodes/InvoiceNinja/invoiceNinja.png b/packages/nodes-base/nodes/InvoiceNinja/invoiceNinja.png new file mode 100644 index 0000000000000000000000000000000000000000..50c5ac69ca294601d53c210b16683f5f1ed8c08b GIT binary patch literal 1109 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw3=&b&bYNg$%n0xaaRqX@n3(Y(PG%N7vQ(G) z|NlSGNtVVYJsq8_3=ASXd=Kv5XJ=qswS4*eckdQ2Txe!!_~ZNc-8*+qoisT#D9F;( zjE9}$?wz~m&YoSnYSpai(D$ScT7N=l1MhzSS^^74NE z{Q3H|YexIEHu}e|s&p__l$>fx>nv zttGxQCmHdm=;rM;Fy5Bmv4Hao?d+T-{&-)U8z&E zyml`(+!H!WJndkyu(#OKnpHRD*w-8To?cS5)`NZ4oyp1HeHw1O(7L_qID_t0tHbM< zI-gxrSu5tT%}_b9oMEx=uGsmkYp#UsVVR+sar+*tQIrDz>>|02j~(+Ej-1$>Cb*ts zWrWI`&Kqo96^G_cI^W^myW@+Pfb(0gk1|45+|#3N4ozOBD7)1u#vjc1Is(uUl?95 zaK3R=nZ@S%(H#L&oHZ;?cM7MuYm~9XZ)j?8|7EacdcZT0GA-qJMyJd*FB0eMo}~56 z)@-}-#6RzvEN*H)PU1+7V)A-8KceEXDc{dOSDRj|NSsg0DN~DkaagbY@{614AJVlWCUj{?arvDzw3Tdi|rvL1>%V*EmP?eKny0@vZ z