n8n-nodes-centum 0.2.23 → 0.2.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -124,7 +124,7 @@ class Centum {
124
124
  }
125
125
  }
126
126
  case "articuloPorId": {
127
- const codigo = this.getNodeParameter("codigo", 0);
127
+ const codigo = this.getNodeParameter("codigoArticulo", 0);
128
128
  const articleId = this.getNodeParameter("articleId", 0);
129
129
  const fechaCreacionDesde = this.getNodeParameter("startDate", 0);
130
130
  const fechaCreacionHasta = this.getNodeParameter("endDate", 0);
@@ -250,7 +250,7 @@ class Centum {
250
250
  return [this.helpers.returnJsonArray(arrResult)];
251
251
  }
252
252
  case "articulosPrecioPorLista": {
253
- const idArticulos = this.getNodeParameter("codigo", 0);
253
+ const idArticulos = this.getNodeParameter("codigoArticulo", 0);
254
254
  const idLista = this.getNodeParameter("idList", 0);
255
255
  if (!idLista || !idArticulos) {
256
256
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), "El id de la lista y el artículo son obligatorios.");
@@ -291,7 +291,7 @@ class Centum {
291
291
  case "articuloSucursalFisica": {
292
292
  const IdSucursalFisica = this.getNodeParameter("idSucursalFisica", 0);
293
293
  const idArticulo = this.getNodeParameter("articleId", 0);
294
- const codigo = this.getNodeParameter("codigo", 0);
294
+ const codigo = this.getNodeParameter("codigoArticulo", 0);
295
295
  const nombre = this.getNodeParameter("nombreArticulo", 0);
296
296
  const queryParams = {
297
297
  IdSucursalFisica: IdSucursalFisica,
@@ -317,7 +317,7 @@ class Centum {
317
317
  }
318
318
  case 'buscarArticulo': {
319
319
  const nombreArticulo = this.getNodeParameter('nombreArticulo', 0, '');
320
- const codigoArticulo = this.getNodeParameter('codigo', 0, '');
320
+ const codigoArticulo = this.getNodeParameter('codigoArticulo', 0, '');
321
321
  try {
322
322
  const response = await (0, functions_1.apiRequest)(`${centumUrl}/Articulos/DatosGenerales`, {
323
323
  method: 'POST',
@@ -445,7 +445,7 @@ class Centum {
445
445
  }
446
446
  }
447
447
  case "clientesBusqueda": {
448
- const codigo = this.getNodeParameter("codigo", 0, "");
448
+ const codigo = this.getNodeParameter("codigoCliente", 0, "");
449
449
  const cuit = this.getNodeParameter("cuit", 0, "");
450
450
  const razonSocial = this.getNodeParameter("razonSocial", 0, "");
451
451
  if (!codigo && !cuit && !razonSocial) {
@@ -455,7 +455,7 @@ class Centum {
455
455
  if (cuit)
456
456
  queryParams.Cuit = cuit;
457
457
  if (codigo)
458
- queryParams.Codigo = codigo;
458
+ queryParams.codigo = codigo;
459
459
  if (razonSocial)
460
460
  queryParams.RazonSocial = razonSocial;
461
461
  try {
@@ -540,40 +540,139 @@ class Centum {
540
540
  }
541
541
  }
542
542
  case "crearPedidoVenta": {
543
- const customerSalesOrder = this.getNodeParameter("cliente", 0);
544
- const articlesSalesOrder = this.getNodeParameter("articulo", 0);
545
- const shippingSalesOrder = this.getNodeParameter("envio", 0);
546
- const idCobro = this.getNodeParameter("idCobro", 0);
547
- const date = new Date().toISOString();
548
- const formattedDate = date.replace(/\..+/, "");
543
+ const razonSocial = this.getNodeParameter('razonSocial', 0);
544
+ const articulosRaw = this.getNodeParameter('articulo', 0);
545
+ let articulos;
546
+ if (typeof articulosRaw === 'string') {
547
+ try {
548
+ const parsed = JSON.parse(articulosRaw);
549
+ if (typeof parsed === 'object' && !Array.isArray(parsed)) {
550
+ articulos = [parsed];
551
+ }
552
+ else if (Array.isArray(parsed)) {
553
+ articulos = parsed;
554
+ }
555
+ else {
556
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Formato Inválido');
557
+ }
558
+ }
559
+ catch (error) {
560
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'El formato de artículos no es válido. Ejemplos válidos: {"ID": 1271, "Cantidad": 10} o {"Codigo": "ABC123", "Cantidad": 10} o arrays de estos objetos');
561
+ }
562
+ }
563
+ else if (Array.isArray(articulosRaw)) {
564
+ articulos = articulosRaw;
565
+ }
566
+ else if (typeof articulosRaw === 'object' && articulosRaw !== null) {
567
+ articulos = [articulosRaw];
568
+ }
569
+ else {
570
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Tipo de dato inesperado: ${typeof articulosRaw}`);
571
+ }
572
+ const codigoCliente = this.getNodeParameter('codigoCliente', 0);
573
+ const fechaDocumento = this.getNodeParameter('documentDate', 0);
574
+ const formattedDocumentDate = String(fechaDocumento).split("T")[0];
575
+ const bonificacion = this.getNodeParameter('idBonificacion', 0);
576
+ const turnoEntrega = this.getNodeParameter('turnoEntrega', 0);
577
+ const fechaEntrega = this.getNodeParameter('deliveryDate', 0);
578
+ const vendedor = this.getNodeParameter('vendedorId', 0);
579
+ let clientId, queryParams;
580
+ if (!razonSocial.trim() && !codigoCliente.trim()) {
581
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'El código o la razón social del cliente es obligatorio.');
582
+ }
583
+ if (!Array.isArray(articulos) || articulos.length === 0) {
584
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Debes enviar al menos un artículo con su cantidad.');
585
+ }
586
+ for (const art of articulos) {
587
+ if (!art.ID && !art.Codigo) {
588
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Cada artículo debe tener al menos un ID o un Codigo');
589
+ }
590
+ }
591
+ if (codigoCliente)
592
+ queryParams = `codigo=${codigoCliente}`;
593
+ if (razonSocial)
594
+ queryParams = `razonSocial=${razonSocial}`;
549
595
  try {
550
- const arrArticles = await (0, functions_1.apiRequest)(`${centumUrl}/Articulos/Venta`, {
551
- method: "POST",
552
- headers,
553
- body: {
554
- idCliente: 1,
555
- FechaDocumento: formattedDate,
556
- Habilitado: true,
557
- ActivoWeb: true,
558
- },
596
+ const dataCliente = await (0, functions_1.apiRequest)(`${centumUrl}/Clientes?${queryParams}`, {
597
+ method: "GET",
598
+ headers
559
599
  });
560
- const bodyPedidoVenta = (0, functions_1.createOrderSaleJson)(arrArticles.Articulos.Items, customerSalesOrder, articlesSalesOrder, shippingSalesOrder, idCobro);
561
- const centumSuiteAccessTokenSalesOrder = (0, functions_1.createHash)(centumApiCredentials.publicAccessKey);
562
- const headersSalesOrder = {
563
- CentumSuiteConsumidorApiPublicaId: consumerApiPublicId,
564
- CentumSuiteAccessToken: centumSuiteAccessTokenSalesOrder,
565
- };
566
- const dataPedidosVenta = await (0, functions_1.apiRequest)(`${centumUrl}/PedidosVenta`, {
600
+ const cliente = dataCliente?.Items?.[0];
601
+ if (!cliente?.IdCliente) {
602
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'El cliente no fue encontrado');
603
+ }
604
+ clientId = cliente.IdCliente;
605
+ }
606
+ catch (error) {
607
+ console.log("Error creating sales order:", error);
608
+ const errorMessage = error?.response?.data?.Message || error.message || "Error al obtener el cliente.";
609
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), errorMessage);
610
+ }
611
+ const resultados = [];
612
+ for (const articuloInput of articulos) {
613
+ try {
614
+ const bodyArticulo = {
615
+ IdCliente: clientId,
616
+ FechaDocumento: formattedDocumentDate,
617
+ };
618
+ if (articuloInput.ID) {
619
+ bodyArticulo.Ids = [articuloInput.ID];
620
+ }
621
+ else if (articuloInput.Codigo) {
622
+ bodyArticulo.Codigo = articuloInput.Codigo;
623
+ }
624
+ const dataArticulo = await (0, functions_1.apiRequest)(`${centumUrl}/Articulos/Venta`, {
625
+ method: 'POST',
626
+ headers,
627
+ body: bodyArticulo,
628
+ });
629
+ const items = dataArticulo?.Articulos?.Items ?? [];
630
+ if (items.length > 0) {
631
+ const itemsConCantidad = items.map((item) => ({
632
+ ...item,
633
+ Cantidad: articuloInput.Cantidad,
634
+ }));
635
+ resultados.push(...itemsConCantidad);
636
+ }
637
+ const identificador = articuloInput.ID || articuloInput.Codigo;
638
+ console.log(`✔ Artículo ${identificador} procesado correctamente`);
639
+ }
640
+ catch (error) {
641
+ const identificador = articuloInput.ID || articuloInput.Codigo;
642
+ console.log(`❌ Error consultando artículo ${identificador}:`, error.message);
643
+ resultados.push({
644
+ id: articuloInput.ID,
645
+ codigo: articuloInput.Codigo,
646
+ error: error.message || 'Error desconocido',
647
+ });
648
+ }
649
+ }
650
+ const bodyPedidoVenta = {
651
+ Bonificacion: {
652
+ IdBonificacion: bonificacion
653
+ },
654
+ PedidoVentaArticulos: resultados,
655
+ Cliente: {
656
+ IdCliente: clientId
657
+ },
658
+ Vendedor: {
659
+ IdVendedor: vendedor
660
+ },
661
+ TurnoEntrega: {
662
+ IdTurnoEntrega: turnoEntrega
663
+ },
664
+ FechaEntrega: fechaEntrega
665
+ };
666
+ try {
667
+ const pedidoVenta = await (0, functions_1.apiRequest)(`${centumUrl}/PedidosVenta`, {
567
668
  method: "POST",
568
- headers: headersSalesOrder,
569
- body: bodyPedidoVenta,
669
+ headers,
670
+ body: bodyPedidoVenta
570
671
  });
571
- dataPedidosVenta.IdCobro = idCobro;
572
- return [this.helpers.returnJsonArray(dataPedidosVenta)];
672
+ return [this.helpers.returnJsonArray(pedidoVenta)];
573
673
  }
574
674
  catch (error) {
575
- console.log("Error creating sales order:", error);
576
- const errorMessage = error?.response?.data?.Message || error.message || "Error desconocido";
675
+ const errorMessage = error?.response?.data?.Message || error.message || "Error al crear el pedido de venta.";
577
676
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), errorMessage);
578
677
  }
579
678
  }
@@ -684,6 +783,142 @@ class Centum {
684
783
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error creando la compra.\n ${errorMessage}`);
685
784
  }
686
785
  }
786
+ case "generarOrdenCompra": {
787
+ try {
788
+ const response = await (0, functions_1.apiRequest)(`${centumUrl}/OrdenesCompra`, {
789
+ method: "POST",
790
+ headers,
791
+ body: {
792
+ "SucursalFisica": {
793
+ "IdSucursalFisica": 6084
794
+ },
795
+ "NumeroDocumento": {
796
+ "LetraDocumento": "O",
797
+ "PuntoVenta": 1,
798
+ "Numero": 6
799
+ },
800
+ "FechaDocumento": "2025-11-07T00:00:00",
801
+ "FechaEntrega": "2026-06-02T00:00:00",
802
+ "Proveedor": {
803
+ "IdProveedor": 6283,
804
+ "Codigo": "006283",
805
+ "RazonSocial": "Proveedores Río 240 EIRL",
806
+ "CUIT": "27260404100",
807
+ "Direccion": null,
808
+ "Localidad": "CONCEPCION ARENAL 7350",
809
+ "CodigoPostal": "7600",
810
+ "Provincia": {
811
+ "IdProvincia": 4876,
812
+ "Codigo": "BSAS",
813
+ "Nombre": "Buenos Aires"
814
+ },
815
+ "Pais": {
816
+ "IdPais": 4657,
817
+ "Codigo": "ARG",
818
+ "Nombre": "Argentina"
819
+ },
820
+ "Telefono": "541166778899",
821
+ "TelefonoAlternativo": "541166778899",
822
+ "Fax": null,
823
+ "Interno": null,
824
+ "Email": "matjul.mdq@hotmail.com",
825
+ "OperadorCompra": {
826
+ "IdOperadorCompra": 1,
827
+ "Codigo": "Operador de Compras Defecto",
828
+ "Nombre": "Operador de Compras Defecto",
829
+ "EsSupervisor": true
830
+ },
831
+ "CondicionIVA": {
832
+ "IdCondicionIVA": 1895,
833
+ "Codigo": "RI",
834
+ "Nombre": "Responsable Inscripto"
835
+ },
836
+ "CondicionIIBB": {
837
+ "IdCondicionIIBB": 6051,
838
+ "Codigo": "Responsable Inscript"
839
+ },
840
+ "NumeroIIBB": "30716828820",
841
+ "FormaPagoProveedor": {
842
+ "IdFormaPagoProveedor": 6091,
843
+ "Nombre": "Efectivo"
844
+ },
845
+ "DiasMorosidad": null,
846
+ "DiasIncobrables": null,
847
+ "CondicionPago": {
848
+ "IdCondicionPago": 4,
849
+ "Codigo": "CC1",
850
+ "Nombre": "7 Dias"
851
+ },
852
+ "CategoriaImpuestoGanancias": {
853
+ "IdCategoriaImpuestoGanancia": 6065,
854
+ "Nombre": "Exento"
855
+ },
856
+ "CategoriaRetencionIVA": null,
857
+ "CategoriaRetencionSUSS": null,
858
+ "ClaseProveedor": {
859
+ "IdClaseProveedor": 8609,
860
+ "Codigo": "02",
861
+ "Nombre": "DISTRIBUIDOR"
862
+ },
863
+ "Zona": {
864
+ "IdZona": 6095,
865
+ "Codigo": "Zona Defecto",
866
+ "Nombre": "Zona Defecto",
867
+ "Activo": true,
868
+ "EntregaLunes": false,
869
+ "EntregaMartes": false,
870
+ "EntregaMiercoles": false,
871
+ "EntregaJueves": false,
872
+ "EntregaViernes": false,
873
+ "EntregaSabado": false,
874
+ "EntregaDomingo": false,
875
+ "DemoraEnHorasFechaEntrega": 24,
876
+ "CostoEntrega": 10000
877
+ },
878
+ "DescuentoProveedor": null,
879
+ "DiasEntrega": 0,
880
+ "Activo": true
881
+ },
882
+ "PorcentajeDescuento": 0.000000,
883
+ "Observaciones": "",
884
+ "OrdenCompraArticulos": [
885
+ {
886
+ "IdArticulo": 2757,
887
+ "Codigo": "00002757",
888
+ "Nombre": "GALL MARYSOL MARINERAS 300gr",
889
+ "Cantidad": 1.000,
890
+ "SegundoControlStock": 0.000,
891
+ "Precio": 7.0,
892
+ "PorcentajeDescuento1": 0.000,
893
+ "PorcentajeDescuento2": 0.000,
894
+ "PorcentajeDescuento3": 0.000,
895
+ "DescuentoCalculado": 0.000000,
896
+ "CategoriaImpuestoIVA": {
897
+ "IdCategoriaImpuestoIVA": 4,
898
+ "Codigo": "5",
899
+ "Nombre": "IVA 21.00",
900
+ "Tasa": 21.000
901
+ },
902
+ "ImpuestoInterno": 0.000,
903
+ "Observaciones": ""
904
+ }
905
+ ],
906
+ "FechaVencimiento": "2029-11-07T00:00:00",
907
+ "OperadorCompra": {
908
+ "IdOperadorCompra": 1,
909
+ "Codigo": "1",
910
+ "Nombre": "Operador de Compras Defecto",
911
+ "EsSupervisor": false
912
+ },
913
+ }
914
+ });
915
+ return [this.helpers.returnJsonArray(response)];
916
+ }
917
+ catch (error) {
918
+ const errorMessage = error?.response?.data?.Message || error.message || "Error desconocido";
919
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error creando la compra.\n ${errorMessage}`);
920
+ }
921
+ }
687
922
  case "generarToken": {
688
923
  try {
689
924
  const tokenGenerado = (0, functions_1.createHash)(headers.publicAccessKey);
@@ -862,6 +1097,25 @@ class Centum {
862
1097
  });
863
1098
  }
864
1099
  }
1100
+ case 'obtenerBonificaciones': {
1101
+ try {
1102
+ const bonificaciones = await (0, functions_1.apiRequest)(`${centumUrl}/Bonificaciones`, {
1103
+ method: "GET",
1104
+ headers
1105
+ });
1106
+ return [this.helpers.returnJsonArray([bonificaciones])];
1107
+ }
1108
+ catch (error) {
1109
+ console.error("Error al obtener las bonificaciones:", error);
1110
+ const statusCode = error?.response?.status;
1111
+ const responseData = error?.response?.data;
1112
+ const errorMessage = responseData?.Message || responseData?.message || error?.message || "Error desconocido al crear el contribuyente.";
1113
+ const fullMessage = statusCode ? `Error ${statusCode}: ${errorMessage}` : errorMessage;
1114
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), fullMessage, {
1115
+ description: responseData?.Detail || "Ocurrió un error inesperado al llamar a la API de Centum.",
1116
+ });
1117
+ }
1118
+ }
865
1119
  case "obtenerCobros": {
866
1120
  const idCliente = this.getNodeParameter("clienteId", 0);
867
1121
  const idCobro = this.getNodeParameter("idCobro", 0);
@@ -1152,6 +1406,32 @@ class Centum {
1152
1406
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error obteniendo saldo para cliente ${clientId}: ${errorMessage}`);
1153
1407
  }
1154
1408
  }
1409
+ case 'obtenerTurnoEntrega': {
1410
+ try {
1411
+ const turnoEntrega = await (0, functions_1.apiRequest)(`${centumUrl}/TurnosEntrega`, {
1412
+ method: 'GET',
1413
+ headers
1414
+ });
1415
+ return [this.helpers.returnJsonArray(turnoEntrega)];
1416
+ }
1417
+ catch (error) {
1418
+ const errorMessage = error?.response?.data?.Message || error.message || "Error desconocido";
1419
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error obteniendo los turnos de entrega: ${errorMessage}`);
1420
+ }
1421
+ }
1422
+ case 'obtenerVendedores': {
1423
+ try {
1424
+ const turnoEntrega = await (0, functions_1.apiRequest)(`${centumUrl}/Vendedores`, {
1425
+ method: 'GET',
1426
+ headers
1427
+ });
1428
+ return [this.helpers.returnJsonArray(turnoEntrega)];
1429
+ }
1430
+ catch (error) {
1431
+ const errorMessage = error?.response?.data?.Message || error.message || "Error desconocido";
1432
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error obteniendo los vendedores: ${errorMessage}`);
1433
+ }
1434
+ }
1155
1435
  case "operadoresMoviles": {
1156
1436
  const username = this.getNodeParameter("username", 0, "");
1157
1437
  const password = this.getNodeParameter("password", 0, "");
@@ -1258,7 +1538,7 @@ class Centum {
1258
1538
  }
1259
1539
  }
1260
1540
  case 'proveedorCrear': {
1261
- const codigo = this.getNodeParameter('codigo', 0, '');
1541
+ const codigo = this.getNodeParameter('codigoArticulo', 0, '');
1262
1542
  const razonSocial = this.getNodeParameter('razonSocial', 0, '');
1263
1543
  const cuit = this.getNodeParameter('cuit', 0);
1264
1544
  const provincia = this.getNodeParameter('idProvincia', 0);