mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-14 16:44:07 -08:00
⚡ Improvements
This commit is contained in:
parent
be11ff473a
commit
1577322a2a
|
@ -1,4 +1,6 @@
|
||||||
import { INodeProperties } from 'n8n-workflow';
|
import {
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export const documentOperations = [
|
export const documentOperations = [
|
||||||
{
|
{
|
||||||
|
@ -51,7 +53,10 @@ export const documentFields = [
|
||||||
{
|
{
|
||||||
displayName: 'DocType',
|
displayName: 'DocType',
|
||||||
name: 'docType',
|
name: 'docType',
|
||||||
type: 'string',
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getDocTypes',
|
||||||
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The DocType of which the documents you want to get.',
|
description: 'The DocType of which the documents you want to get.',
|
||||||
placeholder: 'Customer',
|
placeholder: 'Customer',
|
||||||
|
@ -98,8 +103,8 @@ export const documentFields = [
|
||||||
'getAll',
|
'getAll',
|
||||||
],
|
],
|
||||||
returnAll: [
|
returnAll: [
|
||||||
false
|
false,
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -123,7 +128,13 @@ export const documentFields = [
|
||||||
{
|
{
|
||||||
displayName: 'Fields',
|
displayName: 'Fields',
|
||||||
name: 'fields',
|
name: 'fields',
|
||||||
type: 'string',
|
type: 'multiOptions',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getDocFields',
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'docType',
|
||||||
|
],
|
||||||
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'Comma separated fields you wish returned.',
|
description: 'Comma separated fields you wish returned.',
|
||||||
placeholder: 'name,country'
|
placeholder: 'name,country'
|
||||||
|
@ -141,14 +152,6 @@ export const documentFields = [
|
||||||
displayName: 'Property',
|
displayName: 'Property',
|
||||||
name: 'customProperty',
|
name: 'customProperty',
|
||||||
values: [
|
values: [
|
||||||
{
|
|
||||||
displayName: 'DocType',
|
|
||||||
name: 'docType',
|
|
||||||
type: 'string',
|
|
||||||
default: '',
|
|
||||||
description: 'The DocType you would like to receive.',
|
|
||||||
placeholder: 'Customer'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
displayName: 'Field',
|
displayName: 'Field',
|
||||||
name: 'field',
|
name: 'field',
|
||||||
|
@ -210,8 +213,11 @@ export const documentFields = [
|
||||||
{
|
{
|
||||||
displayName: 'DocType',
|
displayName: 'DocType',
|
||||||
name: 'docType',
|
name: 'docType',
|
||||||
type: 'string',
|
type: 'options',
|
||||||
default: '',
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getDocTypes',
|
||||||
|
},
|
||||||
description: 'DocType you would like to create.',
|
description: 'DocType you would like to create.',
|
||||||
placeholder: 'Customer',
|
placeholder: 'Customer',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
|
@ -220,7 +226,7 @@ export const documentFields = [
|
||||||
'document',
|
'document',
|
||||||
],
|
],
|
||||||
operation: [
|
operation: [
|
||||||
'create'
|
'create',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -252,7 +258,13 @@ export const documentFields = [
|
||||||
{
|
{
|
||||||
displayName: 'Field',
|
displayName: 'Field',
|
||||||
name: 'field',
|
name: 'field',
|
||||||
type: 'string',
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getDocFields',
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'docType',
|
||||||
|
],
|
||||||
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'Name of field.',
|
description: 'Name of field.',
|
||||||
placeholder: 'Name'
|
placeholder: 'Name'
|
||||||
|
@ -275,7 +287,10 @@ export const documentFields = [
|
||||||
{
|
{
|
||||||
displayName: 'DocType',
|
displayName: 'DocType',
|
||||||
name: 'docType',
|
name: 'docType',
|
||||||
type: 'string',
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getDocTypes',
|
||||||
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The type of document you would like to get.',
|
description: 'The type of document you would like to get.',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
|
@ -314,7 +329,10 @@ export const documentFields = [
|
||||||
{
|
{
|
||||||
displayName: 'DocType',
|
displayName: 'DocType',
|
||||||
name: 'docType',
|
name: 'docType',
|
||||||
type: 'string',
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getDocTypes',
|
||||||
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The type of document you would like to delete.',
|
description: 'The type of document you would like to delete.',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
|
@ -353,7 +371,10 @@ export const documentFields = [
|
||||||
{
|
{
|
||||||
displayName: 'DocType',
|
displayName: 'DocType',
|
||||||
name: 'docType',
|
name: 'docType',
|
||||||
type: 'string',
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getDocTypes',
|
||||||
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The type of document you would like to update',
|
description: 'The type of document you would like to update',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
|
@ -413,7 +434,13 @@ export const documentFields = [
|
||||||
{
|
{
|
||||||
displayName: 'Field',
|
displayName: 'Field',
|
||||||
name: 'field',
|
name: 'field',
|
||||||
type: 'string',
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getDocFields',
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'docType',
|
||||||
|
],
|
||||||
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'Name of field.',
|
description: 'Name of field.',
|
||||||
placeholder: 'Name'
|
placeholder: 'Name'
|
||||||
|
|
|
@ -1,15 +1,26 @@
|
||||||
import {
|
import {
|
||||||
IExecuteFunctions,
|
IExecuteFunctions,
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
ILoadOptionsFunctions,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
IDataObject,
|
IDataObject,
|
||||||
|
INodePropertyOptions,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { documentOperations, documentFields } from './DocumentDescription';
|
|
||||||
import { erpNextApiRequest, erpNextApiRequestAllItems } from './GenericFunctions';
|
|
||||||
|
|
||||||
|
import {
|
||||||
|
documentOperations,
|
||||||
|
documentFields
|
||||||
|
} from './DocumentDescription';
|
||||||
|
|
||||||
|
import {
|
||||||
|
erpNextApiRequest,
|
||||||
|
erpNextApiRequestAllItems
|
||||||
|
} from './GenericFunctions';
|
||||||
|
import { filter } from 'rhea';
|
||||||
|
|
||||||
export class ERPNext implements INodeType {
|
export class ERPNext implements INodeType {
|
||||||
description: INodeTypeDescription = {
|
description: INodeTypeDescription = {
|
||||||
|
@ -74,13 +85,65 @@ export class ERPNext implements INodeType {
|
||||||
default: 'document',
|
default: 'document',
|
||||||
description: 'Resource to consume.',
|
description: 'Resource to consume.',
|
||||||
},
|
},
|
||||||
|
|
||||||
// DOCUMENT
|
// DOCUMENT
|
||||||
...documentOperations,
|
...documentOperations,
|
||||||
...documentFields
|
...documentFields
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
methods = {
|
||||||
|
loadOptions: {
|
||||||
|
// Get all the doc types to display them to user so that he can
|
||||||
|
// select them easily
|
||||||
|
async getDocTypes(
|
||||||
|
this: ILoadOptionsFunctions
|
||||||
|
): Promise<INodePropertyOptions[]> {
|
||||||
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
const types = await erpNextApiRequestAllItems.call(
|
||||||
|
this,
|
||||||
|
'data',
|
||||||
|
'GET',
|
||||||
|
'/api/resource/DocType',
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
for (const type of types) {
|
||||||
|
const typeName = type.name;
|
||||||
|
const typeId = type.name;
|
||||||
|
returnData.push({
|
||||||
|
name: typeName,
|
||||||
|
value: typeId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return returnData;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Get all the doc fields to display them to user so that he can
|
||||||
|
// select them easily
|
||||||
|
async getDocFields(
|
||||||
|
this: ILoadOptionsFunctions
|
||||||
|
): Promise<INodePropertyOptions[]> {
|
||||||
|
const docId = this.getCurrentNodeParameter('docType') as string;
|
||||||
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
const { data } = await erpNextApiRequest.call(
|
||||||
|
this,
|
||||||
|
'GET',
|
||||||
|
`/api/resource/DocType/${docId}`,
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
for (const field of data.fields) {
|
||||||
|
const fieldName = field.label;
|
||||||
|
const fieldId = field.fieldname;
|
||||||
|
returnData.push({
|
||||||
|
name: fieldName,
|
||||||
|
value: fieldId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return returnData;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||||
const items = this.getInputData();
|
const items = this.getInputData();
|
||||||
const returnData: IDataObject[] = [];
|
const returnData: IDataObject[] = [];
|
||||||
|
@ -91,6 +154,8 @@ export class ERPNext implements INodeType {
|
||||||
const resource = this.getNodeParameter('resource', 0) as string;
|
const resource = this.getNodeParameter('resource', 0) as string;
|
||||||
const operation = this.getNodeParameter('operation', 0) as string;
|
const operation = this.getNodeParameter('operation', 0) as string;
|
||||||
for (let i = 0; i < length; i++) {
|
for (let i = 0; i < length; i++) {
|
||||||
|
//https://app.swaggerhub.com/apis-docs/alyf.de/ERPNext/11#/Resources/post_api_resource_Webhook
|
||||||
|
//https://frappeframework.com/docs/user/en/guides/integration/rest_api/manipulating_documents
|
||||||
if (resource === 'document') {
|
if (resource === 'document') {
|
||||||
if (operation === 'get') {
|
if (operation === 'get') {
|
||||||
const docType = this.getNodeParameter('docType', i) as string;
|
const docType = this.getNodeParameter('docType', i) as string;
|
||||||
|
@ -99,6 +164,8 @@ export class ERPNext implements INodeType {
|
||||||
const endpoint = `/api/resource/${docType}/${documentName}`;
|
const endpoint = `/api/resource/${docType}/${documentName}`;
|
||||||
|
|
||||||
responseData = await erpNextApiRequest.call(this, 'GET', endpoint, {});
|
responseData = await erpNextApiRequest.call(this, 'GET', endpoint, {});
|
||||||
|
|
||||||
|
responseData = responseData.data;
|
||||||
}
|
}
|
||||||
if (operation === 'getAll') {
|
if (operation === 'getAll') {
|
||||||
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||||
|
@ -106,79 +173,49 @@ export class ERPNext implements INodeType {
|
||||||
|
|
||||||
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||||
|
|
||||||
let endpoint = `/api/resource/${docType}`;
|
const endpoint = `/api/resource/${docType}`;
|
||||||
|
|
||||||
// Add field options for query. FORMAT: fields=["test", "example", "hi"]
|
// Add field options for query. FORMAT: fields=["test", "example", "hi"]
|
||||||
if (additionalFields.fields as string) {
|
if (additionalFields.fields) {
|
||||||
let newString : string = '';
|
qs.fields = JSON.stringify(additionalFields.fields as string[]);
|
||||||
let fields = (additionalFields.fields as string).split(',');
|
|
||||||
console.log(fields.length);
|
|
||||||
|
|
||||||
fields.map((field, idx) => {
|
|
||||||
newString = newString + `"${field}",`
|
|
||||||
});
|
|
||||||
// Remove excessive comma at end
|
|
||||||
newString = newString.substring(0, newString.length - 1);
|
|
||||||
|
|
||||||
endpoint = `${endpoint}/?fields=[${newString}]`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add filter options for query. FORMAT: filters=[["Person","first_name","=","Jane"]]
|
// Add filter options for query. FORMAT: filters=[["Person","first_name","=","Jane"]]
|
||||||
if (additionalFields.filters) {
|
if (additionalFields.filters) {
|
||||||
let newString : string = '';
|
|
||||||
const filters = (additionalFields.filters as IDataObject).customProperty as IDataObject[];
|
|
||||||
|
|
||||||
filters.map(filter => {
|
const operators: { [key: string]: string } = {
|
||||||
let operator : string = '';
|
'is': '=',
|
||||||
// Operators cannot be used as options in Document description, so must use words and then convert here
|
'isNot': '!=',
|
||||||
switch(filter.operator) {
|
'greater': '>',
|
||||||
case 'is':
|
'less': '<',
|
||||||
operator = '=';
|
'equalsGreater': '>=',
|
||||||
break;
|
'equalsLess': '<=',
|
||||||
case 'isNot':
|
};
|
||||||
operator = '!=';
|
|
||||||
break;
|
|
||||||
case 'greater':
|
|
||||||
operator = '>';
|
|
||||||
break;
|
|
||||||
case 'less':
|
|
||||||
operator = '<';
|
|
||||||
break;
|
|
||||||
case 'equalsGreater':
|
|
||||||
operator = '>=';
|
|
||||||
break;
|
|
||||||
case 'equalsLess':
|
|
||||||
operator = '<=';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
newString = newString + `["${filter.docType}","${filter.field}","${operator}","${filter.value}"],`
|
|
||||||
});
|
|
||||||
// Remove excessive comma at end
|
|
||||||
newString = newString.substring(0, newString.length - 1);
|
|
||||||
|
|
||||||
// Ensure correct URL based on which queries active
|
const filterValues = (additionalFields.filters as IDataObject).customProperty as IDataObject[];
|
||||||
if (additionalFields.fields) {
|
const filters: string[][] = [];
|
||||||
endpoint = `${endpoint}&filters=[${newString}]`;
|
for (const filter of filterValues) {
|
||||||
} else {
|
const data = [
|
||||||
endpoint = `${endpoint}/?filters=[${newString}]`;
|
docType,
|
||||||
|
filter.field as string,
|
||||||
|
operators[filter.operator as string],
|
||||||
|
filter.value as string,
|
||||||
|
];
|
||||||
|
filters.push(data);
|
||||||
}
|
}
|
||||||
|
qs.filters = filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!returnAll) {
|
if (!returnAll) {
|
||||||
|
|
||||||
const limit = this.getNodeParameter('limit', i) as number;
|
const limit = this.getNodeParameter('limit', i) as number;
|
||||||
if (additionalFields.fields || additionalFields.filters) {
|
qs.limit_page_lengt = limit;
|
||||||
endpoint = `${endpoint}&limit_page_length=${limit}`
|
qs.limit_start = 1;
|
||||||
} else {
|
responseData = await erpNextApiRequest.call(this, 'GET', endpoint, {}, qs);
|
||||||
endpoint = `${endpoint}/?limit_page_length=${limit}`
|
responseData = responseData.data;
|
||||||
}
|
|
||||||
responseData = await erpNextApiRequest.call(this, 'GET', endpoint, {});
|
|
||||||
} else {
|
} else {
|
||||||
if (additionalFields.fields || additionalFields.filters) {
|
responseData = await erpNextApiRequestAllItems.call(this, 'data', 'GET', endpoint, {}, qs);
|
||||||
endpoint = `${endpoint}&limit_start=`
|
|
||||||
} else {
|
|
||||||
endpoint = `${endpoint}/?limit_start=`
|
|
||||||
}
|
|
||||||
responseData = await erpNextApiRequestAllItems.call(this, 'GET', endpoint, {});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (operation === 'create') {
|
if (operation === 'create') {
|
||||||
|
@ -186,17 +223,16 @@ export class ERPNext implements INodeType {
|
||||||
const endpoint = `/api/resource/${docType}`;
|
const endpoint = `/api/resource/${docType}`;
|
||||||
|
|
||||||
const properties = this.getNodeParameter('properties', i) as IDataObject;
|
const properties = this.getNodeParameter('properties', i) as IDataObject;
|
||||||
|
|
||||||
if (properties) {
|
if (properties) {
|
||||||
const fieldsValues = (properties as IDataObject).customProperty as IDataObject[];
|
const fieldsValues = (properties as IDataObject).customProperty as IDataObject[];
|
||||||
|
for (const fieldValue of fieldsValues) {
|
||||||
fieldsValues.map(item => {
|
body[fieldValue.field as string] = fieldValue.value;
|
||||||
//@ts-ignore
|
}
|
||||||
body[item.field] = item.value;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
responseData = await erpNextApiRequest.call(this, 'POST', endpoint, body);
|
responseData = await erpNextApiRequest.call(this, 'POST', endpoint, body);
|
||||||
|
responseData = responseData.data;
|
||||||
}
|
}
|
||||||
if (operation === 'delete') {
|
if (operation === 'delete') {
|
||||||
const docType = this.getNodeParameter('docType', i) as string;
|
const docType = this.getNodeParameter('docType', i) as string;
|
||||||
|
@ -212,22 +248,19 @@ export class ERPNext implements INodeType {
|
||||||
const endpoint = `/api/resource/${docType}/${documentName}`;
|
const endpoint = `/api/resource/${docType}/${documentName}`;
|
||||||
|
|
||||||
const properties = this.getNodeParameter('properties', i) as IDataObject;
|
const properties = this.getNodeParameter('properties', i) as IDataObject;
|
||||||
|
|
||||||
|
|
||||||
if (properties) {
|
if (properties) {
|
||||||
const fieldsValues = (properties as IDataObject).customProperty as IDataObject[];
|
const fieldsValues = (properties as IDataObject).customProperty as IDataObject[];
|
||||||
|
for (const fieldValue of fieldsValues) {
|
||||||
fieldsValues.map(item => {
|
body[fieldValue.field as string] = fieldValue.value;
|
||||||
//@ts-ignore
|
}
|
||||||
body[item.field] = item.value;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
responseData = await erpNextApiRequest.call(this, 'PUT', endpoint, body);
|
responseData = await erpNextApiRequest.call(this, 'PUT', endpoint, body);
|
||||||
|
responseData = responseData.data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (Array.isArray(responseData)) {
|
if (Array.isArray(responseData)) {
|
||||||
returnData.push.apply(returnData, responseData as IDataObject[]);
|
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import { OptionsWithUri } from 'request';
|
import {
|
||||||
|
OptionsWithUri,
|
||||||
|
} from 'request';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IExecuteFunctions,
|
IExecuteFunctions,
|
||||||
|
@ -12,16 +14,6 @@ import {
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
export async function erpNextApiRequest(this: IExecuteFunctions | IWebhookFunctions | IHookFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, query: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
export async function erpNextApiRequest(this: IExecuteFunctions | IWebhookFunctions | IHookFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, query: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
let options: OptionsWithUri = {
|
|
||||||
headers: {'Accept': 'application/json'},
|
|
||||||
method,
|
|
||||||
body,
|
|
||||||
qs: query,
|
|
||||||
uri: uri || ``,
|
|
||||||
json: true
|
|
||||||
};
|
|
||||||
|
|
||||||
options = Object.assign({}, options, option);
|
|
||||||
|
|
||||||
const credentials = this.getCredentials('erpNextApi');
|
const credentials = this.getCredentials('erpNextApi');
|
||||||
|
|
||||||
|
@ -29,31 +21,58 @@ export async function erpNextApiRequest(this: IExecuteFunctions | IWebhookFuncti
|
||||||
throw new Error('No credentials got returned!');
|
throw new Error('No credentials got returned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
options.headers!['Authorization'] = `token ${credentials.apiKey}:${credentials.apiSecret}`;
|
let options: OptionsWithUri = {
|
||||||
options.uri = `https://${credentials.subdomain}.erpnext.com${resource}`;
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
method,
|
||||||
|
body,
|
||||||
|
qs: query,
|
||||||
|
uri: uri || `https://${credentials.subdomain}.erpnext.com${resource}`,
|
||||||
|
json: true,
|
||||||
|
};
|
||||||
|
|
||||||
return await this.helpers.request!(options);
|
options = Object.assign({}, options, option);
|
||||||
|
|
||||||
|
console.log(options);
|
||||||
|
|
||||||
|
options.headers!['Authorization'] = `token ${credentials.apiKey}:${credentials.apiSecret}`;
|
||||||
|
|
||||||
|
if (Object.keys(body).length === 0) {
|
||||||
|
delete options.body;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return await this.helpers.request!(options);
|
||||||
|
} catch (error) {
|
||||||
|
let errorMessages;
|
||||||
|
if (error.response && error.response.body && error.response.body._server_messages) {
|
||||||
|
const errors = JSON.parse(error.response.body._server_messages);
|
||||||
|
errorMessages = errors.map((e: string) => JSON.parse(e).message);
|
||||||
|
throw new Error(
|
||||||
|
`ARPNext error response [${error.statusCode}]: ${errorMessages.join('|')}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function erpNextApiRequestAllItems(this: IHookFunctions | IExecuteFunctions, method: string, endpoint: string, body: IDataObject, query?: IDataObject): Promise<any> { // tslint:disable-line:no-any
|
export async function erpNextApiRequestAllItems(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions , propertyName: string, method: string, resource: string, body: IDataObject, query: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
const limit : number = 100;
|
|
||||||
const returnData: IDataObject[] = [];
|
const returnData: IDataObject[] = [];
|
||||||
|
|
||||||
let responseData;
|
let responseData;
|
||||||
let index : number = 0;
|
query!.limit_start = 1;
|
||||||
|
query!.limit_page_lengt = 20;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
endpoint = `${endpoint}${index}`;
|
responseData = await erpNextApiRequest.call(this, method, resource, body, query);
|
||||||
responseData = await erpNextApiRequest.call(this, method, endpoint, body, query);
|
returnData.push.apply(returnData, responseData[propertyName]);
|
||||||
returnData.push.apply(returnData, responseData.data);
|
query!.limit_start += query!.limit_page_lengt - 1;
|
||||||
|
|
||||||
index = index + limit;
|
|
||||||
} while (
|
} while (
|
||||||
responseData.data.length !== 0
|
responseData.data.length !== 0
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return returnData;
|
||||||
data: returnData
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue