Merge pull request #1338 from automatisch/AUT-327
feat(invoice-ninja): add create invoice action
This commit is contained in:
@@ -0,0 +1,407 @@
|
|||||||
|
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: 'string' as const,
|
||||||
|
required: false,
|
||||||
|
description:
|
||||||
|
'If this value is greater than zero a payment will be created along with the invoice.',
|
||||||
|
variables: 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: 'Custom Field 1',
|
||||||
|
key: 'customField1',
|
||||||
|
type: 'string' as const,
|
||||||
|
required: false,
|
||||||
|
description: '',
|
||||||
|
variables: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Custom Field 2',
|
||||||
|
key: 'customField2',
|
||||||
|
type: 'string' as const,
|
||||||
|
required: false,
|
||||||
|
description: '',
|
||||||
|
variables: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Custom Field 3',
|
||||||
|
key: 'customField3',
|
||||||
|
type: 'string' as const,
|
||||||
|
required: false,
|
||||||
|
description: '',
|
||||||
|
variables: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Custom 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 Custom Field 1',
|
||||||
|
key: 'lineItemCustomField1',
|
||||||
|
type: 'string' as const,
|
||||||
|
required: false,
|
||||||
|
description: '',
|
||||||
|
variables: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Line Item Custom Field 2',
|
||||||
|
key: 'lineItemCustomField2',
|
||||||
|
type: 'string' as const,
|
||||||
|
required: false,
|
||||||
|
description: '',
|
||||||
|
variables: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Line Item Custom Field 3',
|
||||||
|
key: 'lineItemCustomField3',
|
||||||
|
type: 'string' as const,
|
||||||
|
required: false,
|
||||||
|
description: '',
|
||||||
|
variables: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Line Item Custom 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,
|
||||||
|
},
|
||||||
|
];
|
@@ -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 });
|
||||||
|
},
|
||||||
|
});
|
@@ -1,3 +1,4 @@
|
|||||||
import createClient from './create-client';
|
import createClient from './create-client';
|
||||||
|
import createInvoice from './create-invoice';
|
||||||
|
|
||||||
export default [createClient];
|
export default [createClient, createInvoice];
|
||||||
|
@@ -0,0 +1,3 @@
|
|||||||
|
import listClients from './list-clients';
|
||||||
|
|
||||||
|
export default [listClients];
|
@@ -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;
|
||||||
|
},
|
||||||
|
};
|
@@ -4,6 +4,7 @@ import addAuthHeader from './common/add-auth-header';
|
|||||||
import auth from './auth';
|
import auth from './auth';
|
||||||
import triggers from './triggers';
|
import triggers from './triggers';
|
||||||
import actions from './actions';
|
import actions from './actions';
|
||||||
|
import dynamicData from './dynamic-data';
|
||||||
|
|
||||||
export default defineApp({
|
export default defineApp({
|
||||||
name: 'Invoice Ninja',
|
name: 'Invoice Ninja',
|
||||||
@@ -18,4 +19,5 @@ export default defineApp({
|
|||||||
auth,
|
auth,
|
||||||
triggers,
|
triggers,
|
||||||
actions,
|
actions,
|
||||||
|
dynamicData,
|
||||||
});
|
});
|
||||||
|
@@ -3,6 +3,8 @@ favicon: /favicons/invoice-ninja.svg
|
|||||||
items:
|
items:
|
||||||
- name: Create client
|
- name: Create client
|
||||||
desc: Creates a new client.
|
desc: Creates a new client.
|
||||||
|
- name: Create invoice
|
||||||
|
desc: Creates a new invoice.
|
||||||
---
|
---
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
Reference in New Issue
Block a user