diff --git a/components/invoice_ninja/actions/create-client/create-client.mjs b/components/invoice_ninja/actions/create-client/create-client.mjs new file mode 100644 index 0000000000000..c0281a7ffcf25 --- /dev/null +++ b/components/invoice_ninja/actions/create-client/create-client.mjs @@ -0,0 +1,246 @@ +import { CLASSIFICATION_OPTIONS } from "../../common/constants.mjs"; +import { parseObject } from "../../common/utils.mjs"; +import app from "../../invoice_ninja.app.mjs"; + +export default { + key: "invoice_ninja-create-client", + name: "Create Client", + description: "Creates a new client in Invoice Ninja. [See the documentation](https://api-docs.invoicing.co/#tag/clients/POST/api/v1/clients)", + version: "0.0.1", + type: "action", + props: { + app, + contacts: { + type: "string[]", + label: "Contacts", + description: "An array of contact objects in JSON format. **Example: { \"first_name\": \"John\", \"last_name\": \"Smith\", \"email\": \"john@example.com\", \"phone\": \"555-0123\" }**", + }, + name: { + type: "string", + label: "Client Name", + description: "Name of the client", + optional: true, + }, + website: { + type: "string", + label: "Website", + description: "Website of the client", + optional: true, + }, + privateNotes: { + type: "string", + label: "Private Notes", + description: "Notes that are only visible to the user who created the client", + optional: true, + }, + industryId: { + propDefinition: [ + app, + "industryId", + ], + optional: true, + }, + sizeId: { + propDefinition: [ + app, + "sizeId", + ], + optional: true, + }, + address1: { + type: "string", + label: "Address 1", + description: "Primary address line for the client", + optional: true, + }, + address2: { + type: "string", + label: "Address 2", + description: "Secondary address line for the client", + optional: true, + }, + city: { + type: "string", + label: "City", + description: "City of the client", + optional: true, + }, + state: { + type: "string", + label: "State", + description: "State of the client", + optional: true, + }, + postalCode: { + type: "string", + label: "Postal Code", + description: "Postal code of the client", + optional: true, + }, + phone: { + type: "string", + label: "Phone", + description: "Phone number of the client", + optional: true, + }, + countryId: { + propDefinition: [ + app, + "countryId", + ], + }, + customValue1: { + type: "string", + label: "Custom Value 1", + description: "A custom field for storing additional information", + optional: true, + }, + customValue2: { + type: "string", + label: "Custom Value 2", + description: "A custom field for storing additional information", + optional: true, + }, + customValue3: { + type: "string", + label: "Custom Value 3", + description: "A custom field for storing additional information", + optional: true, + }, + customValue4: { + type: "string", + label: "Custom Value 4", + description: "A custom field for storing additional information", + optional: true, + }, + vatNumber: { + type: "string", + label: "VAT Number", + description: "The client's VAT (Value Added Tax) number, if applicable", + optional: true, + }, + idNumber: { + type: "string", + label: "ID Number", + description: "A unique identification number for the client, such as a tax ID or business registration number", + optional: true, + }, + number: { + type: "string", + label: "Number", + description: "A system-assigned unique number for the client, typically used for invoicing purposes", + optional: true, + }, + shippingAddress1: { + type: "string", + label: "Shipping Address 1", + description: "First line of the client's shipping address", + optional: true, + }, + shippingAddress2: { + type: "string", + label: "Shipping Address 2", + description: "Second line of the client's shipping address, if needed", + optional: true, + }, + shippingCity: { + type: "string", + label: "Shipping City", + description: "City of the client's shipping address", + optional: true, + }, + shippingState: { + type: "string", + label: "Shipping State", + description: "State of the client's shipping address", + optional: true, + }, + shippingPostalCode: { + type: "string", + label: "Shipping Postal Code", + description: "Postal code of the client's shipping address", + optional: true, + }, + shippingCountryId: { + propDefinition: [ + app, + "countryId", + ], + label: "Shipping Country ID", + description: "The ID of the country for the client's shipping address", + optional: true, + }, + groupSettingsId: { + propDefinition: [ + app, + "groupSettingsId", + ], + optional: true, + }, + isTaxExempt: { + type: "boolean", + label: "Is Tax Exempt", + description: "Flag which defines if the client is exempt from taxes", + optional: true, + }, + hasValidVatNumber: { + type: "boolean", + label: "Has Valid VAT Number", + description: "Flag which defines if the client has a valid VAT number", + optional: true, + }, + classification: { + type: "string", + label: "Classification", + description: "Classification of the client", + options: CLASSIFICATION_OPTIONS, + optional: true, + }, + settings: { + type: "object", + label: "Settings", + description: "An array of settings objects in JSON format. **Example: {\"currency_id\": 1, \"timezone_id\": 5, \"date_format_id\": 1, \"language_id\": 1}** [See the documentation](https://api-docs.invoicing.co/#tag/clients/POST/api/v1/clients) for further details", + optional: true, + }, + }, + async run({ $ }) { + const { data } = await this.app.createNewClient({ + $, + data: { + contacts: parseObject(this.contacts), + name: this.name, + website: this.website, + private_notes: this.privateNotes, + industry_id: this.industryId, + size_id: this.sizeId, + address1: this.address1, + address2: this.address2, + city: this.city, + state: this.state, + postal_code: this.postalCode, + phone: this.phone, + country_id: this.countryId, + custom_value1: this.customValue1, + custom_value2: this.customValue2, + custom_value3: this.customValue3, + custom_value4: this.customValue4, + vat_number: this.vatNumber, + id_number: this.idNumber, + number: this.number, + shipping_address1: this.shippingAddress1, + shipping_address2: this.shippingAddress2, + shipping_city: this.shippingCity, + shipping_state: this.shippingState, + shipping_postal_code: this.shippingPostalCode, + shipping_country_id: this.shipping_country_id, + group_settings_id: this.groupSettingsId, + is_tax_exempt: this.isTaxExempt, + has_valid_vat_number: this.hasValidVatNumber, + classification: this.classification, + settings: parseObject(this.settings), + }, + }); + $.export("$summary", `Created client: ${data.id}`); + return data; + }, +}; diff --git a/components/invoice_ninja/actions/create-invoice/create-invoice.mjs b/components/invoice_ninja/actions/create-invoice/create-invoice.mjs new file mode 100644 index 0000000000000..acc9cf426cc6e --- /dev/null +++ b/components/invoice_ninja/actions/create-invoice/create-invoice.mjs @@ -0,0 +1,174 @@ +import { parseObject } from "../../common/utils.mjs"; +import app from "../../invoice_ninja.app.mjs"; + +export default { + key: "invoice_ninja-create-invoice", + name: "Create Invoice", + description: "Creates a new invoice. [See the documentation](https://api-docs.invoicing.co/#tag/invoices/POST/api/v1/invoices).", + version: "0.0.1", + type: "action", + props: { + app, + clientId: { + propDefinition: [ + app, + "clientId", + ], + }, + userId: { + propDefinition: [ + app, + "userId", + ], + optional: true, + }, + assignedUserId: { + propDefinition: [ + app, + "userId", + ], + label: "Assigned User ID", + description: "The ID of the user to assign the invoice to", + optional: true, + }, + number: { + type: "string", + label: "Invoice Number", + description: "The number of the invoice", + optional: true, + }, + poNumber: { + type: "string", + label: "PO Number", + description: "Purchase Order number for the invoice", + optional: true, + }, + terms: { + type: "string", + label: "Terms", + description: "Payment terms for the invoice", + optional: true, + }, + publicNotes: { + type: "string", + label: "Public Notes", + description: "Public notes for the invoice", + optional: true, + }, + privateNotes: { + type: "string", + label: "Private Notes", + description: "Private notes for the invoice", + optional: true, + }, + footer: { + type: "string", + label: "Footer", + description: "Footer content for the invoice", + optional: true, + }, + customValue1: { + type: "string", + label: "Custom Value 1", + description: "Custom field 1 for the invoice", + optional: true, + }, + customValue2: { + type: "string", + label: "Custom Value 2", + description: "Custom field 2 for the invoice", + optional: true, + }, + customValue3: { + type: "string", + label: "Custom Value 3", + description: "Custom field 3 for the invoice", + optional: true, + }, + customValue4: { + type: "string", + label: "Custom Value 4", + description: "Custom field 4 for the invoice", + optional: true, + }, + totalTaxes: { + type: "string", + label: "Total Taxes", + description: "Total taxes for the invoice", + optional: true, + }, + lineItems: { + type: "string[]", + label: "Line Items", + description: "An array of line items in JSON format. **Example: { \"quantity\": 1, \"cost\": 10, \"product_key\": \"Product key\", \"product_cost\": 10, \"notes\": \"Item notes\", \"discount\": 5, \"is_amount_discount\": false, \"tax_name1\": \"GST\", \"tax_rate1\": 10, \"tax_name2\": \"VAT\", \"tax_rate2\": 5, \"tax_name3\": \"CA Sales Tax\", \"tax_rate3\": 3, \"sort_id\": \"0\", \"date\": \"2023-03-19T00:00:00Z\", \"custom_value1\": \"Custom value 1\", \"custom_value2\": \"Custom value 2\", \"custom_value3\": \"Custom value 3\", \"custom_value4\": \"Custom value 4\", \"type_id\": \"1\", \"tax_id\": \"1\" }.**", + optional: true, + }, + amount: { + type: "string", + label: "Amount", + description: "Total amount of the invoice", + optional: true, + }, + balance: { + type: "string", + label: "Balance", + description: "Balance remaining on the invoice", + optional: true, + }, + paidToDate: { + type: "string", + label: "Paid To Date", + description: "Amount paid to date for the invoice", + optional: true, + }, + discount: { + type: "string", + label: "Discount", + description: "Discount applied to the invoice", + optional: true, + }, + date: { + type: "string", + label: "Invoice Date", + description: "Date of the invoice (YYYY-MM-DD)", + optional: true, + }, + dueDate: { + type: "string", + label: "Due Date", + description: "Due date for the invoice (YYYY-MM-DD)", + optional: true, + }, + }, + async run({ $ }) { + const { data } = await this.app.createNewInvoice({ + $, + data: { + client_id: this.clientId, + user_id: this.userId, + assigned_user_id: this.assignedUserId, + status_id: this.statusId, + number: this.number, + po_number: this.poNumber, + terms: this.terms, + public_notes: this.publicNotes, + private_notes: this.privateNotes, + footer: this.footer, + custom_value1: this.customValue1, + custom_value2: this.customValue2, + custom_value3: this.customValue3, + custom_value4: this.customValue4, + total_taxes: this.totalTaxes && parseFloat(this.totalTaxes), + line_items: parseObject(this.lineItems), + amount: this.amount && parseFloat(this.amount), + balance: this.balance && parseFloat(this.balance), + paid_to_date: this.paidToDate && parseFloat(this.paidToDate), + discount: this.discount && parseFloat(this.discount), + date: this.date, + due_date: this.dueDate, + }, + }); + $.export("$summary", `Created invoice with ID: ${data.id}`); + return data; + }, +}; diff --git a/components/invoice_ninja/actions/create-payment/create-payment.mjs b/components/invoice_ninja/actions/create-payment/create-payment.mjs new file mode 100644 index 0000000000000..5e11d96e8b127 --- /dev/null +++ b/components/invoice_ninja/actions/create-payment/create-payment.mjs @@ -0,0 +1,165 @@ +import { parseObject } from "../../common/utils.mjs"; +import app from "../../invoice_ninja.app.mjs"; + +export default { + key: "invoice_ninja-create-payment", + name: "Create Payment", + description: "Records a payment for an invoice. [See the documentation](https://api-docs.invoicing.co/#tag/payments/POST/api/v1/payments)", + version: "0.0.1", + type: "action", + props: { + app, + clientId: { + propDefinition: [ + app, + "clientId", + ], + description: "The client hashed id", + }, + paymentId: { + type: "string", + label: "Payment ID", + description: "The payment hashed id", + optional: true, + }, + clientContactId: { + propDefinition: [ + app, + "clientContactId", + ({ clientId }) => ({ + clientId, + }), + ], + optional: true, + }, + userId: { + propDefinition: [ + app, + "userId", + ], + description: "The user hashed id", + optional: true, + }, + typeId: { + propDefinition: [ + app, + "typeId", + ], + optional: true, + }, + paymentDate: { + type: "string", + label: "Payment Date", + description: "Date of the payment (D-M-YYYY)", + optional: true, + }, + transactionReference: { + type: "string", + label: "Transaction Reference", + description: "The transaction reference as defined by the payment gateway", + optional: true, + }, + assignedUserId: { + propDefinition: [ + app, + "userId", + ], + description: "The assigned user hashed id", + optional: true, + }, + privateNotes: { + type: "string", + label: "Private Notes", + description: "The private notes of the payment", + optional: true, + }, + isManual: { + type: "boolean", + label: "Is Manual", + description: "Flags whether the payment was made manually or processed via a gateway", + optional: true, + }, + isDeleted: { + type: "boolean", + label: "Is Deleted", + description: "Defines if the payment has been deleted", + optional: true, + }, + amount: { + type: "string", + label: "Amount", + description: "The amount of this payment", + optional: true, + }, + refunded: { + type: "string", + label: "Refunded", + description: "The refunded amount of this payment", + optional: true, + }, + companyGatewayId: { + propDefinition: [ + app, + "companyGatewayId", + ], + optional: true, + }, + paymentAmount: { + type: "integer", + label: "Payment Amount", + description: "Amount of the payment", + optional: true, + }, + paymentables: { + type: "object", + label: "Paymentables", + description: "An object containing the paymentables configuration. **Example: { \"id\": \"AS3df3A\", \"invoice_id\": \"AS3df3A\", \"credit_id\": \"AS3df3A\", \"refunded\": \"10.00\", \"amount\": \"10.00\", \"updated_at\": \"1434342123\", \"created_at\": \"1434342123\" }** [See the documentation](https://api-docs.invoicing.co/#tag/payments/POST/api/v1/payments) for futher details", + optional: true, + }, + invoices: { + type: "string[]", + label: "Invoices", + description: "An array of invoice objects. **Example: [{\"invoice_id\": \"AS3df3A\", \"amount\": \"10.00\"}]** [See the documentation](https://api-docs.invoicing.co/#tag/payments/POST/api/v1/payments) for further details", + optional: true, + }, + credits: { + type: "string[]", + label: "Credits", + description: "An array of credit objects. **Example: [{\"credit_id\": \"AS3df3A\", \"amount\": \"10.00\"}]** [See the documentation](https://api-docs.invoicing.co/#tag/payments/POST/api/v1/payments) for further details", + optional: true, + }, + number: { + type: "string", + label: "Number", + description: "The payment number - is a unique alpha numeric number per payment per company", + optional: true, + }, + }, + async run({ $ }) { + const { data } = await this.app.recordPayment({ + $, + data: { + id: this.paymentId, + client_id: this.clientId, + client_contact_id: this.clientContactId, + user_id: this.userId, + type_id: this.typeId, + date: this.paymentDate, + transaction_reference: this.transactionReference, + assigned_user_id: this.assignedUserId, + private_notes: this.privateNotes, + is_manual: this.isManual, + is_deleted: this.isDeleted, + amount: this.amount && parseFloat(this.amount), + refunded: this.refunded && parseFloat(this.refunded), + company_gateway_id: this.companyGatewayId, + paymentables: this.paymentables, + invoices: parseObject(this.invoices), + credits: parseObject(this.credits), + number: this.number, + }, + }); + $.export("$summary", `Payment ${data.id} created successfully`); + return data; + }, +}; diff --git a/components/invoice_ninja/common/constants.mjs b/components/invoice_ninja/common/constants.mjs new file mode 100644 index 0000000000000..c89250ef5e75c --- /dev/null +++ b/components/invoice_ninja/common/constants.mjs @@ -0,0 +1,34 @@ +export const CLASSIFICATION_OPTIONS = [ + { + label: "Individual", + value: "individual", + }, + { + label: "Business", + value: "business", + }, + { + label: "Company", + value: "company", + }, + { + label: "Partnership", + value: "partnership", + }, + { + label: "Trust", + value: "trust", + }, + { + label: "Charity", + value: "charity", + }, + { + label: "Government", + value: "government", + }, + { + label: "Other", + value: "other", + }, +]; diff --git a/components/invoice_ninja/common/utils.mjs b/components/invoice_ninja/common/utils.mjs new file mode 100644 index 0000000000000..dcc9cc61f6f41 --- /dev/null +++ b/components/invoice_ninja/common/utils.mjs @@ -0,0 +1,24 @@ +export const parseObject = (obj) => { + if (!obj) return undefined; + + if (Array.isArray(obj)) { + return obj.map((item) => { + if (typeof item === "string") { + try { + return JSON.parse(item); + } catch (e) { + return item; + } + } + return item; + }); + } + if (typeof obj === "string") { + try { + return JSON.parse(obj); + } catch (e) { + return obj; + } + } + return obj; +}; diff --git a/components/invoice_ninja/invoice_ninja.app.mjs b/components/invoice_ninja/invoice_ninja.app.mjs index 1c15b3e8f27b4..91b9c788dc8e0 100644 --- a/components/invoice_ninja/invoice_ninja.app.mjs +++ b/components/invoice_ninja/invoice_ninja.app.mjs @@ -1,11 +1,240 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "invoice_ninja", - propDefinitions: {}, + propDefinitions: { + // Create Invoice Props + clientId: { + type: "string", + label: "Client ID", + description: "The ID of the client to associate with the invoice", + async options({ page }) { + const { data } = await this.getClients({ + params: { + page: page + 1, + }, + }); + return data.map(({ + id: value, ...client + }) => ({ + label: `${client.display_name || client.name} ${client.email + ? `(${client.email})` + : ""}}`, + value, + })); + }, + }, + userId: { + type: "string", + label: "User ID", + description: "The ID of the user creating the invoice", + async options({ page }) { + const { data } = await this.getUsers({ + params: { + page: page + 1, + }, + }); + return data.map(({ + id: value, ...user + }) => ({ + label: `${user.email || `${user.first_name} ${user.last_name}`}`, + value, + })); + }, + }, + industryId: { + type: "string", + label: "Industry ID", + description: "Industry ID of the client", + async options() { + const { industries } = await this.getStatics(); + return industries.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + sizeId: { + type: "string", + label: "Size ID", + description: "Size ID of the client", + async options() { + const { sizes } = await this.getStatics(); + return sizes.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + optional: true, + }, + // Create Client Props + countryId: { + type: "string", + label: "Country ID", + description: "The ID of the country for the client", + async options() { + const { countries } = await this.getStatics(); + return countries.map(({ + id: value, name, iso_3166_3: iso, + }) => ({ + label: `${name} (${iso})`, + value, + })); + }, + }, + groupSettingsId: { + type: "string", + label: "Group Settings ID", + description: "Group settings ID for the client", + async options({ page }) { + const { data } = await this.getGroupSettings({ + params: { + page: page + 1, + }, + }); + return data.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + // Record Payment Props + clientContactId: { + type: "string", + label: "Client Contact ID", + description: "The ID of the client's contact", + async options({ clientId }) { + const { data: { contacts } } = await this.showClient({ + clientId, + }); + return contacts.map(({ + id: value, ...contact + }) => ({ + label: `${contact.first_name} ${contact.last_name} ${contact.email + ? `(${contact.email})` + : ""}`, + value, + })); + }, + }, + typeId: { + type: "string", + label: "Type ID", + description: "The Payment Type ID", + async options() { + const { payment_types: data } = await this.getStatics(); + return data.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + companyGatewayId: { + type: "string", + label: "Company Gateway ID", + description: "The ID of the company gateway", + async options() { + const { data } = await this.getCompanyGateways(); + return data.map(({ + id: value, config: label, + }) => ({ + label, + value, + })); + }, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return "https://invoicing.co/api/v1"; + }, + _headers() { + return { + "X-Api-Token": this.$auth.api_token, + "X-Requested-With": "XMLHttpRequest", + }; + }, + _makeRequest({ + $ = this, path, ...opts + }) { + return axios($, { + url: this._baseUrl() + path, + headers: this._headers(), + ...opts, + }); + }, + createNewInvoice(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/invoices", + ...opts, + }); + }, + createNewClient(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/clients", + ...opts, + }); + }, + recordPayment(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/payments", + ...opts, + }); + }, + getClients() { + return this._makeRequest({ + path: "/clients", + }); + }, + getUsers() { + return this._makeRequest({ + path: "/users", + }); + }, + getStatics() { + return this._makeRequest({ + path: "/statics", + }); + }, + getGroupSettings() { + return this._makeRequest({ + path: "/group_settings", + }); + }, + getCompanyGateways() { + return this._makeRequest({ + path: "/company_gateways", + }); + }, + showClient({ clientId }) { + return this._makeRequest({ + path: `/clients/${clientId}`, + }); + }, + createWebhook(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/webhooks", + ...opts, + }); + }, + deleteWebhook(webhookId) { + return this._makeRequest({ + method: "DELETE", + path: `/webhooks/${webhookId}`, + }); }, }, }; diff --git a/components/invoice_ninja/package.json b/components/invoice_ninja/package.json new file mode 100644 index 0000000000000..f72dc0dd55673 --- /dev/null +++ b/components/invoice_ninja/package.json @@ -0,0 +1,18 @@ +{ + "name": "@pipedream/invoice_ninja", + "version": "0.1.0", + "description": "Pipedream Invoice Ninja Components", + "main": "invoice_ninja.app.mjs", + "keywords": [ + "pipedream", + "invoice_ninja" + ], + "homepage": "https://pipedream.com/apps/invoice_ninja", + "author": "Pipedream (https://pipedream.com/)", + "publishConfig": { + "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.3" + } +} diff --git a/components/invoice_ninja/sources/common/base.mjs b/components/invoice_ninja/sources/common/base.mjs new file mode 100644 index 0000000000000..3d84bfa0a8248 --- /dev/null +++ b/components/invoice_ninja/sources/common/base.mjs @@ -0,0 +1,47 @@ +import app from "../../invoice_ninja.app.mjs"; + +export default { + props: { + app, + http: { + type: "$.interface.http", + customResponse: true, + }, + db: "$.service.db", + }, + methods: { + _getHookId() { + return this.db.get("hookId"); + }, + _setHookId(hookId) { + this.db.set("hookId", hookId); + }, + getExtraData() { + return {}; + }, + }, + hooks: { + async activate() { + const { data } = await this.app.createWebhook({ + data: { + target_url: this.http.endpoint, + event_id: this.getEvent(), + format: "JSON", + }, + }); + + this._setHookId(data.id); + }, + async deactivate() { + const webhookId = this._getHookId(); + await this.app.deleteWebhook(webhookId); + }, + }, + async run({ body }) { + this.$emit(body, { + id: body.id, + summary: this.getSummary(body), + ts: body.created_at, + }); + }, +}; diff --git a/components/invoice_ninja/sources/new-client-instant/new-client-instant.mjs b/components/invoice_ninja/sources/new-client-instant/new-client-instant.mjs new file mode 100644 index 0000000000000..c93b626d52571 --- /dev/null +++ b/components/invoice_ninja/sources/new-client-instant/new-client-instant.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "invoice_ninja-new-client-instant", + name: "New Client (Instant)", + description: "Emit new event when a new client is added.", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getEvent() { + return 1; + }, + getSummary(client) { + return `New client: ${client.name}`; + }, + }, + sampleEmit, +}; diff --git a/components/invoice_ninja/sources/new-client-instant/test-event.mjs b/components/invoice_ninja/sources/new-client-instant/test-event.mjs new file mode 100644 index 0000000000000..17b37844896d3 --- /dev/null +++ b/components/invoice_ninja/sources/new-client-instant/test-event.mjs @@ -0,0 +1,282 @@ +export default { + "id": "Opnel5aKBz", + "contacts": [ + { + "id": "Opnel5aKBz", + "user_id": "Opnel5aKBz", + "client_id": "Opnel5aKBz", + "first_name": "John", + "last_name": "Doe", + "phone": "555-152-4524", + "custom_value1": "", + "custom_value2": "", + "custom_value3": "", + "custom_value4": "", + "email": "", + "accepted_terms_version": "A long set of ToS", + "password": "*****", + "confirmation_code": "333-sdjkh34gbasd", + "token": "333-sdjkh34gbasd", + "contact_key": "JD0X52bkfZlJRiroCJ0tcSiAjsJTntZ5uqKdiZ0a", + "is_primary": true, + "confirmed": true, + "is_locked": true, + "send_email": true, + "failed_logins": "3", + "email_verified_at": "134341234234", + "last_login": "134341234234", + "created_at": "134341234234", + "updated_at": "134341234234", + "deleted_at": "134341234234" + } + ], + "user_id": "Ua6Rw4pVbS", + "assigned_user_id": "Ua6Rw4pVbS", + "name": "Jim's Housekeeping", + "website": "https://www.jims-housekeeping.com", + "private_notes": "Client prefers email communication over phone calls", + "client_hash": "asdfkjhk342hjhbfdvmnfb1", + "industry_id": "5", + "size_id": "2", + "address1": "123 Main St", + "address2": "Apt 4B", + "city": "Beverly Hills", + "state": "California", + "postal_code": "90210", + "phone": "555-3434-3434", + "country_id": "1", + "custom_value1": "Preferred contact: Email", + "custom_value2": "Account manager: John Doe", + "custom_value3": "VIP client: Yes", + "custom_value4": "Annual contract value: $50,000", + "vat_number": "VAT123456", + "id_number": "…", + "number": "CL-0001", + "shipping_address1": "5 Wallaby Way", + "shipping_address2": "Suite 5", + "shipping_city": "Perth", + "shipping_state": "Western Australia", + "shipping_postal_code": "6110", + "shipping_country_id": "4", + "is_deleted": false, + "balance": "500.00", + "paid_to_date": "2000.00", + "credit_balance": "100.00", + "last_login": "1628686031", + "created_at": "1617629031", + "updated_at": "1628445631", + "group_settings_id": "Opnel5aKBz", + "routing_id": "Opnel5aKBz3489-dfkiu-2239-sdsd", + "is_tax_exempt": false, + "has_valid_vat_number": false, + "payment_balance": 100, + "settings": { + "currency_id": true, + "timezone_id": "15", + "date_format_id": "15", + "military_time": true, + "language_id": "1", + "show_currency_code": true, + "payment_terms": "1", + "company_gateway_ids": "1,2,3,4", + "custom_value1": "Custom Label", + "custom_value2": "Custom Label", + "custom_value3": "Custom Label", + "custom_value4": "Custom Label", + "default_task_rate": "10.00", + "send_reminders": true, + "enable_client_portal_tasks": true, + "email_style": "light", + "reply_to_email": "email@gmail.com", + "bcc_email": "email@gmail.com, contact@gmail.com", + "pdf_email_attachment": true, + "ubl_email_attachment": true, + "email_style_custom": "", + "counter_number_applied": "when_sent", + "quote_number_applied": "when_sent", + "custom_message_dashboard": "Please pay invoices immediately", + "custom_message_unpaid_invoice": "Please pay invoices immediately", + "custom_message_paid_invoice": "Thanks for paying this invoice!", + "custom_message_unapproved_quote": "Please approve quote", + "lock_invoices": true, + "auto_archive_invoice": true, + "auto_archive_quote": true, + "auto_convert_quote": true, + "inclusive_taxes": true, + "task_number_pattern": "{$year}-{$counter}", + "task_number_counter": "1", + "reminder_send_time": "32400", + "expense_number_pattern": "{$year}-{$counter}", + "expense_number_counter": "1", + "vendor_number_pattern": "{$year}-{$counter}", + "vendor_number_counter": "1", + "ticket_number_pattern": "{$year}-{$counter}", + "ticket_number_counter": "1", + "payment_number_pattern": "{$year}-{$counter}", + "payment_number_counter": "1", + "invoice_number_pattern": "{$year}-{$counter}", + "invoice_number_counter": "1", + "quote_number_pattern": "{$year}-{$counter}", + "quote_number_counter": "1", + "client_number_pattern": "{$year}-{$counter}", + "client_number_counter": "1", + "credit_number_pattern": "{$year}-{$counter}", + "credit_number_counter": "1", + "recurring_invoice_number_prefix": "R", + "reset_counter_frequency_id": "1", + "reset_counter_date": "2019-01-01", + "counter_padding": "1", + "shared_invoice_quote_counter": true, + "update_products": true, + "convert_products": true, + "fill_products": true, + "invoice_terms": "Invoice Terms are...", + "quote_terms": "Quote Terms are...", + "invoice_taxes": "1", + "invoice_design_id": "1", + "quote_design_id": "1", + "invoice_footer": "1", + "invoice_labels": "1", + "tax_rate1": "10", + "tax_name1": "GST", + "tax_rate2": "10", + "tax_name2": "GST", + "tax_rate3": "10", + "tax_name3": "GST", + "payment_type_id": "1", + "custom_fields": "{}", + "email_footer": "A default email footer", + "email_sending_method": "default", + "gmail_sending_user_id": "F76sd34D", + "email_subject_invoice": "Your Invoice Subject", + "email_subject_quote": "Your Quote Subject", + "email_subject_payment": "Your Payment Subject", + "email_template_invoice": "", + "email_template_quote": "", + "email_template_payment": "", + "email_subject_reminder1": "", + "email_subject_reminder2": "", + "email_subject_reminder3": "", + "email_subject_reminder_endless": "", + "email_template_reminder1": "", + "email_template_reminder2": "", + "email_template_reminder3": "", + "email_template_reminder_endless": "", + "enable_portal_password": true, + "show_accept_invoice_terms": true, + "show_accept_quote_terms": true, + "require_invoice_signature": true, + "require_quote_signature": true, + "name": "Acme Co", + "company_logo": "logo.png", + "website": "www.acme.com", + "address1": "Suite 888", + "address2": "5 Jimbo Way", + "city": "Sydney", + "state": "Florisa", + "postal_code": "90210", + "phone": "555-213-3948", + "email": "joe@acme.co", + "country_id": "1", + "vat_number": "32 120 377 720", + "page_size": "A4", + "font_size": "9", + "primary_font": "roboto", + "secondary_font": "roboto", + "hide_paid_to_date": false, + "embed_documents": false, + "all_pages_header": false, + "all_pages_footer": false, + "document_email_attachment": false, + "enable_client_portal_password": false, + "enable_email_markup": false, + "enable_client_portal_dashboard": false, + "enable_client_portal": false, + "email_template_statement": "template matter", + "email_subject_statement": "subject matter", + "signature_on_pdf": false, + "quote_footer": "the quote footer", + "email_subject_custom1": "Custom Subject 1", + "email_subject_custom2": "Custom Subject 2", + "email_subject_custom3": "Custom Subject 3", + "email_template_custom1": "", + "email_template_custom2": "", + "email_template_custom3": "", + "enable_reminder1": false, + "enable_reminder2": false, + "enable_reminder3": false, + "num_days_reminder1": "9", + "num_days_reminder2": "9", + "num_days_reminder3": "9", + "schedule_reminder1": "after_invoice_date", + "schedule_reminder2": "after_invoice_date", + "schedule_reminder3": "after_invoice_date", + "late_fee_amount1": 10, + "late_fee_amount2": 20, + "late_fee_amount3": 100, + "endless_reminder_frequency_id": "1", + "client_online_payment_notification": false, + "client_manual_payment_notification": false, + "enable_e_invoice": false, + "default_expense_payment_type_id": "0", + "e_invoice_type": "EN16931", + "mailgun_endpoint": "api.mailgun.net or api.eu.mailgun.net", + "client_initiated_payments": false, + "client_initiated_payments_minimum": 10, + "sync_invoice_quote_columns": false, + "show_task_item_description": false, + "allow_billable_task_items": false, + "accept_client_input_quote_approval": false, + "custom_sending_email": "bob@gmail.com", + "show_paid_stamp": false, + "show_shipping_address": false, + "company_logo_size": 100, + "show_email_footer": false, + "email_alignment": "left", + "auto_bill_standard_invoices": false, + "postmark_secret": "123456", + "mailgun_secret": "123456", + "mailgun_domain": "sandbox123456.mailgun.org", + "send_email_on_mark_paid": false, + "vendor_portal_enable_uploads": false, + "besr_id": "123456", + "qr_iban": "CH123456", + "email_subject_purchase_order": "Purchase Order", + "email_template_purchase_order": "Please see attached your purchase order.", + "require_purchase_order_signature": false, + "purchase_order_public_notes": "Please see attached your purchase order.", + "purchase_order_terms": "Please see attached your purchase order.", + "purchase_order_footer": "Please see attached your purchase order.", + "purchase_order_design_id": "hd677df", + "purchase_order_number_pattern": "PO-000000", + "purchase_order_number_counter": 1, + "page_numbering_alignment": "left", + "page_numbering": false, + "auto_archive_invoice_cancelled": false, + "email_from_name": "Bob Smith", + "show_all_tasks_client_portal": false, + "entity_send_time": 9, + "shared_invoice_credit_counter": false, + "reply_to_name": "Bob Smith", + "hide_empty_columns_on_pdf": false, + "enable_reminder_endless": false, + "use_credits_payment": false, + "recurring_invoice_number_pattern": "R-000000", + "recurring_invoice_number_counter": 1, + "client_portal_under_payment_minimum": 10, + "auto_bill_date": "on_send_date", + "primary_color": "#ffffff", + "secondary_color": "#ffffff", + "client_portal_allow_under_payment": false, + "client_portal_allow_over_payment": false, + "auto_bill": "off", + "client_portal_terms": "Please see attached your invoice.", + "client_portal_privacy_policy": "These are the terms of use for using the client portal.", + "client_can_register": false, + "portal_design_id": "hd677df", + "late_fee_endless_percent": 10, + "late_fee_endless_amount": 10, + "auto_email_invoice": false, + "email_signature": "Bob Smith" + } +} \ No newline at end of file diff --git a/components/invoice_ninja/sources/new-invoice-instant/new-invoice-instant.mjs b/components/invoice_ninja/sources/new-invoice-instant/new-invoice-instant.mjs new file mode 100644 index 0000000000000..c8908a37e4920 --- /dev/null +++ b/components/invoice_ninja/sources/new-invoice-instant/new-invoice-instant.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "invoice_ninja-new-invoice-instant", + name: "New Invoice Created (Instant)", + description: "Emit new event when a new invoice is created.", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getEvent() { + return 2; + }, + getSummary(invoice) { + return `New invoice created: ${invoice.number}`; + }, + }, + sampleEmit, +}; diff --git a/components/invoice_ninja/sources/new-invoice-instant/test-event.mjs b/components/invoice_ninja/sources/new-invoice-instant/test-event.mjs new file mode 100644 index 0000000000000..b831cd3e7472e --- /dev/null +++ b/components/invoice_ninja/sources/new-invoice-instant/test-event.mjs @@ -0,0 +1,82 @@ +export default { + "id": "Opnel5aKBz", + "user_id": "Opnel5aKBz", + "assigned_user_id": "Opnel5aKBz", + "client_id": "Opnel5aKBz", + "status_id": "4", + "number": "INV_101", + "po_number": "PO-1234", + "terms": "These are invoice terms", + "public_notes": "These are some public notes", + "private_notes": "These are some private notes", + "footer": "", + "custom_value1": "2022-10-01", + "custom_value2": "Something custom", + "custom_value3": "", + "custom_value4": "", + "tax_name1": "", + "tax_name2": "", + "tax_rate1": "10.00", + "tax_rate2": "10.00", + "tax_name3": "", + "tax_rate3": "10.00", + "total_taxes": "10.00", + "line_items": [ + { + "quantity": 1, + "cost": 10, + "product_key": "Product key", + "product_cost": 10, + "notes": "Item notes", + "discount": 5, + "is_amount_discount": false, + "tax_name1": "GST", + "tax_rate1": 10, + "tax_name2": "VAT", + "tax_rate2": 5, + "tax_name3": "CA Sales Tax", + "tax_rate3": 3, + "sort_id": "0", + "line_total": 10, + "gross_line_total": 15, + "tax_amount": 1, + "date": "2023-03-19T00:00:00Z", + "custom_value1": "Custom value 1", + "custom_value2": "Custom value 2", + "custom_value3": "Custom value 3", + "custom_value4": "Custom value 4", + "type_id": "1", + "tax_id": "1" + } + ], + "invitations": [], + "amount": "10.00", + "balance": "10.00", + "paid_to_date": "10.00", + "discount": "10.00", + "partial": "10.00", + "is_amount_discount": true, + "is_deleted": true, + "uses_inclusive_taxes": true, + "date": "1994-07-30", + "last_sent_date": "1994-07-30", + "next_send_date": "1994-07-30", + "partial_due_date": "1994-07-30", + "due_date": "1994-07-30", + "last_viewed": "1434342123", + "updated_at": "1434342123", + "created_at": "1434342123", + "archived_at": "1434342123", + "custom_surcharge1": "10.00", + "custom_surcharge2": "10.00", + "custom_surcharge3": "10.00", + "custom_surcharge4": "10.00", + "custom_surcharge_tax1": true, + "custom_surcharge_tax2": true, + "custom_surcharge_tax3": true, + "custom_surcharge_tax4": true, + "project_id": "Opnel5aKBz", + "auto_bill_tries": "1", + "auto_bill_enabled": true, + "subscription_id": "Opnel5aKBz" +} \ No newline at end of file diff --git a/components/invoice_ninja/sources/new-payment-instant/new-payment-instant.mjs b/components/invoice_ninja/sources/new-payment-instant/new-payment-instant.mjs new file mode 100644 index 0000000000000..47b1346550d3f --- /dev/null +++ b/components/invoice_ninja/sources/new-payment-instant/new-payment-instant.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "invoice_ninja-new-payment-instant", + name: "New Payment Registered (Instant)", + description: "Emit new event when a new payment is registered.", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getEvent() { + return 4; + }, + getSummary(payment) { + return `New payment created: ${payment.number}`; + }, + }, + sampleEmit, +}; diff --git a/components/invoice_ninja/sources/new-payment-instant/test-event.mjs b/components/invoice_ninja/sources/new-payment-instant/test-event.mjs new file mode 100644 index 0000000000000..6b96960c40c29 --- /dev/null +++ b/components/invoice_ninja/sources/new-payment-instant/test-event.mjs @@ -0,0 +1,42 @@ +export default { + "id": "Opnel5aKBz", + "client_id": "Opnel5aKBz", + "invitation_id": "Opnel5aKBz", + "client_contact_id": "Opnel5aKBz", + "user_id": "Opnel5aKBz", + "type_id": "1", + "date": "1-1-2014", + "transaction_reference": "xcsSxcs124asd", + "assigned_user_id": "Opnel5aKBz", + "private_notes": "The payment was refunded due to error", + "is_manual": true, + "is_deleted": true, + "amount": 10, + "refunded": 10, + "created_at": "1434342123", + "updated_at": "1434342123", + "archived_at": "1434342123", + "company_gateway_id": "3", + "paymentables": { + "id": "AS3df3A", + "invoice_id": "AS3df3A", + "credit_id": "AS3df3A", + "refunded": "10.00", + "amount": "10.00", + "updated_at": "1434342123", + "created_at": "1434342123" + }, + "invoices": [ + { + "invoice_id": "Opnel5aKBz", + "amount": "2" + } + ], + "credits": [ + { + "credit_id": "Opnel5aKBz", + "amount": "2" + } + ], + "number": "PAY_101" +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a2d916b34964b..2984e40926adc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5333,6 +5333,12 @@ importers: specifier: ^3.0.0 version: 3.0.3 + components/invoice_ninja: + dependencies: + '@pipedream/platform': + specifier: ^3.0.3 + version: 3.0.3 + components/invoicing_plus: {} components/ip2location: @@ -8294,8 +8300,7 @@ importers: components/propeller: {} - components/proposify: - specifiers: {} + components/proposify: {} components/proprofs_quiz_maker: {}