From 66444b0fb53f85a719b76067c7953d2e7ab384bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C4=B1dvan=20Akca?= Date: Wed, 11 Oct 2023 12:53:46 +0300 Subject: [PATCH] feat(invoice-ninja): add create invoice action --- .../actions/create-invoice/fields.ts | 411 ++++++++++++++++++ .../actions/create-invoice/index.ts | 127 ++++++ .../src/apps/invoice-ninja/actions/index.ts | 3 +- .../apps/invoice-ninja/dynamic-data/index.ts | 3 + .../dynamic-data/list-clients/index.ts | 35 ++ .../backend/src/apps/invoice-ninja/index.ts | 2 + .../docs/pages/apps/invoice-ninja/actions.md | 2 + 7 files changed, 582 insertions(+), 1 deletion(-) create mode 100644 packages/backend/src/apps/invoice-ninja/actions/create-invoice/fields.ts create mode 100644 packages/backend/src/apps/invoice-ninja/actions/create-invoice/index.ts create mode 100644 packages/backend/src/apps/invoice-ninja/dynamic-data/index.ts create mode 100644 packages/backend/src/apps/invoice-ninja/dynamic-data/list-clients/index.ts diff --git a/packages/backend/src/apps/invoice-ninja/actions/create-invoice/fields.ts b/packages/backend/src/apps/invoice-ninja/actions/create-invoice/fields.ts new file mode 100644 index 0000000000..6e39f6a64a --- /dev/null +++ b/packages/backend/src/apps/invoice-ninja/actions/create-invoice/fields.ts @@ -0,0 +1,411 @@ +export const fields = [ + { + label: 'Client ID', + key: 'clientId', + type: 'dropdown' as const, + required: true, + description: 'The ID of the client, not the name or email address.', + variables: true, + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listClients', + }, + ], + }, + }, + { + label: 'Send Email', + key: 'sendEmail', + type: 'dropdown' as const, + required: false, + description: '', + variables: true, + options: [ + { label: 'False', value: 'false' }, + { label: 'True', value: 'true' }, + ], + }, + { + label: 'Mark Sent', + key: 'markSent', + type: 'dropdown' as const, + required: false, + description: 'Setting this to true creates the invoice as sent.', + variables: true, + options: [ + { label: 'False', value: 'false' }, + { label: 'True', value: 'true' }, + ], + }, + { + label: 'Paid', + key: 'paid', + type: 'dropdown' as const, + required: false, + description: 'Setting this to true creates the invoice as paid.', + variables: true, + options: [ + { label: 'False', value: 'false' }, + { label: 'True', value: 'true' }, + ], + }, + { + label: 'Amount Paid', + key: 'amountPaid', + type: 'dropdown' as const, + required: false, + description: + 'If this value is greater than zero a payment will be created along with the invoice.', + variables: true, + options: [ + { label: 'False', value: 'false' }, + { label: 'True', value: 'true' }, + ], + }, + { + label: 'Number', + key: 'number', + type: 'string' as const, + required: false, + description: + 'The invoice number - is a unique alpha numeric number per invoice per company', + variables: true, + }, + { + label: 'Discount', + key: 'discount', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'PO Number', + key: 'poNumber', + type: 'string' as const, + required: false, + description: 'The purchase order associated with this invoice', + variables: true, + }, + { + label: 'Date', + key: 'date', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Due Date', + key: 'dueDate', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Tax Rate 1', + key: 'taxRate1', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Tax Name 1', + key: 'taxName1', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Tax Rate 2', + key: 'taxRate2', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Tax Name 2', + key: 'taxName2', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Tax Rate 3', + key: 'taxRate3', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Tax Name 3', + key: 'taxName3', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Custon Field 1', + key: 'customField1', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Custon Field 2', + key: 'customField2', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Custon Field 3', + key: 'customField3', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Custon Field 4', + key: 'customField4', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Custom Surcharge 1', + key: 'customSurcharge1', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Custom Surcharge 2', + key: 'customSurcharge2', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Custom Surcharge 3', + key: 'customSurcharge3', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Custom Surcharge 4', + key: 'customSurcharge4', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Is Amount Discount', + key: 'isAmountDiscount', + type: 'dropdown' as const, + required: false, + description: + 'By default the discount is applied as a percentage, enabling this applies the discount as a fixed amount.', + variables: true, + options: [ + { label: 'False', value: 'false' }, + { label: 'True', value: 'true' }, + ], + }, + { + label: 'Partial/Deposit', + key: 'partialDeposit', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Partial Due Date', + key: 'partialDueDate', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Cost', + key: 'lineItemCost', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Quatity', + key: 'lineItemQuantity', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Product', + key: 'lineItemProduct', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Discount', + key: 'lineItemDiscount', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Description', + key: 'lineItemDescription', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Tax Rate 1', + key: 'lineItemTaxRate1', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Tax Name 1', + key: 'lineItemTaxName1', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Tax Rate 2', + key: 'lineItemTaxRate2', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Tax Name 2', + key: 'lineItemTaxName2', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Tax Rate 3', + key: 'lineItemTaxRate3', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Tax Name 3', + key: 'lineItemTaxName3', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Custon Field 1', + key: 'lineItemCustomField1', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Custon Field 2', + key: 'lineItemCustomField2', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Custon Field 3', + key: 'lineItemCustomField3', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Custon Field 4', + key: 'lineItemCustomField4', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Line Item Product Cost', + key: 'lineItemProductCost', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Public Notes', + key: 'publicNotes', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Private Notes', + key: 'privateNotes', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Terms', + key: 'terms', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Footer', + key: 'footer', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, +]; diff --git a/packages/backend/src/apps/invoice-ninja/actions/create-invoice/index.ts b/packages/backend/src/apps/invoice-ninja/actions/create-invoice/index.ts new file mode 100644 index 0000000000..b357d4403d --- /dev/null +++ b/packages/backend/src/apps/invoice-ninja/actions/create-invoice/index.ts @@ -0,0 +1,127 @@ +import defineAction from '../../../../helpers/define-action'; +import { filterProvidedFields } from '../../common/filter-provided-fields'; +import { fields } from './fields'; + +export default defineAction({ + name: 'Create invoice', + key: 'createInvoice', + description: 'Creates a new invoice.', + arguments: fields, + + async run($) { + const { + clientId, + sendEmail, + markSent, + paid, + amountPaid, + number, + discount, + poNumber, + date, + dueDate, + taxRate1, + taxName1, + taxRate2, + taxName2, + taxRate3, + taxName3, + customField1, + customField2, + customField3, + customField4, + customSurcharge1, + customSurcharge2, + customSurcharge3, + customSurcharge4, + isAmountDiscount, + partialDeposit, + partialDueDate, + lineItemCost, + lineItemQuantity, + lineItemProduct, + lineItemDiscount, + lineItemDescription, + lineItemTaxRate1, + lineItemTaxName1, + lineItemTaxRate2, + lineItemTaxName2, + lineItemTaxRate3, + lineItemTaxName3, + lineItemCustomField1, + lineItemCustomField2, + lineItemCustomField3, + lineItemCustomField4, + lineItemProductCost, + publicNotes, + privateNotes, + terms, + footer, + } = $.step.parameters; + + const paramFields = { + send_email: sendEmail, + mark_sent: markSent, + paid: paid, + amount_paid: amountPaid, + }; + + const params = filterProvidedFields(paramFields); + + const bodyFields = { + client_id: clientId, + number: number, + discount: discount, + po_number: poNumber, + date: date, + due_date: dueDate, + tax_rate1: taxRate1, + tax_name1: taxName1, + tax_rate2: taxRate2, + tax_name2: taxName2, + tax_rate3: taxRate3, + tax_name3: taxName3, + custom_value1: customField1, + custom_value2: customField2, + custom_value3: customField3, + custom_value4: customField4, + custom_surcharge1: customSurcharge1, + custom_surcharge2: customSurcharge2, + custom_surcharge3: customSurcharge3, + custom_surcharge4: customSurcharge4, + is_amount_discount: Boolean(isAmountDiscount), + partial: partialDeposit, + partial_due_date: partialDueDate, + line_items: [ + { + cost: lineItemCost, + quantity: lineItemQuantity, + product_key: lineItemProduct, + discount: lineItemDiscount, + notes: lineItemDescription, + tax_rate1: lineItemTaxRate1, + tax_name1: lineItemTaxName1, + tax_rate2: lineItemTaxRate2, + tax_name2: lineItemTaxName2, + tax_rate3: lineItemTaxRate3, + tax_name3: lineItemTaxName3, + custom_value1: lineItemCustomField1, + custom_value2: lineItemCustomField2, + custom_value3: lineItemCustomField3, + custom_value4: lineItemCustomField4, + product_cost: lineItemProductCost, + }, + ], + public_notes: publicNotes, + private_notes: privateNotes, + terms: terms, + footer: footer, + }; + + const body = filterProvidedFields(bodyFields); + + const response = await $.http.post('/v1/invoices', body, { params }); + + $.setActionItem({ raw: response.data.data }); + }, +}); diff --git a/packages/backend/src/apps/invoice-ninja/actions/index.ts b/packages/backend/src/apps/invoice-ninja/actions/index.ts index b2ecee2937..0cfd721927 100644 --- a/packages/backend/src/apps/invoice-ninja/actions/index.ts +++ b/packages/backend/src/apps/invoice-ninja/actions/index.ts @@ -1,3 +1,4 @@ import createClient from './create-client'; +import createInvoice from './create-invoice'; -export default [createClient]; +export default [createClient, createInvoice]; diff --git a/packages/backend/src/apps/invoice-ninja/dynamic-data/index.ts b/packages/backend/src/apps/invoice-ninja/dynamic-data/index.ts new file mode 100644 index 0000000000..e7a5c21cf5 --- /dev/null +++ b/packages/backend/src/apps/invoice-ninja/dynamic-data/index.ts @@ -0,0 +1,3 @@ +import listClients from './list-clients'; + +export default [listClients]; diff --git a/packages/backend/src/apps/invoice-ninja/dynamic-data/list-clients/index.ts b/packages/backend/src/apps/invoice-ninja/dynamic-data/list-clients/index.ts new file mode 100644 index 0000000000..2e3402ff5f --- /dev/null +++ b/packages/backend/src/apps/invoice-ninja/dynamic-data/list-clients/index.ts @@ -0,0 +1,35 @@ +import { IGlobalVariable, IJSONObject } from '@automatisch/types'; + +export default { + name: 'List clients', + key: 'listClients', + + async run($: IGlobalVariable) { + const clients: { + data: IJSONObject[]; + } = { + data: [], + }; + + const params = { + sort: 'created_at|desc', + }; + + const { + data: { data }, + } = await $.http.get('/v1/clients', { params }); + + if (!data?.length) { + return; + } + + for (const client of data) { + clients.data.push({ + value: client.id, + name: client.name, + }); + } + + return clients; + }, +}; diff --git a/packages/backend/src/apps/invoice-ninja/index.ts b/packages/backend/src/apps/invoice-ninja/index.ts index 7198b4dc7a..8a9db6f094 100644 --- a/packages/backend/src/apps/invoice-ninja/index.ts +++ b/packages/backend/src/apps/invoice-ninja/index.ts @@ -3,6 +3,7 @@ import addAuthHeader from './common/add-auth-header'; import auth from './auth'; import triggers from './triggers'; import actions from './actions'; +import dynamicData from './dynamic-data'; export default defineApp({ name: 'Invoice Ninja', @@ -17,4 +18,5 @@ export default defineApp({ auth, triggers, actions, + dynamicData, }); diff --git a/packages/docs/pages/apps/invoice-ninja/actions.md b/packages/docs/pages/apps/invoice-ninja/actions.md index c57f6e72ae..bf23f1d42e 100644 --- a/packages/docs/pages/apps/invoice-ninja/actions.md +++ b/packages/docs/pages/apps/invoice-ninja/actions.md @@ -3,6 +3,8 @@ favicon: /favicons/invoice-ninja.svg items: - name: Create client desc: Creates a new client. + - name: Create invoice + desc: Creates a new invoice. ---