From 530bafd2bc393512a785f7b2e3cece03a490b2cc Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Mon, 24 Feb 2020 19:19:04 -0500 Subject: [PATCH] :sparkles: added order resource --- .../nodes/WooCommerce/GenericFunctions.ts | 63 +- .../nodes/WooCommerce/OrderDescription.ts | 1701 +++++++++++++++++ .../nodes/WooCommerce/OrderInterface.ts | 65 + .../nodes/WooCommerce/WooCommerce.node.ts | 219 ++- 4 files changed, 2046 insertions(+), 2 deletions(-) create mode 100644 packages/nodes-base/nodes/WooCommerce/OrderDescription.ts create mode 100644 packages/nodes-base/nodes/WooCommerce/OrderInterface.ts diff --git a/packages/nodes-base/nodes/WooCommerce/GenericFunctions.ts b/packages/nodes-base/nodes/WooCommerce/GenericFunctions.ts index 776cb6a4f9..ee254ec1ed 100644 --- a/packages/nodes-base/nodes/WooCommerce/GenericFunctions.ts +++ b/packages/nodes-base/nodes/WooCommerce/GenericFunctions.ts @@ -1,5 +1,7 @@ import { OptionsWithUri } from 'request'; import { createHash } from 'crypto'; +import { snakeCase } from 'change-case'; + import { IExecuteFunctions, IExecuteSingleFunctions, @@ -7,7 +9,16 @@ import { ILoadOptionsFunctions, IWebhookFunctions, } from 'n8n-core'; -import { IDataObject, ICredentialDataDecryptedObject } from 'n8n-workflow'; +import { + IDataObject, + ICredentialDataDecryptedObject +} from 'n8n-workflow'; +import { + IShoppingLine, + IFeeLine, + ILineItem, + ICouponLine +} from './OrderInterface'; export async function woocommerceApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IWebhookFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise { // tslint:disable-line:no-any const credentials = this.getCredentials('wooCommerceApi'); @@ -77,3 +88,53 @@ export function getAutomaticSecret(credentials: ICredentialDataDecryptedObject) const data = `${credentials.consumerKey},${credentials.consumerSecret}`; return createHash('md5').update(data).digest('hex'); } + +export function setMetadata(data: + IShoppingLine[] | + IShoppingLine[] | + IFeeLine[] | + ILineItem[] | + ICouponLine[]) { + for (let i = 0; i < data.length; i++) { + //@ts-ignore\ + if (data[i].metadataUi && data[i].metadataUi.metadataValues) { + //@ts-ignore + data[i].meta_data = data[i].metadataUi.metadataValues; + //@ts-ignore + delete data[i].metadataUi + console.log(data[i]); + } else { + //@ts-ignore + delete data[i].metadataUi; + } + } +} + +export function toSnakeCase(data: + IShoppingLine[] | + IShoppingLine[] | + IFeeLine[] | + ILineItem[] | + ICouponLine[] | + IDataObject) { + if (!Array.isArray(data)) { + data = [data]; + } + let remove = false; + for (let i = 0; i < data.length; i++) { + for (const key of Object.keys(data[i])) { + //@ts-ignore + if (data[i][snakeCase(key)] === undefined) { + remove = true; + } + //@ts-ignore + data[i][snakeCase(key)] = data[i][key] + if (remove) { + //@ts-ignore + delete data[i][key]; + remove = false; + } + } + } +} + diff --git a/packages/nodes-base/nodes/WooCommerce/OrderDescription.ts b/packages/nodes-base/nodes/WooCommerce/OrderDescription.ts new file mode 100644 index 0000000000..0dc8e51a6c --- /dev/null +++ b/packages/nodes-base/nodes/WooCommerce/OrderDescription.ts @@ -0,0 +1,1701 @@ +import { INodeProperties } from 'n8n-workflow'; + +export const orderOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'order', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + description: 'Create a order', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a order', + }, + { + name: 'Get', + value: 'get', + description: 'Get a order', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all orders', + }, + { + name: 'Update', + value: 'update', + description: 'Update a order', + }, + ], + default: 'create', + description: 'The operation to perform.', + }, +] as INodeProperties[]; + +export const orderFields = [ + +/* -------------------------------------------------------------------------- */ +/* order:create */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Currency', + name: 'currency', + type: 'string', + default: '', + description: 'Currency the order was created with', + }, + { + displayName: 'Customer ID', + name: 'customerId', + type: 'string', + default: '', + description: 'User ID who owns the order. 0 for guests', + }, + { + displayName: 'Customer Note', + name: 'customerNote', + type: 'string', + default: '', + typeOptions: { + alwaysOpenEditWindow: true, + }, + description: 'Note left by customer during checkout.', + }, + { + displayName: 'Parent ID', + name: 'parentId', + type: 'string', + default: '', + description: 'Parent order ID.', + }, + { + displayName: 'Payment Method ID', + name: 'paymentMethodId', + type: 'string', + default: '', + description: 'Payment method ID.', + }, + { + displayName: 'Payment Method Title', + name: 'paymentMethodTitle', + type: 'string', + default: '', + description: 'Payment method title.', + }, + { + displayName: 'Payment Method Title', + name: 'paymentMethodTitle', + type: 'string', + default: '', + description: 'Payment method title.', + }, + { + displayName: 'Set Paid', + name: 'setPaid', + type: 'boolean', + default: false, + description: 'Define if the order is paid. It will set the status to processing and reduce stock items', + }, + { + displayName: 'Status', + name: 'status', + type: 'options', + options: [ + { + name: 'completed', + value: 'completed', + }, + { + name: 'cancelled', + value: 'cancelled', + }, + { + name: 'failed', + value: 'failed', + }, + { + name: 'on-hold', + value: 'on-hold', + }, + { + name: 'pending', + value: 'pending', + }, + { + name: 'processing', + value: 'processing', + }, + { + name: 'refunded', + value: 'refunded', + }, + { + name: 'trash', + value: 'trash', + }, + ], + default: 'pending', + description: 'A named status for the order.', + }, + { + displayName: 'Transaction ID', + name: 'transactionID', + type: 'string', + default: '', + description: 'Unique transaction ID', + }, + ], + }, + { + displayName: 'Billing', + name: 'billingUi', + placeholder: 'Add Billing', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: false, + }, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'create', + ] + }, + }, + description: 'Billing address', + options: [ + { + name: 'billingValues', + displayName: 'Address', + values: [ + { + displayName: 'First Name', + name: 'firstName', + type: 'string', + default: '', + }, + { + displayName: 'Last Name', + name: 'lastName', + type: 'string', + default: '', + }, + { + displayName: 'Company', + name: 'company', + type: 'string', + default: '', + }, + { + displayName: 'Address Line 1', + name: 'address_1', + type: 'string', + default: '', + }, + { + displayName: 'Address Line 2', + name: 'address_2', + type: 'string', + default: '', + }, + { + displayName: 'City', + name: 'city', + type: 'string', + default: '', + description: 'ISO code or name of the state, province or district.', + }, + { + displayName: 'Postal Code', + name: 'postalCode', + type: 'string', + default: '', + }, + { + displayName: 'Country', + name: 'country', + type: 'string', + default: '', + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + default: '', + }, + { + displayName: 'Phone', + name: 'phone', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Coupon Lines', + name: 'couponLinesUi', + placeholder: 'Add Coupon Line', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'create', + ] + }, + }, + description: 'Coupons line data', + options: [ + { + name: 'couponLinesValues', + displayName: 'Coupon Line', + values: [ + { + displayName: 'Code', + name: 'code', + type: 'string', + default: '', + description: 'Coupon code.', + }, + { + displayName: 'Metadata', + name: 'metadataUi', + placeholder: 'Add Metadata', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + description: 'Meta data', + options: [ + { + name: 'metadataValues', + displayName: 'Metadata', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + description: 'Name of the metadata key to add.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Value to set for the metadata key.', + }, + ], + }, + ], + }, + ], + }, + ], + }, + { + displayName: 'Fee Lines', + name: 'feeLinesUi', + placeholder: 'Add Fee Line', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'create', + ] + }, + }, + description: 'Fee line data', + options: [ + { + name: 'feeLinesValues', + displayName: 'Fee Line', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + description: 'Fee name', + }, + { + displayName: 'Tax Class ', + name: 'taxClass', + type: 'string', + description: 'Tax class of fee.', + default: '', + }, + { + displayName: 'Tax Status ', + name: 'taxStatus', + type: 'options', + options: [ + { + name: 'Taxable', + value: 'taxable', + }, + { + name: 'None', + value: 'none', + }, + ], + default: '', + description: 'Tax class of fee.', + }, + { + displayName: 'Total ', + name: 'total', + type: 'string', + default: '', + description: 'Line total (after discounts).', + }, + { + displayName: 'Metadata', + name: 'metadataUi', + placeholder: 'Add Metadata', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + description: 'Meta data', + options: [ + { + name: 'metadataValues', + displayName: 'Metadata', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + description: 'Name of the metadata key to add.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Value to set for the metadata key.', + }, + ], + }, + ], + }, + ], + }, + ], + }, + { + displayName: 'Line Items', + name: 'lineItemsUi', + placeholder: 'Add Line Item', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'create', + ] + }, + }, + description: 'Line item data', + options: [ + { + name: 'lineItemsValues', + displayName: 'Line Item', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + description: 'Product name.', + }, + { + displayName: 'Product ID', + name: 'productId', + type: 'number', + default: 0, + description: 'Product ID.', + }, + { + displayName: 'Variation ID', + name: 'variationId', + type: 'number', + default: 0, + description: 'Variation ID, if applicable.', + }, + { + displayName: 'Quantity', + name: 'quantity', + type: 'number', + default: 1, + description: 'Quantity ordered.', + }, + { + displayName: 'Tax Class', + name: 'taxClass', + type: 'string', + default: '', + description: 'Slug of the tax class of product.', + }, + { + displayName: 'Subtotal', + name: 'subtotal', + type: 'string', + default: '', + description: 'Line subtotal (before discounts).', + }, + { + displayName: 'Total', + name: 'total', + type: 'string', + default: '', + description: 'Line total (after discounts).', + }, + { + displayName: 'Metadata', + name: 'metadataUi', + placeholder: 'Add Metadata', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + description: 'Meta data', + options: [ + { + name: 'metadataValues', + displayName: 'Metadata', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + description: 'Name of the metadata key to add.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Value to set for the metadata key.', + }, + ], + }, + ], + }, + ], + }, + ], + }, + { + displayName: 'Metadata', + name: 'metadataUi', + placeholder: 'Add Metadata', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'create', + ] + }, + }, + description: 'Meta data', + options: [ + { + name: 'metadataValues', + displayName: 'Metadata', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + description: 'Name of the metadata key to add.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Value to set for the metadata key.', + }, + ], + }, + ], + }, + { + displayName: 'Shipping', + name: 'shippingUi', + placeholder: 'Add Shipping', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: false, + }, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'create', + ] + }, + }, + description: 'Shipping address', + options: [ + { + name: 'shippingValues', + displayName: 'Address', + values: [ + { + displayName: 'First Name', + name: 'firstName', + type: 'string', + default: '', + }, + { + displayName: 'Last Name', + name: 'lastName', + type: 'string', + default: '', + }, + { + displayName: 'Company', + name: 'company', + type: 'string', + default: '', + }, + { + displayName: 'Address Line 1', + name: 'address_1', + type: 'string', + default: '', + }, + { + displayName: 'Address Line 2', + name: 'address_2', + type: 'string', + default: '', + }, + { + displayName: 'City', + name: 'city', + type: 'string', + default: '', + description: 'ISO code or name of the state, province or district.', + }, + { + displayName: 'Postal Code', + name: 'postalCode', + type: 'string', + default: '', + }, + { + displayName: 'Country', + name: 'country', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Shipping Lines', + name: 'shippingLinesUi', + placeholder: 'Add Shipping Line', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'create', + ] + }, + }, + description: 'Shipping line data', + options: [ + { + name: 'shippingLinesValues', + displayName: 'Fee Line', + values: [ + { + displayName: 'Method Title', + name: 'methodTitle', + type: 'string', + default: '', + description: 'Shipping method name', + }, + { + displayName: 'Method ID ', + name: 'method ID', + type: 'string', + description: 'Shipping method ID.', + default: '', + }, + { + displayName: 'Total ', + name: 'total', + type: 'string', + default: '', + description: 'Line total (after discounts).', + }, + { + displayName: 'Metadata', + name: 'metadataUi', + placeholder: 'Add Metadata', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + description: 'Meta data', + options: [ + { + name: 'metadataValues', + displayName: 'Metadata', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + description: 'Name of the metadata key to add.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Value to set for the metadata key.', + }, + ], + }, + ], + }, + ], + }, + ], + }, +/* -------------------------------------------------------------------------- */ +/* order:update */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Order ID', + name: 'orderId', + type: 'string', + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'update', + ], + }, + }, + default: '', + description: 'order ID.', + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + { + displayName: 'Currency', + name: 'currency', + type: 'string', + default: '', + description: 'Currency the order was created with', + }, + { + displayName: 'Customer ID', + name: 'customerId', + type: 'string', + default: '', + description: 'User ID who owns the order. 0 for guests', + }, + { + displayName: 'Customer Note', + name: 'customerNote', + type: 'string', + default: '', + typeOptions: { + alwaysOpenEditWindow: true, + }, + description: 'Note left by customer during checkout.', + }, + { + displayName: 'Parent ID', + name: 'parentId', + type: 'string', + default: '', + description: 'Parent order ID.', + }, + { + displayName: 'Payment Method ID', + name: 'paymentMethodId', + type: 'string', + default: '', + description: 'Payment method ID.', + }, + { + displayName: 'Payment Method Title', + name: 'paymentMethodTitle', + type: 'string', + default: '', + description: 'Payment method title.', + }, + { + displayName: 'Payment Method Title', + name: 'paymentMethodTitle', + type: 'string', + default: '', + description: 'Payment method title.', + }, + { + displayName: 'Status', + name: 'status', + type: 'options', + options: [ + { + name: 'completed', + value: 'completed', + }, + { + name: 'cancelled', + value: 'cancelled', + }, + { + name: 'failed', + value: 'failed', + }, + { + name: 'on-hold', + value: 'on-hold', + }, + { + name: 'pending', + value: 'pending', + }, + { + name: 'processing', + value: 'processing', + }, + { + name: 'refunded', + value: 'refunded', + }, + { + name: 'trash', + value: 'trash', + }, + ], + default: 'pending', + description: 'A named status for the order.', + }, + { + displayName: 'Transaction ID', + name: 'transactionID', + type: 'string', + default: '', + description: 'Unique transaction ID', + }, + ], + }, + { + displayName: 'Billing', + name: 'billingUi', + placeholder: 'Add Billing', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: false, + }, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'update', + ] + }, + }, + description: 'Billing address', + options: [ + { + name: 'billingValues', + displayName: 'Address', + values: [ + { + displayName: 'First Name', + name: 'firstName', + type: 'string', + default: '', + }, + { + displayName: 'Last Name', + name: 'lastName', + type: 'string', + default: '', + }, + { + displayName: 'Company', + name: 'company', + type: 'string', + default: '', + }, + { + displayName: 'Address Line 1', + name: 'address_1', + type: 'string', + default: '', + }, + { + displayName: 'Address Line 2', + name: 'address_2', + type: 'string', + default: '', + }, + { + displayName: 'City', + name: 'city', + type: 'string', + default: '', + description: 'ISO code or name of the state, province or district.', + }, + { + displayName: 'Postal Code', + name: 'postalCode', + type: 'string', + default: '', + }, + { + displayName: 'Country', + name: 'country', + type: 'string', + default: '', + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + default: '', + }, + { + displayName: 'Phone', + name: 'phone', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Coupon Lines', + name: 'couponLinesUi', + placeholder: 'Add Coupon Line', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'update', + ] + }, + }, + description: 'Coupons line data', + options: [ + { + name: 'couponLinesValues', + displayName: 'Coupon Line', + values: [ + { + displayName: 'Code', + name: 'code', + type: 'string', + default: '', + description: 'Coupon code.', + }, + { + displayName: 'Metadata', + name: 'metadataUi', + placeholder: 'Add Metadata', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + description: 'Meta data', + options: [ + { + name: 'metadataValues', + displayName: 'Metadata', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + description: 'Name of the metadata key to add.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Value to set for the metadata key.', + }, + ], + }, + ], + }, + ], + }, + ], + }, + { + displayName: 'Fee Lines', + name: 'feeLinesUi', + placeholder: 'Add Fee Line', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'update', + ] + }, + }, + description: 'Fee line data', + options: [ + { + name: 'feeLinesValues', + displayName: 'Fee Line', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + description: 'Fee name', + }, + { + displayName: 'Tax Class ', + name: 'taxClass', + type: 'string', + description: 'Tax class of fee.', + default: '', + }, + { + displayName: 'Tax Status ', + name: 'taxStatus', + type: 'options', + options: [ + { + name: 'Taxable', + value: 'taxable', + }, + { + name: 'None', + value: 'none', + }, + ], + default: '', + description: 'Tax class of fee.', + }, + { + displayName: 'Total ', + name: 'total', + type: 'string', + default: '', + description: 'Line total (after discounts).', + }, + { + displayName: 'Metadata', + name: 'metadataUi', + placeholder: 'Add Metadata', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + description: 'Meta data', + options: [ + { + name: 'metadataValues', + displayName: 'Metadata', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + description: 'Name of the metadata key to add.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Value to set for the metadata key.', + }, + ], + }, + ], + }, + ], + }, + ], + }, + { + displayName: 'Line Items', + name: 'lineItemsUi', + placeholder: 'Add Line Item', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'update', + ] + }, + }, + description: 'Line item data', + options: [ + { + name: 'lineItemsValues', + displayName: 'Line Item', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + description: 'Product name.', + }, + { + displayName: 'Product ID', + name: 'productId', + type: 'number', + default: 0, + description: 'Product ID.', + }, + { + displayName: 'Variation ID', + name: 'variationId', + type: 'number', + default: 0, + description: 'Variation ID, if applicable.', + }, + { + displayName: 'Quantity', + name: 'quantity', + type: 'number', + default: 1, + description: 'Quantity ordered.', + }, + { + displayName: 'Tax Class', + name: 'taxClass', + type: 'string', + default: '', + description: 'Slug of the tax class of product.', + }, + { + displayName: 'Subtotal', + name: 'subtotal', + type: 'string', + default: '', + description: 'Line subtotal (before discounts).', + }, + { + displayName: 'Total', + name: 'total', + type: 'string', + default: '', + description: 'Line total (after discounts).', + }, + { + displayName: 'Metadata', + name: 'metadataUi', + placeholder: 'Add Metadata', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + description: 'Meta data', + options: [ + { + name: 'metadataValues', + displayName: 'Metadata', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + description: 'Name of the metadata key to add.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Value to set for the metadata key.', + }, + ], + }, + ], + }, + ], + }, + ], + }, + { + displayName: 'Metadata', + name: 'metadataUi', + placeholder: 'Add Metadata', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'update', + ] + }, + }, + description: 'Meta data', + options: [ + { + name: 'metadataValues', + displayName: 'Metadata', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + description: 'Name of the metadata key to add.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Value to set for the metadata key.', + }, + ], + }, + ], + }, + { + displayName: 'Shipping', + name: 'shippingUi', + placeholder: 'Add Shipping', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: false, + }, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'update', + ] + }, + }, + description: 'Shipping address', + options: [ + { + name: 'shippingValues', + displayName: 'Address', + values: [ + { + displayName: 'First Name', + name: 'firstName', + type: 'string', + default: '', + }, + { + displayName: 'Last Name', + name: 'lastName', + type: 'string', + default: '', + }, + { + displayName: 'Company', + name: 'company', + type: 'string', + default: '', + }, + { + displayName: 'Address Line 1', + name: 'address_1', + type: 'string', + default: '', + }, + { + displayName: 'Address Line 2', + name: 'address_2', + type: 'string', + default: '', + }, + { + displayName: 'City', + name: 'city', + type: 'string', + default: '', + description: 'ISO code or name of the state, province or district.', + }, + { + displayName: 'Postal Code', + name: 'postalCode', + type: 'string', + default: '', + }, + { + displayName: 'Country', + name: 'country', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Shipping Lines', + name: 'shippingLinesUi', + placeholder: 'Add Shipping Line', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'update', + ] + }, + }, + description: 'Shipping line data', + options: [ + { + name: 'shippingLinesValues', + displayName: 'Fee Line', + values: [ + { + displayName: 'Method Title', + name: 'methodTitle', + type: 'string', + default: '', + description: 'Shipping method name', + }, + { + displayName: 'Method ID ', + name: 'method ID', + type: 'string', + description: 'Shipping method ID.', + default: '', + }, + { + displayName: 'Total ', + name: 'total', + type: 'string', + default: '', + description: 'Line total (after discounts).', + }, + { + displayName: 'Metadata', + name: 'metadataUi', + placeholder: 'Add Metadata', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + description: 'Meta data', + options: [ + { + name: 'metadataValues', + displayName: 'Metadata', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + description: 'Name of the metadata key to add.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Value to set for the metadata key.', + }, + ], + }, + ], + }, + ], + }, + ], + }, +/* -------------------------------------------------------------------------- */ +/* order:get */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Order ID', + name: 'orderId', + type: 'string', + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'get', + ], + }, + }, + default: '', + description: 'order ID.', + }, +/* -------------------------------------------------------------------------- */ +/* order:getAll */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'getAll', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 100, + }, + default: 50, + description: 'How many results to return.', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'getAll', + ], + }, + }, + options: [ + { + displayName: 'After', + name: 'after', + type: 'dateTime', + default: '', + description: 'Limit response to resources published after a given ISO8601 compliant date.', + }, + { + displayName: 'Before', + name: 'before', + type: 'dateTime', + default: '', + description: 'Limit response to resources published before a given ISO8601 compliant date', + }, + { + displayName: 'Customer', + name: 'customer', + type: 'string', + default: '', + description: 'Limit result set to orders assigned a specific customer.', + }, + { + displayName: 'Decimal Points', + name: 'decimalPoints', + type: 'number', + default: 2, + description: 'Number of decimal points to use in each resource.', + }, + { + displayName: 'Order', + name: 'order', + type: 'options', + options: [ + { + name: 'ASC', + value: 'asc', + }, + { + name: 'DESC', + value: 'desc', + }, + ], + default: 'desc', + description: 'Order sort attribute ascending or descending.', + }, + { + displayName: 'Product', + name: 'product', + type: 'string', + default: '', + description: 'Limit result set to orders assigned a specific product.', + }, + { + displayName: 'Order By', + name: 'orderBy', + type: 'options', + options: [ + { + name: 'Date', + value: 'date', + }, + { + name: 'ID', + value: 'id', + }, + { + name: 'Include', + value: 'include', + }, + { + name: 'Slug', + value: 'slug', + }, + { + name: 'Title', + value: 'title', + }, + ], + default: 'id', + description: 'Sort collection by object attribute.', + }, + { + displayName: 'Search', + name: 'search', + type: 'string', + default: '', + description: 'Limit results to those matching a string.', + }, + { + displayName: 'Status', + name: 'status', + type: 'options', + options: [ + { + name: 'Any', + value: 'any', + }, + { + name: 'completed', + value: 'completed', + }, + { + name: 'cancelled', + value: 'cancelled', + }, + { + name: 'failed', + value: 'failed', + }, + { + name: 'on-hold', + value: 'on-hold', + }, + { + name: 'pending', + value: 'pending', + }, + { + name: 'processing', + value: 'processing', + }, + { + name: 'refunded', + value: 'refunded', + }, + { + name: 'trash', + value: 'trash', + }, + ], + default: 'any', + description: 'Limit result set to orders assigned a specific status.', + }, + ] + }, +/* -------------------------------------------------------------------------- */ +/* order:delete */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Order ID', + name: 'orderId', + type: 'string', + displayOptions: { + show: { + resource: [ + 'order', + ], + operation: [ + 'delete', + ], + }, + }, + default: '', + description: 'order ID.', + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/WooCommerce/OrderInterface.ts b/packages/nodes-base/nodes/WooCommerce/OrderInterface.ts new file mode 100644 index 0000000000..2d09576ee7 --- /dev/null +++ b/packages/nodes-base/nodes/WooCommerce/OrderInterface.ts @@ -0,0 +1,65 @@ +import { IDataObject } from "n8n-workflow"; + +export interface IAddress { + first_name?: string; + last_name?: string; + company?: string; + address_1?: string; + address_2?: string; + city?: string; + state?: string; + postcode?: string; + country?: string; + email?: string; + phone?: string; +} + +export interface ILineItem { + name?: string; + product_id?: number; + variation_id?: number; + quantity?: string; + tax_class?: string; + subtotal?: string; + total?: string; + meta_data?: IDataObject; +} + +export interface IShoppingLine { + method_title?: string; + method_id?: number; + total?: string; + meta_data?: IDataObject; +} + +export interface IFeeLine { + name?: string; + tax_class?: string; + tax_status?: string; + total?: string; + meta_data?: IDataObject; +} + +export interface ICouponLine { + code?: string; + meta_data?: IDataObject; +} + +export interface IOrder { + billing?: IAddress; + coupon_lines?: ICouponLine[]; + currency?: string; + customer_id?: number; + customer_note?: string; + fee_lines?: IFeeLine[]; + line_items?: ILineItem[]; + meta_data?: IDataObject[]; + parent_id?: number; + payment_method?: string; + payment_method_title?: string; + set_paid?: boolean; + shipping?: IAddress; + shipping_lines?: IShoppingLine[]; + status?: string; + transaction_id?: string; +} diff --git a/packages/nodes-base/nodes/WooCommerce/WooCommerce.node.ts b/packages/nodes-base/nodes/WooCommerce/WooCommerce.node.ts index a7865ba5d2..27056f0c49 100644 --- a/packages/nodes-base/nodes/WooCommerce/WooCommerce.node.ts +++ b/packages/nodes-base/nodes/WooCommerce/WooCommerce.node.ts @@ -12,14 +12,30 @@ import { import { woocommerceApiRequest, woocommerceApiRequestAllItems, + toSnakeCase, + setMetadata, } from './GenericFunctions'; import { productFields, productOperations, } from './ProductDescription'; import { - IProduct, IImage, IDimension, + orderFields, + orderOperations, +} from './Orderdescription'; +import { + IProduct, + IImage, + IDimension, } from './ProductInterface'; +import { + IOrder, + IAddress, + ICouponLine, + IFeeLine, + ILineItem, + IShoppingLine, +} from './OrderInterface'; export class WooCommerce implements INodeType { description: INodeTypeDescription = { @@ -52,12 +68,18 @@ export class WooCommerce implements INodeType { name: 'Product', value: 'product', }, + { + name: 'Order', + value: 'order', + }, ], default: 'product', description: 'Resource to consume.', }, ...productOperations, ...productFields, + ...orderOperations, + ...orderFields, ], }; @@ -415,6 +437,201 @@ export class WooCommerce implements INodeType { responseData = await woocommerceApiRequest.call(this,'DELETE', `/products/${productId}`, {}, { force: true }); } } + if (resource === 'order') { + //https://woocommerce.github.io/woocommerce-rest-api-docs/#create-an-order + if (operation === 'create') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IOrder = {}; + if (additionalFields.currency) { + body.currency = additionalFields.currency as string; + } + if (additionalFields.customerId) { + body.customer_id = parseInt(additionalFields.customerId as string, 10); + } + if (additionalFields.customerNote) { + body.customer_note = additionalFields.customerNote as string; + } + if (additionalFields.parentId) { + body.parent_id = parseInt(additionalFields.parentId as string, 10); + } + if (additionalFields.paymentMethodId) { + body.payment_method = additionalFields.paymentMethodId as string + } + if (additionalFields.paymentMethodTitle) { + body.payment_method_title = additionalFields.paymentMethodTitle as string + } + if (additionalFields.setPaid) { + body.set_paid = additionalFields.setPaid as boolean; + } + if (additionalFields.status) { + body.status = additionalFields.status as string; + } + if (additionalFields.transactionID) { + body.transaction_id = additionalFields.transactionID as string; + } + const billing = (this.getNodeParameter('billingUi', i) as IDataObject).billingValues as IAddress; + if (billing !== undefined) { + body.billing = billing; + toSnakeCase(billing as IDataObject); + } + const shipping = (this.getNodeParameter('shippingUi', i) as IDataObject).shippingValues as IAddress; + if (shipping !== undefined) { + body.shipping = shipping; + toSnakeCase(shipping as IDataObject); + } + const couponLines = (this.getNodeParameter('couponLinesUi', i) as IDataObject).couponLinesValues as ICouponLine[]; + if (couponLines) { + body.coupon_lines = couponLines; + setMetadata(couponLines); + toSnakeCase(couponLines); + } + const feeLines = (this.getNodeParameter('feeLinesUi', i) as IDataObject).feeLinesValues as IFeeLine[]; + if (feeLines) { + body.fee_lines = feeLines; + setMetadata(feeLines); + toSnakeCase(feeLines); + } + const lineItems = (this.getNodeParameter('lineItemsUi', i) as IDataObject).lineItemsValues as ILineItem[]; + if (lineItems) { + body.line_items = lineItems; + setMetadata(lineItems); + toSnakeCase(lineItems); + //@ts-ignore + } + const metadata = (this.getNodeParameter('metadataUi', i) as IDataObject).metadataValues as IDataObject[]; + if (metadata) { + body.meta_data = metadata; + } + const shippingLines = (this.getNodeParameter('shippingLinesUi', i) as IDataObject).shippingLinesValues as IShoppingLine[]; + if (shippingLines) { + body.shipping_lines = shippingLines; + setMetadata(shippingLines); + toSnakeCase(shippingLines); + } + responseData = await woocommerceApiRequest.call(this, 'POST', '/orders', body); + } + //https://woocommerce.github.io/woocommerce-rest-api-docs/#update-an-order + if (operation === 'update') { + const orderId = this.getNodeParameter('orderId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IOrder = {}; + if (updateFields.currency) { + body.currency = updateFields.currency as string; + } + if (updateFields.customerId) { + body.customer_id = parseInt(updateFields.customerId as string, 10); + } + if (updateFields.customerNote) { + body.customer_note = updateFields.customerNote as string; + } + if (updateFields.parentId) { + body.parent_id = parseInt(updateFields.parentId as string, 10); + } + if (updateFields.paymentMethodId) { + body.payment_method = updateFields.paymentMethodId as string + } + if (updateFields.paymentMethodTitle) { + body.payment_method_title = updateFields.paymentMethodTitle as string + } + + if (updateFields.status) { + body.status = updateFields.status as string; + } + if (updateFields.transactionID) { + body.transaction_id = updateFields.transactionID as string; + } + const billing = (this.getNodeParameter('billingUi', i) as IDataObject).billingValues as IAddress; + if (billing !== undefined) { + body.billing = billing; + toSnakeCase(billing as IDataObject); + } + const shipping = (this.getNodeParameter('shippingUi', i) as IDataObject).shippingValues as IAddress; + if (shipping !== undefined) { + body.shipping = shipping; + toSnakeCase(shipping as IDataObject); + } + const couponLines = (this.getNodeParameter('couponLinesUi', i) as IDataObject).couponLinesValues as ICouponLine[]; + if (couponLines) { + body.coupon_lines = couponLines; + setMetadata(couponLines); + toSnakeCase(couponLines); + } + const feeLines = (this.getNodeParameter('feeLinesUi', i) as IDataObject).feeLinesValues as IFeeLine[]; + if (feeLines) { + body.fee_lines = feeLines; + setMetadata(feeLines); + toSnakeCase(feeLines); + } + const lineItems = (this.getNodeParameter('lineItemsUi', i) as IDataObject).lineItemsValues as ILineItem[]; + if (lineItems) { + body.line_items = lineItems; + setMetadata(lineItems); + toSnakeCase(lineItems); + } + const metadata = (this.getNodeParameter('metadataUi', i) as IDataObject).metadataValues as IDataObject[]; + if (metadata) { + body.meta_data = metadata; + } + const shippingLines = (this.getNodeParameter('shippingLinesUi', i) as IDataObject).shippingLinesValues as IShoppingLine[]; + if (shippingLines) { + body.shipping_lines = shippingLines; + setMetadata(shippingLines); + toSnakeCase(shippingLines); + } + responseData = await woocommerceApiRequest.call(this, 'PUT', `/orders/${orderId}`, body); + } + //https://woocommerce.github.io/woocommerce-rest-api-docs/#retrieve-an-order + if (operation === 'get') { + const orderId = this.getNodeParameter('orderId', i) as string; + responseData = await woocommerceApiRequest.call(this,'GET', `/orders/${orderId}`, {}, qs); + } + //https://woocommerce.github.io/woocommerce-rest-api-docs/#list-all-orders + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.after) { + qs.after = options.after as string; + } + if (options.before) { + qs.before = options.before as string; + } + if (options.category) { + qs.category = options.category as string; + } + if (options.customer) { + qs.customer = parseInt(options.customer as string, 10); + } + if (options.decimalPoints) { + qs.dp = options.decimalPoints as number; + } + if (options.product) { + qs.product = parseInt(options.product as string, 10); + } + if (options.order) { + qs.order = options.order as string; + } + if (options.orderBy) { + qs.orderby = options.orderBy as string; + } + if (options.search) { + qs.search = options.search as string; + } + if (options.status) { + qs.status = options.status as string; + } + if (returnAll === true) { + responseData = await woocommerceApiRequestAllItems.call(this, 'GET', '/orders', {}, qs); + } else { + qs.per_page = this.getNodeParameter('limit', i) as number; + responseData = await woocommerceApiRequest.call(this, 'GET', '/orders', {}, qs); + } + } + //https://woocommerce.github.io/woocommerce-rest-api-docs/#delete-an-order + if (operation === 'delete') { + const orderId = this.getNodeParameter('orderId', i) as string; + responseData = await woocommerceApiRequest.call(this,'DELETE', `/orders/${orderId}`, {}, { force: true }); + } + } if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]); } else {