UNPKG

n8n-nodes-alegra-unofficial

Version:

Unofficial Alegra node for n8n - Community integration with Alegra's accounting platform. NOT OFFICIALLY SUPPORTED BY ALEGRA.

790 lines 33.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Alegra = void 0; const n8n_workflow_1 = require("n8n-workflow"); const contact_operations_1 = require("./operations/contact.operations"); const invoice_operations_1 = require("./operations/invoice.operations"); const item_operations_1 = require("./operations/item.operations"); const payment_operations_1 = require("./operations/payment.operations"); const estimate_operations_1 = require("./operations/estimate.operations"); const tax_operations_1 = require("./operations/tax.operations"); const bankAccount_operations_1 = require("./operations/bankAccount.operations"); class Alegra { constructor() { this.description = { displayName: 'Alegra (Unofficial - BETA)', name: 'alegra', icon: 'file:alegra.svg', group: ['transform'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', description: 'Consume Alegra API - UNOFFICIAL BETA community node. NOT officially supported by Alegra.', defaults: { name: 'Alegra', }, inputs: [{ type: 'main' }], outputs: [{ type: 'main' }], credentials: [ { name: 'alegraApi', required: true, }, ], properties: [ { displayName: 'Resource', name: 'resource', type: 'options', noDataExpression: true, options: [ { name: 'Contact', value: 'contact', description: 'Manage contacts (clients and providers)', }, { name: 'Invoice', value: 'invoice', description: 'Manage sales invoices', }, { name: 'Item', value: 'item', description: 'Manage products and services', }, { name: 'Payment', value: 'payment', description: 'Manage payments', }, { name: 'Estimate', value: 'estimate', description: 'Manage estimates/quotes', }, { name: 'Tax', value: 'tax', description: 'Manage taxes', }, { name: 'Bank Account', value: 'bankAccount', description: 'Manage bank accounts', }, ], default: 'contact', }, ...contact_operations_1.contactOperations, ...invoice_operations_1.invoiceOperations, ...item_operations_1.itemOperations, ...payment_operations_1.paymentOperations, ...estimate_operations_1.estimateOperations, ...tax_operations_1.taxOperations, ...bankAccount_operations_1.bankAccountOperations, ], }; this.methods = { loadOptions: { async getContacts() { const returnData = []; const contacts = await alegraApiRequest.call(this, 'GET', '/contacts'); for (const contact of contacts) { returnData.push({ name: contact.name, value: contact.id, }); } return returnData; }, async getItems() { const returnData = []; const items = await alegraApiRequest.call(this, 'GET', '/items'); for (const item of items) { returnData.push({ name: item.name, value: item.id, }); } return returnData; }, async getTaxes() { const returnData = []; const taxes = await alegraApiRequest.call(this, 'GET', '/taxes'); for (const tax of taxes) { returnData.push({ name: `${tax.name} (${tax.percentage}%)`, value: tax.id, }); } return returnData; }, async getBankAccounts() { const returnData = []; const accounts = await alegraApiRequest.call(this, 'GET', '/bank-accounts'); for (const account of accounts) { returnData.push({ name: account.name, value: account.id, }); } return returnData; }, async getSellers() { const returnData = []; const sellers = await alegraApiRequest.call(this, 'GET', '/sellers'); for (const seller of sellers) { returnData.push({ name: seller.name, value: seller.id, }); } return returnData; }, async getCategories() { const returnData = []; const categories = await alegraApiRequest.call(this, 'GET', '/categories'); for (const category of categories) { returnData.push({ name: category.name, value: category.id, }); } return returnData; }, async getAccountCategories() { const returnData = []; const categories = await alegraApiRequest.call(this, 'GET', '/account-categories'); for (const category of categories) { returnData.push({ name: category.name, value: category.id, }); } return returnData; }, async getNumberTemplates() { const returnData = []; const templates = await alegraApiRequest.call(this, 'GET', '/number-templates/invoices'); for (const template of templates) { returnData.push({ name: template.name, value: template.id, }); } return returnData; }, async getCostCenters() { const returnData = []; const centers = await alegraApiRequest.call(this, 'GET', '/cost-centers'); for (const center of centers) { returnData.push({ name: center.name, value: center.id, }); } return returnData; }, async getPriceLists() { const returnData = []; const lists = await alegraApiRequest.call(this, 'GET', '/price-lists'); for (const list of lists) { returnData.push({ name: list.name, value: list.id, }); } return returnData; }, async getRetentions() { const returnData = []; const retentions = await alegraApiRequest.call(this, 'GET', '/retentions'); for (const retention of retentions) { returnData.push({ name: `${retention.name} (${retention.percentage}%)`, value: retention.id, }); } return returnData; }, }, }; } async execute() { const items = this.getInputData(); const returnData = []; const resource = this.getNodeParameter('resource', 0); const operation = this.getNodeParameter('operation', 0); for (let i = 0; i < items.length; i++) { try { let responseData; if (resource === 'contact') { responseData = await handleContactOperations.call(this, operation, i); } else if (resource === 'invoice') { responseData = await handleInvoiceOperations.call(this, operation, i); } else if (resource === 'item') { responseData = await handleItemOperations.call(this, operation, i); } else if (resource === 'payment') { responseData = await handlePaymentOperations.call(this, operation, i); } else if (resource === 'estimate') { responseData = await handleEstimateOperations.call(this, operation, i); } else if (resource === 'tax') { responseData = await handleTaxOperations.call(this, operation, i); } else if (resource === 'bankAccount') { responseData = await handleBankAccountOperations.call(this, operation, i); } if (Array.isArray(responseData)) { returnData.push(...responseData.map(item => ({ json: item }))); } else { returnData.push({ json: responseData }); } } catch (error) { if (this.continueOnFail()) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; returnData.push({ json: { error: errorMessage } }); continue; } throw error; } } return [returnData]; } } exports.Alegra = Alegra; // Helper function to make API requests async function alegraApiRequest(method, endpoint, body = {}, query = {}) { const credentials = await this.getCredentials('alegraApi'); const options = { method: method, url: `${credentials.environment}/api/v1${endpoint}`, json: true, qs: query, }; if (Object.keys(body).length !== 0) { options.body = body; } try { return await this.helpers.requestWithAuthentication.call(this, 'alegraApi', options); } catch (error) { if (error instanceof Error) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message); } throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Unknown error occurred'); } } // Contact operations handler async function handleContactOperations(operation, index) { if (operation === 'create') { const name = this.getNodeParameter('name', index); const type = this.getNodeParameter('type', index); const identificationType = this.getNodeParameter('identificationType', index); const identificationNumber = this.getNodeParameter('identificationNumber', index); const additionalFields = this.getNodeParameter('additionalFields', index); const body = { name, type, identification: { type: identificationType, number: identificationNumber, }, }; Object.assign(body, additionalFields); // Handle address fields if (additionalFields.address?.addressFields) { body.address = additionalFields.address.addressFields; delete body.address.addressFields; } return await alegraApiRequest.call(this, 'POST', '/contacts', body); } if (operation === 'get') { const id = this.getNodeParameter('id', index); return await alegraApiRequest.call(this, 'GET', `/contacts/${id}`); } if (operation === 'getAll') { const returnAll = this.getNodeParameter('returnAll', index); const filters = this.getNodeParameter('filters', index); const query = {}; if (!returnAll) { query.limit = this.getNodeParameter('limit', index); } Object.assign(query, filters); return await alegraApiRequest.call(this, 'GET', '/contacts', {}, query); } if (operation === 'update') { const id = this.getNodeParameter('id', index); const updateFields = this.getNodeParameter('updateFields', index); const body = {}; Object.assign(body, updateFields); // Handle address fields if (updateFields.address?.addressFields) { body.address = updateFields.address.addressFields; delete body.address.addressFields; } return await alegraApiRequest.call(this, 'PUT', `/contacts/${id}`, body); } if (operation === 'delete') { const id = this.getNodeParameter('id', index); return await alegraApiRequest.call(this, 'DELETE', `/contacts/${id}`); } } // Invoice operations handler async function handleInvoiceOperations(operation, index) { if (operation === 'create') { const date = this.getNodeParameter('date', index); const dueDate = this.getNodeParameter('dueDate', index); const client = this.getNodeParameter('client', index); const paymentForm = this.getNodeParameter('paymentForm', index); const paymentMethod = this.getNodeParameter('paymentMethod', index); const generateStamp = this.getNodeParameter('generateStamp', index); const items = this.getNodeParameter('items', index); const additionalFields = this.getNodeParameter('additionalFields', index); const body = { date: date.split('T')[0], dueDate: dueDate.split('T')[0], client: { id: client }, paymentForm, paymentMethod, stamp: { generateStamp }, items: items.item, currency: { code: additionalFields.currency || 'COP' }, }; // Handle additional fields if (additionalFields.seller) body.seller = { id: additionalFields.seller }; if (additionalFields.observations) body.observations = additionalFields.observations; if (additionalFields.anotation) body.anotation = additionalFields.anotation; if (additionalFields.termsConditions) body.termsConditions = additionalFields.termsConditions; if (additionalFields.numberTemplate) body.numberTemplate = { id: additionalFields.numberTemplate }; if (additionalFields.costCenter) body.costCenter = { id: additionalFields.costCenter }; if (additionalFields.exchangeRate) body.exchangeRate = additionalFields.exchangeRate; if (additionalFields.type) body.type = additionalFields.type; if (additionalFields.retentions) { body.retentions = additionalFields.retentions.map((id) => ({ id })); } // Process items body.items = body.items.map((item) => { const processedItem = { id: item.id, price: item.price, quantity: item.quantity, description: item.description, }; if (item.discount) processedItem.discount = item.discount; if (item.tax && item.tax.length > 0) { processedItem.tax = item.tax.map((taxId) => ({ id: taxId })); } return processedItem; }); return await alegraApiRequest.call(this, 'POST', '/invoices', body); } if (operation === 'get') { const id = this.getNodeParameter('id', index); return await alegraApiRequest.call(this, 'GET', `/invoices/${id}`); } if (operation === 'getAll') { const returnAll = this.getNodeParameter('returnAll', index); const filters = this.getNodeParameter('filters', index); const query = {}; if (!returnAll) { query.limit = this.getNodeParameter('limit', index); } if (filters.start) query.start = filters.start.split('T')[0]; if (filters.end) query.end = filters.end.split('T')[0]; if (filters.status) query.status = filters.status; if (filters.client) query.client = filters.client; if (filters.orderBy) query.orderBy = filters.orderBy; if (filters.orderDirection) query.order = filters.orderDirection; return await alegraApiRequest.call(this, 'GET', '/invoices', {}, query); } if (operation === 'sendEmail') { const id = this.getNodeParameter('id', index); const emails = this.getNodeParameter('emails', index); const sendCopyToUser = this.getNodeParameter('sendCopyToUser', index); const invoiceType = this.getNodeParameter('invoiceType', index); const body = { emails, send_copy_to_user: sendCopyToUser, invoice_type: invoiceType, }; return await alegraApiRequest.call(this, 'POST', `/invoices/${id}/email`, body); } if (operation === 'update') { const id = this.getNodeParameter('id', index); const updateFields = this.getNodeParameter('updateFields', index); const body = {}; if (updateFields.date) body.date = updateFields.date.split('T')[0]; if (updateFields.dueDate) body.dueDate = updateFields.dueDate.split('T')[0]; if (updateFields.observations) body.observations = updateFields.observations; if (updateFields.anotation) body.anotation = updateFields.anotation; if (updateFields.status) body.status = updateFields.status; return await alegraApiRequest.call(this, 'PUT', `/invoices/${id}`, body); } if (operation === 'delete') { const id = this.getNodeParameter('id', index); return await alegraApiRequest.call(this, 'DELETE', `/invoices/${id}`); } } // Item operations handler async function handleItemOperations(operation, index) { if (operation === 'create') { const name = this.getNodeParameter('name', index); const type = this.getNodeParameter('type', index); const price = this.getNodeParameter('price', index); const additionalFields = this.getNodeParameter('additionalFields', index); const body = { name, type, price, }; Object.assign(body, additionalFields); if (additionalFields.tax && additionalFields.tax.length > 0) { body.tax = additionalFields.tax.map((taxId) => ({ id: taxId })); } if (additionalFields.category) { body.category = { id: additionalFields.category }; } return await alegraApiRequest.call(this, 'POST', '/items', body); } if (operation === 'get') { const id = this.getNodeParameter('id', index); return await alegraApiRequest.call(this, 'GET', `/items/${id}`); } if (operation === 'getAll') { const returnAll = this.getNodeParameter('returnAll', index); const filters = this.getNodeParameter('filters', index); const query = {}; if (!returnAll) { query.limit = this.getNodeParameter('limit', index); } Object.assign(query, filters); return await alegraApiRequest.call(this, 'GET', '/items', {}, query); } if (operation === 'update') { const id = this.getNodeParameter('id', index); const updateFields = this.getNodeParameter('updateFields', index); const body = {}; Object.assign(body, updateFields); if (updateFields.tax && updateFields.tax.length > 0) { body.tax = updateFields.tax.map((taxId) => ({ id: taxId })); } if (updateFields.category) { body.category = { id: updateFields.category }; } return await alegraApiRequest.call(this, 'PUT', `/items/${id}`, body); } if (operation === 'delete') { const id = this.getNodeParameter('id', index); return await alegraApiRequest.call(this, 'DELETE', `/items/${id}`); } } // Payment operations handler async function handlePaymentOperations(operation, index) { if (operation === 'create') { const date = this.getNodeParameter('date', index); const bankAccount = this.getNodeParameter('bankAccount', index); const paymentMethod = this.getNodeParameter('paymentMethod', index); const type = this.getNodeParameter('type', index); const invoices = this.getNodeParameter('invoices', index); const additionalFields = this.getNodeParameter('additionalFields', index); const body = { date: date.split('T')[0], bankAccount: bankAccount, paymentMethod, type, invoices: invoices.invoice, currency: { code: additionalFields.currency || 'COP' }, }; if (additionalFields.contact) body.client = additionalFields.contact; if (additionalFields.observations) body.observations = additionalFields.observations; if (additionalFields.anotation) body.anotation = additionalFields.anotation; if (additionalFields.exchangeRate) body.exchangeRate = additionalFields.exchangeRate; if (additionalFields.categories?.category) { body.categories = additionalFields.categories.category.map((cat) => { const category = { id: cat.id, price: cat.price, }; if (cat.description) category.description = cat.description; if (cat.tax && cat.tax.length > 0) { category.tax = cat.tax.map((taxId) => ({ id: taxId })); } return category; }); } if (additionalFields.retentions?.retention) { body.retentions = additionalFields.retentions.retention; } return await alegraApiRequest.call(this, 'POST', '/payments', body); } if (operation === 'get') { const id = this.getNodeParameter('id', index); return await alegraApiRequest.call(this, 'GET', `/payments/${id}`); } if (operation === 'getAll') { const returnAll = this.getNodeParameter('returnAll', index); const filters = this.getNodeParameter('filters', index); const query = {}; if (!returnAll) { query.limit = this.getNodeParameter('limit', index); } if (filters.start) query.start = filters.start.split('T')[0]; if (filters.end) query.end = filters.end.split('T')[0]; if (filters.type) query.type = filters.type; if (filters.contact) query.contact = filters.contact; if (filters.bankAccount) query.bankAccount = filters.bankAccount; if (filters.orderBy) query.orderBy = filters.orderBy; if (filters.orderDirection) query.order = filters.orderDirection; return await alegraApiRequest.call(this, 'GET', '/payments', {}, query); } if (operation === 'delete') { const id = this.getNodeParameter('id', index); return await alegraApiRequest.call(this, 'DELETE', `/payments/${id}`); } } // Estimate operations handler async function handleEstimateOperations(operation, index) { if (operation === 'create') { const date = this.getNodeParameter('date', index); const dueDate = this.getNodeParameter('dueDate', index); const client = this.getNodeParameter('client', index); const items = this.getNodeParameter('items', index); const additionalFields = this.getNodeParameter('additionalFields', index); const body = { date: date.split('T')[0], dueDate: dueDate.split('T')[0], client: { id: client }, items: items.item, currency: { code: additionalFields.currency || 'COP' }, }; // Handle additional fields if (additionalFields.seller) body.seller = { id: additionalFields.seller }; if (additionalFields.observations) body.observations = additionalFields.observations; if (additionalFields.anotation) body.anotation = additionalFields.anotation; if (additionalFields.termsConditions) body.termsConditions = additionalFields.termsConditions; if (additionalFields.status) body.status = additionalFields.status; if (additionalFields.exchangeRate) body.exchangeRate = additionalFields.exchangeRate; // Process items body.items = body.items.map((item) => { const processedItem = { id: item.id, price: item.price, quantity: item.quantity, }; if (item.description) processedItem.description = item.description; if (item.discount) processedItem.discount = item.discount; if (item.tax && item.tax.length > 0) { processedItem.tax = item.tax.map((taxId) => ({ id: taxId })); } return processedItem; }); return await alegraApiRequest.call(this, 'POST', '/estimates', body); } if (operation === 'get') { const id = this.getNodeParameter('id', index); return await alegraApiRequest.call(this, 'GET', `/estimates/${id}`); } if (operation === 'getAll') { const returnAll = this.getNodeParameter('returnAll', index); const filters = this.getNodeParameter('filters', index); const query = {}; if (!returnAll) { query.limit = this.getNodeParameter('limit', index); } if (filters.start) query.start = filters.start.split('T')[0]; if (filters.end) query.end = filters.end.split('T')[0]; if (filters.status) query.status = filters.status; if (filters.client) query.client = filters.client; if (filters.orderBy) query.orderBy = filters.orderBy; if (filters.orderDirection) query.order = filters.orderDirection; return await alegraApiRequest.call(this, 'GET', '/estimates', {}, query); } if (operation === 'sendEmail') { const id = this.getNodeParameter('id', index); const to = this.getNodeParameter('to', index); const sendCopyToMyself = this.getNodeParameter('sendCopyToMyself', index); const body = { to, send_copy_to_myself: sendCopyToMyself, }; return await alegraApiRequest.call(this, 'POST', `/estimates/${id}/email`, body); } if (operation === 'update') { const id = this.getNodeParameter('id', index); const updateFields = this.getNodeParameter('updateFields', index); const body = {}; if (updateFields.date) body.date = updateFields.date.split('T')[0]; if (updateFields.dueDate) body.dueDate = updateFields.dueDate.split('T')[0]; if (updateFields.observations) body.observations = updateFields.observations; if (updateFields.anotation) body.anotation = updateFields.anotation; if (updateFields.status) body.status = updateFields.status; return await alegraApiRequest.call(this, 'PUT', `/estimates/${id}`, body); } if (operation === 'delete') { const id = this.getNodeParameter('id', index); return await alegraApiRequest.call(this, 'DELETE', `/estimates/${id}`); } } // Tax operations handler async function handleTaxOperations(operation, index) { if (operation === 'create') { const name = this.getNodeParameter('name', index); const percentage = this.getNodeParameter('percentage', index); const type = this.getNodeParameter('type', index); const additionalFields = this.getNodeParameter('additionalFields', index); const body = { name, percentage, type, }; Object.assign(body, additionalFields); return await alegraApiRequest.call(this, 'POST', '/taxes', body); } if (operation === 'get') { const id = this.getNodeParameter('id', index); return await alegraApiRequest.call(this, 'GET', `/taxes/${id}`); } if (operation === 'getAll') { const returnAll = this.getNodeParameter('returnAll', index); const filters = this.getNodeParameter('filters', index); const query = {}; if (!returnAll) { query.limit = this.getNodeParameter('limit', index); } Object.assign(query, filters); return await alegraApiRequest.call(this, 'GET', '/taxes', {}, query); } if (operation === 'update') { const id = this.getNodeParameter('id', index); const updateFields = this.getNodeParameter('updateFields', index); const body = {}; Object.assign(body, updateFields); return await alegraApiRequest.call(this, 'PUT', `/taxes/${id}`, body); } if (operation === 'delete') { const id = this.getNodeParameter('id', index); return await alegraApiRequest.call(this, 'DELETE', `/taxes/${id}`); } } // Bank Account operations handler async function handleBankAccountOperations(operation, index) { if (operation === 'create') { const name = this.getNodeParameter('name', index); const type = this.getNodeParameter('type', index); const initialBalance = this.getNodeParameter('initialBalance', index); const initialBalanceDate = this.getNodeParameter('initialBalanceDate', index); const additionalFields = this.getNodeParameter('additionalFields', index); const body = { name, type, initialBalance: initialBalance.toString(), initialBalanceDate: initialBalanceDate.split('T')[0], }; Object.assign(body, additionalFields); if (additionalFields.currency) { body.currency = { code: additionalFields.currency }; } return await alegraApiRequest.call(this, 'POST', '/bank-accounts', body); } if (operation === 'get') { const id = this.getNodeParameter('id', index); return await alegraApiRequest.call(this, 'GET', `/bank-accounts/${id}`); } if (operation === 'getAll') { const returnAll = this.getNodeParameter('returnAll', index); const filters = this.getNodeParameter('filters', index); const query = {}; if (!returnAll) { query.limit = this.getNodeParameter('limit', index); } Object.assign(query, filters); return await alegraApiRequest.call(this, 'GET', '/bank-accounts', {}, query); } if (operation === 'transfer') { const sourceAccount = this.getNodeParameter('sourceAccount', index); const destinationAccount = this.getNodeParameter('destinationAccount', index); const amount = this.getNodeParameter('amount', index); const date = this.getNodeParameter('date', index); const additionalFields = this.getNodeParameter('additionalFields', index); const body = { id_destination: destinationAccount, amount, date: date.split('T')[0], }; if (additionalFields.description) body.description = additionalFields.description; if (additionalFields.observations) body.observations = additionalFields.observations; return await alegraApiRequest.call(this, 'POST', `/bank-accounts/${sourceAccount}/transfer`, body); } if (operation === 'update') { const id = this.getNodeParameter('id', index); const updateFields = this.getNodeParameter('updateFields', index); const body = {}; Object.assign(body, updateFields); return await alegraApiRequest.call(this, 'PUT', `/bank-accounts/${id}`, body); } if (operation === 'delete') { const id = this.getNodeParameter('id', index); return await alegraApiRequest.call(this, 'DELETE', `/bank-accounts/${id}`); } } //# sourceMappingURL=Alegra.node.js.map