n8n-nodes-tiny-erp-api-v2
Version:
Custom nodes for Tiny ERP integration with n8n, including AI tools for AI Agent workflows
285 lines • 10.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.execute = exports.description = void 0;
const n8n_workflow_1 = require("n8n-workflow");
const api_1 = require("../../transport/api");
exports.description = [
{
displayName: 'Product ID',
name: 'idProduto',
type: 'string',
default: '',
description: 'The ID of the product to update stock for',
displayOptions: {
show: {
resource: ['products'],
operation: ['updateStock'],
},
},
required: true,
placeholder: 'e.g., 12345888',
},
{
displayName: 'Stock Quantity',
name: 'quantidade',
type: 'number',
default: 0,
description: 'The quantity to add, subtract, or set as balance (positive for entry, negative for exit, or absolute value for balance)',
displayOptions: {
show: {
resource: ['products'],
operation: ['updateStock'],
},
},
required: true,
placeholder: 'e.g., 10',
},
{
displayName: 'Deposit Selection',
name: 'depositSelection',
type: 'options',
options: [
{
name: 'By Deposit ID',
value: 'byId',
description: 'Use deposit ID to identify the warehouse',
},
{
name: 'By Deposit Name',
value: 'byName',
description: 'Use deposit name to identify the warehouse',
},
],
default: 'byId',
description: 'Choose how to identify the deposit/warehouse',
displayOptions: {
show: {
resource: ['products'],
operation: ['updateStock'],
},
},
required: true,
},
{
displayName: 'Deposit ID',
name: 'idDeposito',
type: 'string',
default: '',
description: 'ID of the deposit/warehouse where the stock will be updated',
displayOptions: {
show: {
resource: ['products'],
operation: ['updateStock'],
depositSelection: ['byId'],
},
},
required: true,
placeholder: 'e.g., 123456',
},
{
displayName: 'Deposit Name',
name: 'deposito',
type: 'string',
default: '',
description: 'Name of the deposit/warehouse where the stock will be updated',
displayOptions: {
show: {
resource: ['products'],
operation: ['updateStock'],
depositSelection: ['byName'],
},
},
required: true,
placeholder: 'e.g., deposito central',
},
{
displayName: 'Movement Type',
name: 'tipo',
type: 'options',
options: [
{
name: 'Entry (E)',
value: 'E',
description: 'Stock entry - adds to inventory',
},
{
name: 'Exit (S)',
value: 'S',
description: 'Stock exit - removes from inventory',
},
{
name: 'Balance (B)',
value: 'B',
description: 'Stock balance - sets absolute inventory quantity',
},
],
default: 'E',
description: 'Type of stock movement',
displayOptions: {
show: {
resource: ['products'],
operation: ['updateStock'],
},
},
required: true,
},
{
displayName: 'Unit Price',
name: 'precoUnitario',
type: 'number',
default: '',
description: 'Unit price for the stock movement (optional)',
displayOptions: {
show: {
resource: ['products'],
operation: ['updateStock'],
},
},
placeholder: 'e.g., 25.78',
},
{
displayName: 'Date',
name: 'data',
type: 'dateTime',
default: '',
description: 'Date and time of the stock movement (optional, defaults to current date/time)',
displayOptions: {
show: {
resource: ['products'],
operation: ['updateStock'],
},
},
placeholder: 'e.g., 2024-01-15 14:30:00',
},
{
displayName: 'Observations',
name: 'observacoes',
type: 'string',
default: '',
description: 'Additional observations for the stock movement (optional)',
displayOptions: {
show: {
resource: ['products'],
operation: ['updateStock'],
},
},
placeholder: 'e.g., Stock adjustment due to inventory count',
},
];
async function execute(index) {
var _a, _b;
const credentials = await this.getCredentials('tinyErpApi');
const api = new api_1.TinyErpApi(this, credentials);
const idProduto = this.getNodeParameter('idProduto', index);
const quantidade = this.getNodeParameter('quantidade', index);
const depositSelection = this.getNodeParameter('depositSelection', index);
const tipo = this.getNodeParameter('tipo', index);
let idDeposito = '';
let deposito = '';
if (depositSelection === 'byId') {
idDeposito = this.getNodeParameter('idDeposito', index);
}
else {
deposito = this.getNodeParameter('deposito', index);
}
const precoUnitario = this.getNodeParameter('precoUnitario', index);
const data = this.getNodeParameter('data', index);
const observacoes = this.getNodeParameter('observacoes', index);
if (!idProduto || idProduto.trim() === '') {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Product ID (idProduto) is required for stock update');
}
if (quantidade === undefined || quantidade === null) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Stock quantity (quantidade) is required for stock update');
}
if (depositSelection === 'byId' && (!idDeposito || idDeposito.trim() === '')) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Deposit ID (idDeposito) is required when using "By Deposit ID" selection');
}
if (depositSelection === 'byName' && (!deposito || deposito.trim() === '')) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Deposit Name (deposito) is required when using "By Deposit Name" selection');
}
if (!tipo || (tipo !== 'E' && tipo !== 'S' && tipo !== 'B')) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Movement type (tipo) must be either "E" (entry), "S" (exit), or "B" (balance)');
}
try {
const stockData = {
idProduto: idProduto.trim(),
tipo,
quantidade: quantidade.toString(),
};
if (depositSelection === 'byId') {
stockData.idDeposito = idDeposito.trim();
}
else {
stockData.deposito = deposito.trim();
}
if (precoUnitario && precoUnitario > 0) {
stockData.precoUnitario = precoUnitario.toString();
}
if (data && data.trim() !== '') {
stockData.data = data.trim();
}
else {
const now = new Date();
stockData.data = now.toISOString().replace('T', ' ').substring(0, 19);
}
if (observacoes && observacoes.trim() !== '') {
stockData.observacoes = observacoes.trim();
}
const response = await api.updateStock(stockData);
if (!response || typeof response !== 'object') {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response from Tiny ERP API - expected object, got ${typeof response}: ${JSON.stringify(response)}`);
}
if (!response.retorno) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid response structure from Tiny ERP API - missing 'retorno' field: ${JSON.stringify(response)}`);
}
const retorno = response.retorno;
if (retorno.erros && retorno.erros.length > 0) {
const errors = retorno.erros.map((e) => e.erro);
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Tiny ERP API error: ${errors.join(', ')}`);
}
if (retorno.registros && Array.isArray(retorno.registros)) {
for (const registro of retorno.registros) {
if (registro.registro && registro.registro.status === 'Erro') {
const recordErrors = ((_a = registro.registro.erros) === null || _a === void 0 ? void 0 : _a.map((e) => e.erro)) || ['Unknown error'];
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Stock update error: ${recordErrors.join(', ')}`);
}
}
}
if (retorno.status !== 'OK') {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Tiny ERP API error: API returned status: ${retorno.status}`);
}
let resultData = null;
if (retorno.registros) {
if (Array.isArray(retorno.registros)) {
resultData = (_b = retorno.registros[0]) === null || _b === void 0 ? void 0 : _b.registro;
}
else if (retorno.registros.registro) {
resultData = retorno.registros.registro;
}
}
const responseData = {
success: true,
message: 'Stock updated successfully',
operation: 'updateStock',
resource: 'products',
productId: idProduto,
quantity: quantidade,
depositSelection,
depositId: depositSelection === 'byId' ? idDeposito : undefined,
depositName: depositSelection === 'byName' ? deposito : undefined,
movementType: tipo,
timestamp: new Date().toISOString(),
result: resultData,
stockData: stockData,
};
return [{ json: responseData }];
}
catch (error) {
if (error instanceof n8n_workflow_1.NodeOperationError) {
throw error;
}
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to update stock: ${error.message}`);
}
}
exports.execute = execute;
//# sourceMappingURL=updateStock.operation.js.map