Files
comparador-planillas-panama/n8n-workflow/Comparador planilla.json
T
2026-06-06 10:24:44 -04:00

1222 lines
43 KiB
JSON

{
"name": "Comparador planilla",
"nodes": [
{
"parameters": {
"numberInputs": 3
},
"type": "n8n-nodes-base.merge",
"typeVersion": 3.2,
"position": [
1312,
256
],
"id": "307f53e3-ffbd-456f-8dec-ca8aee9e0bfc",
"name": "Merge - Esperar los 3 insumos2"
},
{
"parameters": {
"jsCode": "const sheetItems = $('Get row(s) in sheet').all();\nconst pdf1938Items = $('Primera planilla').all();\nconst pdf1967Items = $('Segunda planilla').all();\n\nfunction clean(value) {\n return String(value ?? '').trim();\n}\n\nfunction normalizeText(value) {\n return clean(value)\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase();\n}\n\nfunction compactId(value) {\n return clean(value)\n .toUpperCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^A-Z0-9]/g, '');\n}\n\nfunction compactName(value) {\n return clean(value)\n .toUpperCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^A-Z]/g, '');\n}\n\nfunction idVariants(value) {\n const compact = compactId(value);\n const noLeadingZeros = compact.replace(/^0+/, '');\n\n return [...new Set([compact, noLeadingZeros])]\n .filter(v => v && v.length >= 4);\n}\n\nfunction collectAllText(value) {\n if (value === null || value === undefined) return '';\n\n if (typeof value === 'string' || typeof value === 'number') {\n return String(value);\n }\n\n if (Array.isArray(value)) {\n return value.map(collectAllText).join('\\n');\n }\n\n if (typeof value === 'object') {\n return Object.values(value).map(collectAllText).join('\\n');\n }\n\n return '';\n}\n\nfunction pdfItemsToCompactText(items) {\n const fullText = items\n .map(item => collectAllText(item.json))\n .join('\\n');\n\n return fullText\n .toUpperCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^A-Z0-9]/g, '');\n}\n\nfunction pdfHasId(pdfCompactText, cedula) {\n return idVariants(cedula).some(id => pdfCompactText.includes(id));\n}\n\nfunction pdfHasName(pdfCompactText, nombre, apellido) {\n const n = compactName(nombre);\n const a = compactName(apellido);\n\n if (!n || !a) return false;\n if (n.length < 3 || a.length < 3) return false;\n\n const apellidoNombre = `${a}${n}`;\n const nombreApellido = `${n}${a}`;\n\n return (\n pdfCompactText.includes(apellidoNombre) ||\n pdfCompactText.includes(nombreApellido)\n );\n}\n\nfunction pdfHasEmployee(pdfCompactText, emp) {\n return (\n pdfHasId(pdfCompactText, emp.cedula) ||\n pdfHasName(pdfCompactText, emp.nombre, emp.apellido)\n );\n}\n\nfunction rowToArray(row) {\n const values = [];\n\n for (const [key, value] of Object.entries(row)) {\n if (key === 'row_number') continue;\n values.push(clean(value));\n }\n\n return values;\n}\n\nfunction looksLikeCedula(value) {\n const v = clean(value).toUpperCase();\n\n return (\n /^\\d{1,2}-\\d{1,4}-\\d{1,5}$/.test(v) ||\n /^E-\\d{1,2}-\\d{1,6}$/.test(v) ||\n /^[A-Z]{1,4}\\s?\\d{4,12}$/.test(v) ||\n /^\\d{5,12}$/.test(v)\n );\n}\n\nfunction extractEmpleadosFromBlockSheet(items) {\n const rows = items.map(item => rowToArray(item.json));\n const empleados = [];\n\n for (let i = 0; i < rows.length - 1; i++) {\n const row = rows[i].map(normalizeText);\n\n const seguroSocialIndex = row.findIndex(v => v === 'seguro social');\n\n const cedulaIndex = row.findIndex(v =>\n v === 'cedula' ||\n v === 'cedula/pasaporte' ||\n v === 'cedula / pasaporte' ||\n v === 'pasaporte'\n );\n\n const apellidoIndex = row.findIndex(v =>\n v === 'apellido' ||\n v === 'apellidos'\n );\n\n const nombreIndex = row.findIndex(v =>\n v === 'nombre' ||\n v === 'nombres'\n );\n\n if (cedulaIndex === -1) continue;\n\n const nextRow = rows[i + 1];\n\n const cedula = clean(nextRow[cedulaIndex]);\n const nombre = nombreIndex !== -1 ? clean(nextRow[nombreIndex]) : '';\n const apellido = apellidoIndex !== -1 ? clean(nextRow[apellidoIndex]) : '';\n const seguroSocial = seguroSocialIndex !== -1 ? clean(nextRow[seguroSocialIndex]) : '';\n\n if (!cedula || !looksLikeCedula(cedula)) continue;\n\n empleados.push({\n cedula,\n nombre,\n apellido,\n seguroSocial,\n filaGoogleSheet: items[i + 1]?.json?.row_number ?? i + 2,\n });\n }\n\n return empleados;\n}\n\nconst empleados = extractEmpleadosFromBlockSheet(sheetItems);\n\nif (empleados.length === 0) {\n return [{\n json: {\n Cedula: '',\n Nombre: '',\n Apellido: '',\n En_Planilla_1938: '',\n En_Planilla_1967: '',\n Estado: 'ERROR - No se encontraron cédulas en el Google Sheet. Revisa que el nodo Google Sheets esté leyendo la hoja correcta.',\n }\n }];\n}\n\nconst pdf1938CompactText = pdfItemsToCompactText(pdf1938Items);\nconst pdf1967CompactText = pdfItemsToCompactText(pdf1967Items);\n\nif (!pdf1938CompactText || !pdf1967CompactText) {\n return [{\n json: {\n Cedula: '',\n Nombre: '',\n Apellido: '',\n En_Planilla_1938: '',\n En_Planilla_1967: '',\n Estado: 'ERROR - Uno de los PDF no devolvió texto. Revisa los nodos Extract From File.',\n }\n }];\n}\n\nconst reporte = empleados.map(emp => {\n const en1938 = pdfHasEmployee(pdf1938CompactText, emp);\n const en1967 = pdfHasEmployee(pdf1967CompactText, emp);\n\n let estado = 'OK';\n\n if (!en1938 && !en1967) {\n estado = 'Falta en ambas planillas';\n } else if (!en1938) {\n estado = 'Falta en Planilla 1938';\n } else if (!en1967) {\n estado = 'Falta en Planilla 1967';\n }\n\n return {\n json: {\n Cedula: emp.cedula,\n Nombre: emp.nombre,\n Apellido: emp.apellido,\n En_Planilla_1938: en1938 ? 'Sí' : 'No',\n En_Planilla_1967: en1967 ? 'Sí' : 'No',\n Estado: estado,\n }\n };\n});\n\nconst faltantes = reporte.filter(item => item.json.Estado !== 'OK');\n\nif (faltantes.length === 0) {\n return [{\n json: {\n Cedula: '',\n Nombre: '',\n Apellido: '',\n En_Planilla_1938: 'Sí',\n En_Planilla_1967: 'Sí',\n Estado: 'OK - Todas las cédulas aparecen en ambas planillas',\n }\n }];\n}\n\nreturn faltantes;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1552,
272
],
"id": "de268977-eeb8-440d-a229-8aec8726cf32",
"name": "Code - Comparar Cedulas2"
},
{
"parameters": {
"jsCode": "return $('Code - Comparar Cedulas2').all();"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1808,
272
],
"id": "a7c6984e-26be-4631-bd45-402687bed312",
"name": "Code - Recuperar Reporte2"
},
{
"parameters": {
"content": "## INICIO Y FUENTES DE DATOS\n\n**Webhook**: Trae las URLs insertada en el frontend.\n\n**Switch**: Si hay dos planillas, activará la ruta 0. Si hay una sola planilla, activará la ruta 1. ",
"height": 304,
"width": 432,
"color": 4
},
"type": "n8n-nodes-base.stickyNote",
"position": [
-144,
144
],
"typeVersion": 1,
"id": "59d2207f-6a2c-40c3-8a2e-8d896afbbaae",
"name": "Sticky Note"
},
{
"parameters": {
"content": "## UNIFICAR INSUMOS\n\nEste nodo espera las 3 fuentes necesarias:\n\nInput 1: Google Sheet base.\nInput 2: Texto extraído del PDF primera planilla.\nInput 3: Texto extraído del PDF segunda planilla.\n\nModo: Append.",
"height": 1104,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"position": [
1232,
-16
],
"typeVersion": 1,
"id": "f6f2a5ea-52ab-4501-a8b6-aa6c63813ed1",
"name": "Sticky Note8"
},
{
"parameters": {
"content": "## VALIDACIÓN PRINCIPAL\n\nEste nodo lee las cédulas desde el Google Sheet, normaliza los formatos y valida si cada cédula aparece en los dos PDF de nómina.\n\nDevuelve solo los empleados que faltan en una o ambas planillas.",
"height": 1104,
"width": 208
},
"type": "n8n-nodes-base.stickyNote",
"position": [
1504,
-16
],
"typeVersion": 1,
"id": "77fc241e-d934-454e-9f9b-86d0525202ae",
"name": "Sticky Note9"
},
{
"parameters": {
"content": "## REPORTE FINAL\n\nCode - Recuperar Reporte trae nuevamente los resultados.\n",
"height": 960,
"color": 5
},
"type": "n8n-nodes-base.stickyNote",
"position": [
1744,
128
],
"typeVersion": 1,
"id": "69602e51-72ff-4125-bc8e-5530352a6d61",
"name": "Sticky Note10"
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"leftValue": "={{ $json.body.planilla1 && $json.body.planilla2 }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"id": "15e876da-9674-4627-9dfe-c681aeaea7de"
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "2d722b7a-d31b-4e20-b219-1889f4246781",
"leftValue": "={{ !$json.body.planilla1 || !$json.body.planilla2 ? 'vacio' : 'con_datos' }}",
"rightValue": "vacio",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
}
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.4,
"position": [
144,
288
],
"id": "b2a9bc1c-92e0-43e7-ac97-a29b5c2fcacf",
"name": "Switch1"
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "166MSfOI_d44RajTOaQtky_2WNIAhS9vdB5T73cZbyWw",
"mode": "list",
"cachedResultName": "TSS",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/166MSfOI_d44RajTOaQtky_2WNIAhS9vdB5T73cZbyWw/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": 1599580508,
"mode": "list",
"cachedResultName": "TSS",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/166MSfOI_d44RajTOaQtky_2WNIAhS9vdB5T73cZbyWw/edit#gid=1599580508"
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.7,
"position": [
1024,
96
],
"id": "4d80bc10-2133-48ba-bed9-32501ebbe4a0",
"name": "Get row(s) in sheet",
"retryOnFail": true,
"credentials": {
"googleSheetsOAuth2Api": {
"id": "8Pp0ek3NPsEkyXfY",
"name": "Eidan - Google Sheets account"
}
}
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "166MSfOI_d44RajTOaQtky_2WNIAhS9vdB5T73cZbyWw",
"mode": "list",
"cachedResultName": "TSS",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/166MSfOI_d44RajTOaQtky_2WNIAhS9vdB5T73cZbyWw/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": 1599580508,
"mode": "list",
"cachedResultName": "TSS",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/166MSfOI_d44RajTOaQtky_2WNIAhS9vdB5T73cZbyWw/edit#gid=1599580508"
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.7,
"position": [
1024,
688
],
"id": "ab7c6cef-1be2-4804-92a1-849d6a2beb0b",
"name": "Get row(s) in sheet3",
"retryOnFail": true,
"credentials": {
"googleSheetsOAuth2Api": {
"id": "8Pp0ek3NPsEkyXfY",
"name": "Eidan - Google Sheets account"
}
}
},
{
"parameters": {
"jsCode": "const sheetItems = $('Get row(s) in sheet3').all();\nconst quincena = $('Planilla').all();\n//const pdf1967Items = $('Segunda planilla').all();\n\nfunction clean(value) {\n return String(value ?? '').trim();\n}\n\nfunction normalizeText(value) {\n return clean(value)\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase();\n}\n\nfunction compactId(value) {\n return clean(value)\n .toUpperCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^A-Z0-9]/g, '');\n}\n\nfunction compactName(value) {\n return clean(value)\n .toUpperCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^A-Z]/g, '');\n}\n\nfunction idVariants(value) {\n const compact = compactId(value);\n const noLeadingZeros = compact.replace(/^0+/, '');\n\n return [...new Set([compact, noLeadingZeros])]\n .filter(v => v && v.length >= 4);\n}\n\nfunction collectAllText(value) {\n if (value === null || value === undefined) return '';\n\n if (typeof value === 'string' || typeof value === 'number') {\n return String(value);\n }\n\n if (Array.isArray(value)) {\n return value.map(collectAllText).join('\\n');\n }\n\n if (typeof value === 'object') {\n return Object.values(value).map(collectAllText).join('\\n');\n }\n\n return '';\n}\n\nfunction pdfItemsToCompactText(items) {\n const fullText = items\n .map(item => collectAllText(item.json))\n .join('\\n');\n\n return fullText\n .toUpperCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^A-Z0-9]/g, '');\n}\n\nfunction pdfHasId(pdfCompactText, cedula) {\n return idVariants(cedula).some(id => pdfCompactText.includes(id));\n}\n\nfunction pdfHasName(pdfCompactText, nombre, apellido) {\n const n = compactName(nombre);\n const a = compactName(apellido);\n\n if (!n || !a) return false;\n if (n.length < 3 || a.length < 3) return false;\n\n const apellidoNombre = `${a}${n}`;\n const nombreApellido = `${n}${a}`;\n\n return (\n pdfCompactText.includes(apellidoNombre) ||\n pdfCompactText.includes(nombreApellido)\n );\n}\n\nfunction pdfHasEmployee(pdfCompactText, emp) {\n return (\n pdfHasId(pdfCompactText, emp.cedula) ||\n pdfHasName(pdfCompactText, emp.nombre, emp.apellido)\n );\n}\n\nfunction rowToArray(row) {\n const values = [];\n\n for (const [key, value] of Object.entries(row)) {\n if (key === 'row_number') continue;\n values.push(clean(value));\n }\n\n return values;\n}\n\nfunction looksLikeCedula(value) {\n const v = clean(value).toUpperCase();\n\n return (\n /^\\d{1,2}-\\d{1,4}-\\d{1,5}$/.test(v) ||\n /^E-\\d{1,2}-\\d{1,6}$/.test(v) ||\n /^[A-Z]{1,4}\\s?\\d{4,12}$/.test(v) ||\n /^\\d{5,12}$/.test(v)\n );\n}\n\nfunction extractEmpleadosFromBlockSheet(items) {\n const rows = items.map(item => rowToArray(item.json));\n const empleados = [];\n\n for (let i = 0; i < rows.length - 1; i++) {\n const row = rows[i].map(normalizeText);\n\n const seguroSocialIndex = row.findIndex(v => v === 'seguro social');\n\n const cedulaIndex = row.findIndex(v =>\n v === 'cedula' ||\n v === 'cedula/pasaporte' ||\n v === 'cedula / pasaporte' ||\n v === 'pasaporte'\n );\n\n const apellidoIndex = row.findIndex(v =>\n v === 'apellido' ||\n v === 'apellidos'\n );\n\n const nombreIndex = row.findIndex(v =>\n v === 'nombre' ||\n v === 'nombres'\n );\n\n if (cedulaIndex === -1) continue;\n\n const nextRow = rows[i + 1];\n\n const cedula = clean(nextRow[cedulaIndex]);\n const nombre = nombreIndex !== -1 ? clean(nextRow[nombreIndex]) : '';\n const apellido = apellidoIndex !== -1 ? clean(nextRow[apellidoIndex]) : '';\n const seguroSocial = seguroSocialIndex !== -1 ? clean(nextRow[seguroSocialIndex]) : '';\n\n if (!cedula || !looksLikeCedula(cedula)) continue;\n\n empleados.push({\n cedula,\n nombre,\n apellido,\n seguroSocial,\n filaGoogleSheet: items[i + 1]?.json?.row_number ?? i + 2,\n });\n }\n\n return empleados;\n}\n\nconst empleados = extractEmpleadosFromBlockSheet(sheetItems);\n\nif (empleados.length === 0) {\n return [{\n json: {\n Cedula: '',\n Nombre: '',\n Apellido: '',\n En_Quincena: '',\n //En_Planilla_1967: '',\n Estado: 'ERROR - No se encontraron cédulas en el Google Sheet. Revisa que el nodo Google Sheets esté leyendo la hoja correcta.',\n }\n }];\n}\n\nconst pdf1938CompactText = pdfItemsToCompactText(quincena);\n//const pdf1967CompactText = pdfItemsToCompactText(pdf1967Items);\n\n//if (!pdf1938CompactText || !pdf1967CompactText) {\nif (!pdf1938CompactText) {\n return [{\n json: {\n Cedula: '',\n Nombre: '',\n Apellido: '',\n En_Quincena: '',\n //En_Planilla_1967: '',\n Estado: 'ERROR - Uno de los PDF no devolvió texto. Revisa los nodos Extract From File.',\n }\n }];\n}\n\nconst reporte = empleados.map(emp => {\n const en1938 = pdfHasEmployee(pdf1938CompactText, emp);\n //const en1967 = pdfHasEmployee(pdf1967CompactText, emp);\n\n let estado = 'OK';\n/*\n if (!en1938 && !en1967) {\n estado = 'Falta en ambas planillas';\n } else if (!en1938) {\n estado = 'Falta en Planilla 1938';\n } else if (!en1967) {\n estado = 'Falta en Planilla 1967';\n }\n*/\n if (!en1938) {\n estado = 'No está en la planilla'\n }\n\n return {\n json: {\n Cedula: emp.cedula,\n Nombre: emp.nombre,\n Apellido: emp.apellido,\n En_Quincena: en1938 ? 'Sí' : 'No',\n //En_Planilla_1967: en1967 ? 'Sí' : 'No',\n Estado: estado,\n }\n };\n});\n\nconst faltantes = reporte.filter(item => item.json.Estado !== 'OK');\n\nif (faltantes.length === 0) {\n return [{\n json: {\n Cedula: '',\n Nombre: '',\n Apellido: '',\n En_Quincena: 'Sí',\n //En_Planilla_1967: 'Sí',\n Estado: 'OK - Todas las cédulas aparecen en ambas planillas',\n }\n }];\n}\n\nreturn faltantes;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1552,
800
],
"id": "6c961178-84a0-4c86-bf3f-7e7f119504d3",
"name": "Code - Comparar Cedulas3"
},
{
"parameters": {
"jsCode": "return $('Code - Comparar Cedulas3').all();"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1808,
800
],
"id": "349f6a47-a671-4c3e-86aa-135c4ba76474",
"name": "Code - Recuperar Reporte3"
},
{
"parameters": {
"jsCode": "return [\n {\n json: {\n data: $input.all().map(item => item.json)\n }\n }\n];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2128,
544
],
"id": "31ef2d32-fe38-4949-b3fc-54effdf04800",
"name": "Code in JavaScript7"
},
{
"parameters": {
"httpMethod": "POST",
"path": "nomina",
"responseMode": "responseNode",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-96,
288
],
"id": "0149f412-0f6e-441d-b165-d55d671e707c",
"name": "Webhook",
"webhookId": "b67eb939-9ebc-4769-97d4-e7e7365d3863"
},
{
"parameters": {
"content": "## Procesar datos ",
"height": 1120,
"width": 768
},
"type": "n8n-nodes-base.stickyNote",
"position": [
400,
-32
],
"typeVersion": 1,
"id": "63f28c66-d400-48b5-a67c-1552ee359ca7",
"name": "Sticky Note2"
},
{
"parameters": {
"url": "=https://docs.google.com/spreadsheets/d/1GOD4drTGgXPZuMMnjzzE-QraxRc0ZrXPJBC7YD_vyaQ/export?format=csv",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
656,
96
],
"id": "751589d7-2e31-4fe0-abbb-a45b79f55b1a",
"name": "Descargar a CSV",
"retryOnFail": true,
"credentials": {
"googleDriveOAuth2Api": {
"id": "gL2ZTwJb6xojauac",
"name": "Eidan - Google Drive account"
}
}
},
{
"parameters": {
"name": "TSS",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"value": "1c08rDipBOATxBEf6T1jmCaki3TW0cwUh",
"mode": "list",
"cachedResultName": "TSS",
"cachedResultUrl": "https://drive.google.com/drive/folders/1c08rDipBOATxBEf6T1jmCaki3TW0cwUh"
},
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
832,
96
],
"id": "5a6da339-1b2d-42f6-89d2-0f22f266f2e6",
"name": "Guardar archivo CSV",
"retryOnFail": true,
"credentials": {
"googleDriveOAuth2Api": {
"id": "gL2ZTwJb6xojauac",
"name": "Eidan - Google Drive account"
}
}
},
{
"parameters": {
"jsCode": "for (const item of $input.all()) {\n const url = $input.first().json.body.tssUrl;\n \n // Extraer el ID del Spreadsheet\n const spreadsheetRegex = /\\/d\\/([a-zA-Z0-9-_]+)/;\n const spreadsheetMatch = url.match(spreadsheetRegex);\n item.json.spreadsheetId = spreadsheetMatch ? spreadsheetMatch[1] : \"No encontrado\";\n\n // Extraer el ID de la Hoja (gid)\n const sheetRegex = /[#&]gid=([0-9]+)/;\n const sheetMatch = url.match(sheetRegex);\n \n // Como en tu URL no hay \"gid\", se asigna 0 por defecto\n item.json.sheetId = sheetMatch ? sheetMatch[1] : \"0\";\n}\n\nreturn $input.all();"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
480,
96
],
"id": "b898cd23-bb59-452e-bce2-aeb2dde795aa",
"name": "ID del spreadsheet"
},
{
"parameters": {
"options": {}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.5,
"position": [
2352,
544
],
"id": "afc5931f-6a09-4b2f-8600-d59f2c0d532f",
"name": "Respond to Webhook"
},
{
"parameters": {
"jsCode": "for (const item of $input.all()) {\n const url = $input.first().json.body.planilla1;\n \n // Extraer el ID del archivo de Google Drive\n // Busca el patrón que sigue a \"/file/d/\" y termina antes de \"/view\"\n const fileIdRegex = /\\/file\\/d\\/([a-zA-Z0-9-_]+)/;\n const fileIdMatch = url.match(fileIdRegex);\n \n item.json.fileId = fileIdMatch ? fileIdMatch[1] : \"No encontrado\";\n\n // En archivos de Drive (PDF, etc.) no existe el \"sheetId\" o \"gid\", \n // por lo que eliminamos esa parte o la dejamos como nula.\n item.json.isDriveFile = true;\n}\n\nreturn $input.all();"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
480,
272
],
"id": "2cb03f47-fd7c-4430-ac1d-9682b98159d9",
"name": "ID del PDF de la primera planilla"
},
{
"parameters": {
"jsCode": "for (const item of $input.all()) {\n const url = $input.first().json.body.planilla2;\n \n // Extraer el ID del archivo de Google Drive\n // Busca el patrón que sigue a \"/file/d/\" y termina antes de \"/view\"\n const fileIdRegex = /\\/file\\/d\\/([a-zA-Z0-9-_]+)/;\n const fileIdMatch = url.match(fileIdRegex);\n \n item.json.fileId = fileIdMatch ? fileIdMatch[1] : \"No encontrado\";\n\n // En archivos de Drive (PDF, etc.) no existe el \"sheetId\" o \"gid\", \n // por lo que eliminamos esa parte o la dejamos como nula.\n item.json.isDriveFile = true;\n}\n\nreturn $input.all();"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
480,
448
],
"id": "0c60a069-b662-4920-96c5-c9b2d2bd46e2",
"name": "ID del PDF de la segunda planilla"
},
{
"parameters": {
"url": "=https://www.googleapis.com/drive/v3/files/{{ $json.fileId }}?alt=media",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
656,
272
],
"id": "08b3517a-7b60-4eb6-b026-0e99263ffffa",
"name": "Descargar primera planilla",
"retryOnFail": true,
"credentials": {
"googleDriveOAuth2Api": {
"id": "gL2ZTwJb6xojauac",
"name": "Eidan - Google Drive account"
}
}
},
{
"parameters": {
"url": "=https://www.googleapis.com/drive/v3/files/{{ $json.fileId }}?alt=media",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
656,
448
],
"id": "3ed444be-b1c0-4793-88ac-6af6243f160b",
"name": "Descargar segunda planilla",
"retryOnFail": true,
"credentials": {
"googleDriveOAuth2Api": {
"id": "gL2ZTwJb6xojauac",
"name": "Eidan - Google Drive account"
}
}
},
{
"parameters": {
"jsCode": "for (const item of $input.all()) {\n const url = $input.first().json.body.tssUrl;\n \n // Extraer el ID del Spreadsheet\n const spreadsheetRegex = /\\/d\\/([a-zA-Z0-9-_]+)/;\n const spreadsheetMatch = url.match(spreadsheetRegex);\n item.json.spreadsheetId = spreadsheetMatch ? spreadsheetMatch[1] : \"No encontrado\";\n\n // Extraer el ID de la Hoja (gid)\n const sheetRegex = /[#&]gid=([0-9]+)/;\n const sheetMatch = url.match(sheetRegex);\n \n // Como en tu URL no hay \"gid\", se asigna 0 por defecto\n item.json.sheetId = sheetMatch ? sheetMatch[1] : \"0\";\n}\n\nreturn $input.all();"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
480,
688
],
"id": "de247dce-c2e0-4b49-8ea8-0d3d188ff6a4",
"name": "ID del spreadsheet1"
},
{
"parameters": {
"jsCode": "for (const item of $input.all()) {\n const url = $input.first().json.body.planilla1 || $input.first().json.body.planilla2;\n \n // Extraer el ID del archivo de Google Drive\n // Busca el patrón que sigue a \"/file/d/\" y termina antes de \"/view\"\n const fileIdRegex = /\\/file\\/d\\/([a-zA-Z0-9-_]+)/;\n const fileIdMatch = url.match(fileIdRegex);\n \n item.json.fileId = fileIdMatch ? fileIdMatch[1] : \"No encontrado\";\n\n // En archivos de Drive (PDF, etc.) no existe el \"sheetId\" o \"gid\", \n // por lo que eliminamos esa parte o la dejamos como nula.\n item.json.isDriveFile = true;\n}\n\nreturn $input.all();"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
480,
896
],
"id": "75183ac3-e569-49a0-a3b3-a31275731f19",
"name": "ID del PDF de la planilla"
},
{
"parameters": {
"operation": "pdf",
"options": {}
},
"type": "n8n-nodes-base.extractFromFile",
"typeVersion": 1.1,
"position": [
832,
272
],
"id": "89c9942c-003d-4c90-aca8-0e519ef09811",
"name": "Primera planilla",
"retryOnFail": true
},
{
"parameters": {
"operation": "pdf",
"options": {}
},
"type": "n8n-nodes-base.extractFromFile",
"typeVersion": 1.1,
"position": [
832,
448
],
"id": "c201147b-bb33-436e-a58a-f3a12d9bf3b1",
"name": "Segunda planilla",
"retryOnFail": true
},
{
"parameters": {
"url": "=https://docs.google.com/spreadsheets/d/1GOD4drTGgXPZuMMnjzzE-QraxRc0ZrXPJBC7YD_vyaQ/export?format=csv",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
656,
688
],
"id": "c3542086-79d8-4582-8452-2aa38f865fab",
"name": "Descargar a CSV1",
"retryOnFail": true,
"credentials": {
"googleDriveOAuth2Api": {
"id": "gL2ZTwJb6xojauac",
"name": "Eidan - Google Drive account"
}
}
},
{
"parameters": {
"url": "=https://www.googleapis.com/drive/v3/files/{{ $json.fileId }}?alt=media",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
656,
896
],
"id": "300d158c-5cd1-4dd0-bca6-23cbe800ea38",
"name": "Descargar planilla",
"retryOnFail": true,
"credentials": {
"googleDriveOAuth2Api": {
"id": "gL2ZTwJb6xojauac",
"name": "Eidan - Google Drive account"
}
}
},
{
"parameters": {
"operation": "pdf",
"options": {}
},
"type": "n8n-nodes-base.extractFromFile",
"typeVersion": 1.1,
"position": [
832,
896
],
"id": "396ac651-5784-422a-b829-8cbcbbc17090",
"name": "Planilla",
"retryOnFail": true
},
{
"parameters": {},
"type": "n8n-nodes-base.merge",
"typeVersion": 3.2,
"position": [
1312,
800
],
"id": "a250c4a5-b883-41b3-a47e-b09128ac0e8e",
"name": "Merge - Esperar los 2 insumos"
},
{
"parameters": {
"content": " \n**Extraer el ID de la URL** ",
"height": 1008,
"width": 160,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
448,
32
],
"typeVersion": 1,
"id": "afeb7ce3-9d95-4271-9626-b2f774afe4dc",
"name": "Sticky Note1"
},
{
"parameters": {
"content": " \n**Descargar archivo** ",
"height": 1008,
"width": 150,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
624,
32
],
"typeVersion": 1,
"id": "a62279b8-8c7b-4c72-b18c-2d185a06a00f",
"name": "Sticky Note3"
},
{
"parameters": {
"content": " \n**Guardar archivo** ",
"height": 192,
"width": 150,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
800,
32
],
"typeVersion": 1,
"id": "184b6ae9-4e89-4c7a-9807-d0deabb59003",
"name": "Sticky Note4"
},
{
"parameters": {
"content": " \n**Guardar archivo** ",
"height": 192,
"width": 150,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
800,
640
],
"typeVersion": 1,
"id": "80084a9c-0d74-4b4a-9cbc-db0db238122c",
"name": "Sticky Note5"
},
{
"parameters": {
"content": " \n**Descargar binario** ",
"height": 352,
"width": 150,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
800,
240
],
"typeVersion": 1,
"id": "31b4ced0-ca9e-4033-b3b6-e43355a8e617",
"name": "Sticky Note6"
},
{
"parameters": {
"content": " \n**Descargar binario** ",
"height": 176,
"width": 150,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
800,
864
],
"typeVersion": 1,
"id": "7a2f4a1d-eec4-40e4-b6fe-996d37922db3",
"name": "Sticky Note7"
},
{
"parameters": {
"content": " \n**Extraer datos** ",
"height": 192,
"width": 150,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
992,
640
],
"typeVersion": 1,
"id": "c13efed6-6ead-46fe-97be-38b10ce936b0",
"name": "Sticky Note11"
},
{
"parameters": {
"content": " \n**Extraer datos** ",
"height": 192,
"width": 150,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
992,
32
],
"typeVersion": 1,
"id": "75edfe2e-a73c-486b-86d5-cb9d841ed5eb",
"name": "Sticky Note12"
},
{
"parameters": {
"operation": "deleteFile",
"fileId": {
"__rl": true,
"value": "={{ $('Guardar archivo CSV').first().json.id }}",
"mode": "id"
},
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
2112,
272
],
"id": "4ccdc650-d54a-439e-b052-1b68888ec678",
"name": "Eliminar archivo TSS",
"retryOnFail": true,
"credentials": {
"googleDriveOAuth2Api": {
"id": "gL2ZTwJb6xojauac",
"name": "Eidan - Google Drive account"
}
}
},
{
"parameters": {
"name": "TSS",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"value": "1c08rDipBOATxBEf6T1jmCaki3TW0cwUh",
"mode": "list",
"cachedResultName": "TSS",
"cachedResultUrl": "https://drive.google.com/drive/folders/1c08rDipBOATxBEf6T1jmCaki3TW0cwUh"
},
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
832,
688
],
"id": "1f77d3c2-2eb4-4c9b-9a56-55e0abbc13d3",
"name": "Guardar archivo CSV1",
"retryOnFail": true,
"credentials": {
"googleDriveOAuth2Api": {
"id": "gL2ZTwJb6xojauac",
"name": "Eidan - Google Drive account"
}
}
},
{
"parameters": {
"operation": "deleteFile",
"fileId": {
"__rl": true,
"value": "={{ $('Guardar archivo CSV1').first().json.id }}",
"mode": "id"
},
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
2128,
800
],
"id": "79cc470a-5acb-4c75-b44b-d9fa43865a80",
"name": "Eliminar archivo TSS1",
"retryOnFail": true,
"credentials": {
"googleDriveOAuth2Api": {
"id": "gL2ZTwJb6xojauac",
"name": "Eidan - Google Drive account"
}
}
},
{
"parameters": {
"content": " \n**Eliminar archivo TSS** ",
"height": 192,
"width": 166,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
2080,
224
],
"typeVersion": 1,
"id": "2067949e-101e-41e0-9762-cc8f7c3acec7",
"name": "Sticky Note13"
},
{
"parameters": {
"content": " \n**Eliminar archivo TSS** ",
"height": 192,
"width": 166,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
2096,
752
],
"typeVersion": 1,
"id": "6f7709ad-e017-4964-8cfa-a58c8a47d2b0",
"name": "Sticky Note14"
},
{
"parameters": {
"content": " \n**Listar todos los items** ",
"height": 192,
"width": 182,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
2080,
496
],
"typeVersion": 1,
"id": "2e52ed34-6182-4c63-b19c-689a95240ebe",
"name": "Sticky Note15"
}
],
"pinData": {},
"connections": {
"Merge - Esperar los 3 insumos2": {
"main": [
[
{
"node": "Code - Comparar Cedulas2",
"type": "main",
"index": 0
}
]
]
},
"Code - Comparar Cedulas2": {
"main": [
[
{
"node": "Code - Recuperar Reporte2",
"type": "main",
"index": 0
}
]
]
},
"Code - Recuperar Reporte2": {
"main": [
[
{
"node": "Code in JavaScript7",
"type": "main",
"index": 0
},
{
"node": "Eliminar archivo TSS",
"type": "main",
"index": 0
}
]
]
},
"Switch1": {
"main": [
[
{
"node": "ID del spreadsheet",
"type": "main",
"index": 0
},
{
"node": "ID del PDF de la primera planilla",
"type": "main",
"index": 0
},
{
"node": "ID del PDF de la segunda planilla",
"type": "main",
"index": 0
}
],
[
{
"node": "ID del spreadsheet1",
"type": "main",
"index": 0
},
{
"node": "ID del PDF de la planilla",
"type": "main",
"index": 0
}
]
]
},
"Get row(s) in sheet": {
"main": [
[
{
"node": "Merge - Esperar los 3 insumos2",
"type": "main",
"index": 0
}
]
]
},
"Get row(s) in sheet3": {
"main": [
[
{
"node": "Merge - Esperar los 2 insumos",
"type": "main",
"index": 0
}
]
]
},
"Code - Comparar Cedulas3": {
"main": [
[
{
"node": "Code - Recuperar Reporte3",
"type": "main",
"index": 0
}
]
]
},
"Code - Recuperar Reporte3": {
"main": [
[
{
"node": "Code in JavaScript7",
"type": "main",
"index": 0
},
{
"node": "Eliminar archivo TSS1",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript7": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Webhook": {
"main": [
[
{
"node": "Switch1",
"type": "main",
"index": 0
}
]
]
},
"Descargar a CSV": {
"main": [
[
{
"node": "Guardar archivo CSV",
"type": "main",
"index": 0
}
]
]
},
"Guardar archivo CSV": {
"main": [
[
{
"node": "Get row(s) in sheet",
"type": "main",
"index": 0
}
]
]
},
"ID del spreadsheet": {
"main": [
[
{
"node": "Descargar a CSV",
"type": "main",
"index": 0
}
]
]
},
"ID del PDF de la primera planilla": {
"main": [
[
{
"node": "Descargar primera planilla",
"type": "main",
"index": 0
}
]
]
},
"ID del PDF de la segunda planilla": {
"main": [
[
{
"node": "Descargar segunda planilla",
"type": "main",
"index": 0
}
]
]
},
"Descargar primera planilla": {
"main": [
[
{
"node": "Primera planilla",
"type": "main",
"index": 0
}
]
]
},
"Descargar segunda planilla": {
"main": [
[
{
"node": "Segunda planilla",
"type": "main",
"index": 0
}
]
]
},
"ID del spreadsheet1": {
"main": [
[
{
"node": "Descargar a CSV1",
"type": "main",
"index": 0
}
]
]
},
"ID del PDF de la planilla": {
"main": [
[
{
"node": "Descargar planilla",
"type": "main",
"index": 0
}
]
]
},
"Primera planilla": {
"main": [
[
{
"node": "Merge - Esperar los 3 insumos2",
"type": "main",
"index": 1
}
]
]
},
"Segunda planilla": {
"main": [
[
{
"node": "Merge - Esperar los 3 insumos2",
"type": "main",
"index": 2
}
]
]
},
"Descargar a CSV1": {
"main": [
[
{
"node": "Guardar archivo CSV1",
"type": "main",
"index": 0
}
]
]
},
"Descargar planilla": {
"main": [
[
{
"node": "Planilla",
"type": "main",
"index": 0
}
]
]
},
"Planilla": {
"main": [
[
{
"node": "Merge - Esperar los 2 insumos",
"type": "main",
"index": 1
}
]
]
},
"Merge - Esperar los 2 insumos": {
"main": [
[
{
"node": "Code - Comparar Cedulas3",
"type": "main",
"index": 0
}
]
]
},
"Respond to Webhook": {
"main": [
[]
]
},
"Guardar archivo CSV1": {
"main": [
[
{
"node": "Get row(s) in sheet3",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1",
"binaryMode": "separate",
"timeSavedMode": "fixed",
"errorWorkflow": "lX5ITf9s4TSQglsM",
"timezone": "America/Santo_Domingo",
"callerPolicy": "workflowsFromSameOwner",
"availableInMCP": false
},
"versionId": "20eb764f-b87d-472b-a330-9b237fdba431",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "b4b77b17af092830e794eef639ce2f6d7daccf7eddc075060b03b3b6545aac70"
},
"id": "8Oz31iFlkxqEcW64",
"tags": []
}