Update backup: Portal de Verificación de Nómina - Reportar corrección BambooHR a RRHH

This commit is contained in:
2026-08-23 04:00:39 +00:00
parent d1aad117fd
commit cfebf0b646
@@ -1,5 +1,5 @@
{
"updatedAt": "2026-08-11T18:48:49.761Z",
"updatedAt": "2026-08-19T14:20:00.099Z",
"createdAt": "2026-08-11T18:47:42.698Z",
"id": "0yaiagL1tWdhRUXy",
"name": "Portal de Verificación de Nómina - Reportar corrección BambooHR a RRHH",
@@ -17,10 +17,10 @@
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
0,
0
256,
528
],
"id": "7e321136-0268-4f7e-bde1-b3a7b1b60caf",
"id": "9f82287d-3017-4fb8-be43-3c3313f4e466",
"name": "Webhook",
"webhookId": "df5cb56b-75f3-4e8b-a1f2-f9a05c8ec317"
},
@@ -31,10 +31,10 @@
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
240,
0
496,
528
],
"id": "507c0065-11d8-4693-86d7-acaaf826d8a0",
"id": "48884cdb-c052-4e9c-ac95-1d0eac8911f3",
"name": "Preparar solicitud"
},
{
@@ -68,10 +68,10 @@
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
480,
0
736,
528
],
"id": "9b9f3800-4182-4cc4-a6e3-11e200c44b1f",
"id": "3b5acfa4-19f9-41cf-943b-2dddf799b909",
"name": "Validar acceso Supabase",
"retryOnFail": true,
"maxTries": 2,
@@ -84,10 +84,10 @@
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
720,
0
976,
528
],
"id": "b20cb8fa-fa37-48a5-93aa-dd1740e8a6c0",
"id": "23a5aabe-20be-4f4d-92a2-e4d400b96d75",
"name": "Validar usuario"
},
{
@@ -131,10 +131,10 @@
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
960,
0
1216,
528
],
"id": "5dc107fa-c704-4643-9479-1f57e163d5fd",
"id": "07be5909-2a5b-47f4-96b2-466f2658f0db",
"name": "Consultar empleado BambooHR",
"retryOnFail": true,
"maxTries": 3,
@@ -148,15 +148,15 @@
},
{
"parameters": {
"jsCode": "const request = $('Validar usuario').first().json || {};\nconst raw = $input.first().json || {};\n\nfunction clean(value) {\n return String(value ?? '').replace(/\\s+/g, ' ').trim();\n}\n\nfunction normalizeName(value) {\n return clean(value)\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9 ]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction normalizeIdentifier(value) {\n return clean(value).toUpperCase().replace(/[^A-Z0-9]/g, '');\n}\n\nfunction countryMatches(employee) {\n const location = normalizeName(\n employee.location ||\n employee.jobInformationLocation ||\n employee.jobLocation ||\n employee.country ||\n ''\n );\n\n if (request.country === 'GT') {\n return location.includes('guatemala');\n }\n\n return location.includes('trinidad') || location.includes('tobago');\n}\n\nfunction employeeAliases(employee) {\n const first = clean(employee.firstName || employee.first_name);\n const middle = clean(employee.middleName || employee.middle_name);\n const last = clean(employee.lastName || employee.last_name);\n const display = clean(employee.displayName || employee.fullName || employee.full_name);\n\n return Array.from(new Set([\n display,\n [first, middle, last].filter(Boolean).join(' '),\n [first, last].filter(Boolean).join(' '),\n ].map(clean).filter(Boolean)));\n}\n\nconst employees = Array.isArray(raw.employees)\n ? raw.employees\n : Array.isArray(raw.data?.employees)\n ? raw.data.employees\n : [];\n\nif (!employees.length) {\n throw new Error('BambooHR no devolvió empleados para validar la corrección.');\n}\n\nconst candidates = employees.filter(countryMatches);\nif (!candidates.length) {\n throw new Error(`No se encontraron empleados de ${request.countryName} en BambooHR.`);\n}\n\nconst requestedNumber = normalizeIdentifier(request.bambooEmployeeNumber);\nlet matches = [];\nlet matchedBy = '';\n\nif (requestedNumber) {\n matches = candidates.filter((employee) =>\n normalizeIdentifier(employee.employeeNumber || employee.employee_number) === requestedNumber\n );\n matchedBy = 'employee_number';\n}\n\nif (!matches.length) {\n const targetName = normalizeName(request.bambooName);\n matches = candidates.filter((employee) =>\n employeeAliases(employee).some((alias) => normalizeName(alias) === targetName)\n );\n matchedBy = 'exact_bamboo_name';\n}\n\nif (matches.length !== 1) {\n if (matches.length > 1) {\n throw new Error('La identificación en BambooHR es ambigua. Indica el Employee Number para seleccionar una sola persona.');\n }\n\n throw new Error(\n 'No se encontró exactamente ese empleado en BambooHR para el país seleccionado. Revisa el nombre o indica el Employee Number.'\n );\n}\n\nconst employee = matches[0];\nconst aliases = employeeAliases(employee);\nconst actualName = clean(employee.displayName) || aliases[0] || request.bambooName;\nconst actualEmployeeNumber = clean(employee.employeeNumber || employee.employee_number);\nconst bambooId = clean(employee.employeeId || employee.id);\nconst now = new Date().toISOString();\n\nconst recipients = request.country === 'TT'\n ? ['lnicomejack@gomezleemarketing.com']\n : [\n 'pgamboa@gomezleemarketing.com',\n 'smeyer@gomezleemarketing.com',\n 'mjmorales@gomezleemarketing.com',\n ];\n\nconst aliasPayload = request.sourceNames.map((sourceName) => ({\n pais: request.country,\n nombre_origen: sourceName,\n nombre_origen_normalizado: normalizeName(sourceName),\n cuenta_bancaria: String(request.bankAccount || '').replace(/[^0-9A-Za-z]+/g, ''),\n bamboo_employee_number: actualEmployeeNumber || null,\n bamboo_employee_id: bambooId || null,\n bamboo_nombre: actualName,\n motivo: request.reason,\n comentario: request.comment || null,\n activo: true,\n validado_por_email: request.requestedByEmail,\n validado_por_nombre: request.requestedByName,\n last_reported_at: now,\n updated_at: now,\n}));\n\nreturn [{\n json: {\n request,\n matchedBy,\n employee: {\n bambooId,\n employeeNumber: actualEmployeeNumber,\n name: actualName,\n status: clean(employee.status),\n location: clean(employee.location),\n },\n recipients,\n aliasPayload,\n },\n}];"
"jsCode": "const request = $('Validar usuario').first().json || {};\nconst raw = $input.first().json || {};\n\nfunction clean(value) {\n return String(value ?? '').replace(/\\s+/g, ' ').trim();\n}\n\nfunction normalizeName(value) {\n return clean(value)\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9 ]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction normalizeIdentifier(value) {\n return clean(value).toUpperCase().replace(/[^A-Z0-9]/g, '');\n}\n\nfunction countryMatches(employee) {\n const location = normalizeName(\n employee.location ||\n employee.jobInformationLocation ||\n employee.jobLocation ||\n employee.country ||\n ''\n );\n\n if (request.country === 'GT') {\n return location.includes('guatemala');\n }\n\n return location.includes('trinidad') || location.includes('tobago');\n}\n\nfunction employeeAliases(employee) {\n const first = clean(employee.firstName || employee.first_name);\n const middle = clean(employee.middleName || employee.middle_name);\n const last = clean(employee.lastName || employee.last_name);\n const display = clean(employee.displayName || employee.fullName || employee.full_name);\n\n return Array.from(new Set([\n display,\n [first, middle, last].filter(Boolean).join(' '),\n [first, last].filter(Boolean).join(' '),\n ].map(clean).filter(Boolean)));\n}\n\nconst employees = Array.isArray(raw.employees)\n ? raw.employees\n : Array.isArray(raw.data?.employees)\n ? raw.data.employees\n : [];\n\nif (!employees.length) {\n throw new Error('BambooHR no devolvió empleados para validar la corrección.');\n}\n\nconst candidates = employees.filter(countryMatches);\nif (!candidates.length) {\n throw new Error(`No se encontraron empleados de ${request.countryName} en BambooHR.`);\n}\n\nconst requestedNumber = normalizeIdentifier(request.bambooEmployeeNumber);\nlet matches = [];\nlet matchedBy = '';\n\nif (requestedNumber) {\n matches = candidates.filter((employee) =>\n normalizeIdentifier(employee.employeeNumber || employee.employee_number) === requestedNumber\n );\n matchedBy = 'employee_number';\n}\n\nif (!matches.length) {\n const targetName = normalizeName(request.bambooName);\n matches = candidates.filter((employee) =>\n employeeAliases(employee).some((alias) => normalizeName(alias) === targetName)\n );\n matchedBy = 'exact_bamboo_name';\n}\n\nif (matches.length !== 1) {\n if (matches.length > 1) {\n throw new Error('La identificación en BambooHR es ambigua. Indica el Employee Number para seleccionar una sola persona.');\n }\n\n throw new Error(\n 'No se encontró exactamente ese empleado en BambooHR para el país seleccionado. Revisa el nombre o indica el Employee Number.'\n );\n}\n\nconst employee = matches[0];\nconst aliases = employeeAliases(employee);\nconst actualName = clean(employee.displayName) || aliases[0] || request.bambooName;\nconst actualEmployeeNumber = clean(employee.employeeNumber || employee.employee_number);\nconst bambooId = clean(employee.employeeId || employee.id);\nconst now = new Date().toISOString();\n\nconst recipients = request.country === 'TT'\n ? ['lnicomejack@gomezleemarketing.com']\n : ['haguirre@gomezleemarketing.com'];\n\nconst aliasPayload = request.sourceNames.map((sourceName) => ({\n pais: request.country,\n nombre_origen: sourceName,\n nombre_origen_normalizado: normalizeName(sourceName),\n cuenta_bancaria: String(request.bankAccount || '').replace(/[^0-9A-Za-z]+/g, ''),\n bamboo_employee_number: actualEmployeeNumber || null,\n bamboo_employee_id: bambooId || null,\n bamboo_nombre: actualName,\n motivo: request.reason,\n comentario: request.comment || null,\n activo: true,\n validado_por_email: request.requestedByEmail,\n validado_por_nombre: request.requestedByName,\n last_reported_at: now,\n updated_at: now,\n}));\n\nreturn [{\n json: {\n request,\n matchedBy,\n employee: {\n bambooId,\n employeeNumber: actualEmployeeNumber,\n name: actualName,\n status: clean(employee.status),\n location: clean(employee.location),\n },\n recipients,\n aliasPayload,\n },\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1200,
0
1456,
528
],
"id": "504eed05-c6be-442e-9707-8cd4aca1d19c",
"id": "bb82de3a-cbbf-479c-a2da-96b677cb6eda",
"name": "Resolver empleado BambooHR"
},
{
@@ -194,10 +194,10 @@
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
1440,
0
1696,
528
],
"id": "6fc69ac2-6999-4810-9e8d-675c4c4d40ac",
"id": "062d8846-d24a-4887-9ef3-7de4a5d204d4",
"name": "Guardar alias Supabase",
"retryOnFail": true,
"maxTries": 2,
@@ -210,10 +210,10 @@
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1680,
0
1936,
528
],
"id": "9d565bf5-a6df-4ac9-bad1-abe48a277c37",
"id": "3c1d6a0d-c096-4b31-9ba9-4ce2ec357f8e",
"name": "Preparar auditoría"
},
{
@@ -251,10 +251,10 @@
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
1920,
0
2176,
528
],
"id": "45f87d7b-a746-4eb2-a54e-d2de7645f854",
"id": "9cd76301-127f-449a-a8c5-1bcdfe79de9a",
"name": "Guardar solicitud Supabase",
"retryOnFail": true,
"maxTries": 2,
@@ -267,10 +267,10 @@
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2160,
0
2416,
528
],
"id": "68be3c1d-42eb-4bc5-aa35-36333261f2a6",
"id": "6f05bfa0-78b5-4447-a440-19f90c6f7bba",
"name": "Preparar correo RRHH"
},
{
@@ -285,10 +285,10 @@
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
2400,
0
2656,
528
],
"id": "28f7c657-0c5b-47c6-898b-f68f1cf21378",
"id": "9822f786-4c81-4a07-94ed-081e8485cbba",
"name": "Enviar correo RRHH",
"retryOnFail": true,
"maxTries": 3,
@@ -336,10 +336,10 @@
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
2640,
0
2896,
528
],
"id": "87b7910e-0465-40b1-89d4-6b160726b7f7",
"id": "3e801286-89a6-4e29-a443-4c1f5e5afe14",
"name": "Marcar correo enviado",
"retryOnFail": true,
"maxTries": 2,
@@ -364,10 +364,10 @@
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.5,
"position": [
2880,
0
3136,
528
],
"id": "1db48431-4661-49de-a495-66c740b2aac1",
"id": "4359eea0-0f16-4241-840f-565d56700bb5",
"name": "Respond to Webhook"
}
],
@@ -511,9 +511,9 @@
},
"staticData": null,
"meta": null,
"versionId": "7e4daa40-244f-43ed-9d74-14a9cb589ddf",
"activeVersionId": "7e4daa40-244f-43ed-9d74-14a9cb589ddf",
"versionCounter": 5,
"versionId": "a190ab40-7527-4805-a7ac-cc26ed1e558b",
"activeVersionId": "a190ab40-7527-4805-a7ac-cc26ed1e558b",
"versionCounter": 8,
"triggerCount": 1,
"shared": [
{
@@ -536,9 +536,9 @@
],
"tags": [],
"activeVersion": {
"updatedAt": "2026-08-11T18:47:55.000Z",
"createdAt": "2026-08-11T18:47:42.715Z",
"versionId": "7e4daa40-244f-43ed-9d74-14a9cb589ddf",
"updatedAt": "2026-08-19T14:20:03.000Z",
"createdAt": "2026-08-19T14:20:00.103Z",
"versionId": "a190ab40-7527-4805-a7ac-cc26ed1e558b",
"workflowId": "0yaiagL1tWdhRUXy",
"nodes": [
{
@@ -551,10 +551,10 @@
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
0,
0
256,
528
],
"id": "7e321136-0268-4f7e-bde1-b3a7b1b60caf",
"id": "9f82287d-3017-4fb8-be43-3c3313f4e466",
"name": "Webhook",
"webhookId": "df5cb56b-75f3-4e8b-a1f2-f9a05c8ec317"
},
@@ -565,10 +565,10 @@
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
240,
0
496,
528
],
"id": "507c0065-11d8-4693-86d7-acaaf826d8a0",
"id": "48884cdb-c052-4e9c-ac95-1d0eac8911f3",
"name": "Preparar solicitud"
},
{
@@ -602,10 +602,10 @@
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
480,
0
736,
528
],
"id": "9b9f3800-4182-4cc4-a6e3-11e200c44b1f",
"id": "3b5acfa4-19f9-41cf-943b-2dddf799b909",
"name": "Validar acceso Supabase",
"retryOnFail": true,
"maxTries": 2,
@@ -618,10 +618,10 @@
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
720,
0
976,
528
],
"id": "b20cb8fa-fa37-48a5-93aa-dd1740e8a6c0",
"id": "23a5aabe-20be-4f4d-92a2-e4d400b96d75",
"name": "Validar usuario"
},
{
@@ -665,10 +665,10 @@
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
960,
0
1216,
528
],
"id": "5dc107fa-c704-4643-9479-1f57e163d5fd",
"id": "07be5909-2a5b-47f4-96b2-466f2658f0db",
"name": "Consultar empleado BambooHR",
"retryOnFail": true,
"maxTries": 3,
@@ -682,15 +682,15 @@
},
{
"parameters": {
"jsCode": "const request = $('Validar usuario').first().json || {};\nconst raw = $input.first().json || {};\n\nfunction clean(value) {\n return String(value ?? '').replace(/\\s+/g, ' ').trim();\n}\n\nfunction normalizeName(value) {\n return clean(value)\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9 ]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction normalizeIdentifier(value) {\n return clean(value).toUpperCase().replace(/[^A-Z0-9]/g, '');\n}\n\nfunction countryMatches(employee) {\n const location = normalizeName(\n employee.location ||\n employee.jobInformationLocation ||\n employee.jobLocation ||\n employee.country ||\n ''\n );\n\n if (request.country === 'GT') {\n return location.includes('guatemala');\n }\n\n return location.includes('trinidad') || location.includes('tobago');\n}\n\nfunction employeeAliases(employee) {\n const first = clean(employee.firstName || employee.first_name);\n const middle = clean(employee.middleName || employee.middle_name);\n const last = clean(employee.lastName || employee.last_name);\n const display = clean(employee.displayName || employee.fullName || employee.full_name);\n\n return Array.from(new Set([\n display,\n [first, middle, last].filter(Boolean).join(' '),\n [first, last].filter(Boolean).join(' '),\n ].map(clean).filter(Boolean)));\n}\n\nconst employees = Array.isArray(raw.employees)\n ? raw.employees\n : Array.isArray(raw.data?.employees)\n ? raw.data.employees\n : [];\n\nif (!employees.length) {\n throw new Error('BambooHR no devolvió empleados para validar la corrección.');\n}\n\nconst candidates = employees.filter(countryMatches);\nif (!candidates.length) {\n throw new Error(`No se encontraron empleados de ${request.countryName} en BambooHR.`);\n}\n\nconst requestedNumber = normalizeIdentifier(request.bambooEmployeeNumber);\nlet matches = [];\nlet matchedBy = '';\n\nif (requestedNumber) {\n matches = candidates.filter((employee) =>\n normalizeIdentifier(employee.employeeNumber || employee.employee_number) === requestedNumber\n );\n matchedBy = 'employee_number';\n}\n\nif (!matches.length) {\n const targetName = normalizeName(request.bambooName);\n matches = candidates.filter((employee) =>\n employeeAliases(employee).some((alias) => normalizeName(alias) === targetName)\n );\n matchedBy = 'exact_bamboo_name';\n}\n\nif (matches.length !== 1) {\n if (matches.length > 1) {\n throw new Error('La identificación en BambooHR es ambigua. Indica el Employee Number para seleccionar una sola persona.');\n }\n\n throw new Error(\n 'No se encontró exactamente ese empleado en BambooHR para el país seleccionado. Revisa el nombre o indica el Employee Number.'\n );\n}\n\nconst employee = matches[0];\nconst aliases = employeeAliases(employee);\nconst actualName = clean(employee.displayName) || aliases[0] || request.bambooName;\nconst actualEmployeeNumber = clean(employee.employeeNumber || employee.employee_number);\nconst bambooId = clean(employee.employeeId || employee.id);\nconst now = new Date().toISOString();\n\nconst recipients = request.country === 'TT'\n ? ['lnicomejack@gomezleemarketing.com']\n : [\n 'pgamboa@gomezleemarketing.com',\n 'smeyer@gomezleemarketing.com',\n 'mjmorales@gomezleemarketing.com',\n ];\n\nconst aliasPayload = request.sourceNames.map((sourceName) => ({\n pais: request.country,\n nombre_origen: sourceName,\n nombre_origen_normalizado: normalizeName(sourceName),\n cuenta_bancaria: String(request.bankAccount || '').replace(/[^0-9A-Za-z]+/g, ''),\n bamboo_employee_number: actualEmployeeNumber || null,\n bamboo_employee_id: bambooId || null,\n bamboo_nombre: actualName,\n motivo: request.reason,\n comentario: request.comment || null,\n activo: true,\n validado_por_email: request.requestedByEmail,\n validado_por_nombre: request.requestedByName,\n last_reported_at: now,\n updated_at: now,\n}));\n\nreturn [{\n json: {\n request,\n matchedBy,\n employee: {\n bambooId,\n employeeNumber: actualEmployeeNumber,\n name: actualName,\n status: clean(employee.status),\n location: clean(employee.location),\n },\n recipients,\n aliasPayload,\n },\n}];"
"jsCode": "const request = $('Validar usuario').first().json || {};\nconst raw = $input.first().json || {};\n\nfunction clean(value) {\n return String(value ?? '').replace(/\\s+/g, ' ').trim();\n}\n\nfunction normalizeName(value) {\n return clean(value)\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9 ]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction normalizeIdentifier(value) {\n return clean(value).toUpperCase().replace(/[^A-Z0-9]/g, '');\n}\n\nfunction countryMatches(employee) {\n const location = normalizeName(\n employee.location ||\n employee.jobInformationLocation ||\n employee.jobLocation ||\n employee.country ||\n ''\n );\n\n if (request.country === 'GT') {\n return location.includes('guatemala');\n }\n\n return location.includes('trinidad') || location.includes('tobago');\n}\n\nfunction employeeAliases(employee) {\n const first = clean(employee.firstName || employee.first_name);\n const middle = clean(employee.middleName || employee.middle_name);\n const last = clean(employee.lastName || employee.last_name);\n const display = clean(employee.displayName || employee.fullName || employee.full_name);\n\n return Array.from(new Set([\n display,\n [first, middle, last].filter(Boolean).join(' '),\n [first, last].filter(Boolean).join(' '),\n ].map(clean).filter(Boolean)));\n}\n\nconst employees = Array.isArray(raw.employees)\n ? raw.employees\n : Array.isArray(raw.data?.employees)\n ? raw.data.employees\n : [];\n\nif (!employees.length) {\n throw new Error('BambooHR no devolvió empleados para validar la corrección.');\n}\n\nconst candidates = employees.filter(countryMatches);\nif (!candidates.length) {\n throw new Error(`No se encontraron empleados de ${request.countryName} en BambooHR.`);\n}\n\nconst requestedNumber = normalizeIdentifier(request.bambooEmployeeNumber);\nlet matches = [];\nlet matchedBy = '';\n\nif (requestedNumber) {\n matches = candidates.filter((employee) =>\n normalizeIdentifier(employee.employeeNumber || employee.employee_number) === requestedNumber\n );\n matchedBy = 'employee_number';\n}\n\nif (!matches.length) {\n const targetName = normalizeName(request.bambooName);\n matches = candidates.filter((employee) =>\n employeeAliases(employee).some((alias) => normalizeName(alias) === targetName)\n );\n matchedBy = 'exact_bamboo_name';\n}\n\nif (matches.length !== 1) {\n if (matches.length > 1) {\n throw new Error('La identificación en BambooHR es ambigua. Indica el Employee Number para seleccionar una sola persona.');\n }\n\n throw new Error(\n 'No se encontró exactamente ese empleado en BambooHR para el país seleccionado. Revisa el nombre o indica el Employee Number.'\n );\n}\n\nconst employee = matches[0];\nconst aliases = employeeAliases(employee);\nconst actualName = clean(employee.displayName) || aliases[0] || request.bambooName;\nconst actualEmployeeNumber = clean(employee.employeeNumber || employee.employee_number);\nconst bambooId = clean(employee.employeeId || employee.id);\nconst now = new Date().toISOString();\n\nconst recipients = request.country === 'TT'\n ? ['lnicomejack@gomezleemarketing.com']\n : ['haguirre@gomezleemarketing.com'];\n\nconst aliasPayload = request.sourceNames.map((sourceName) => ({\n pais: request.country,\n nombre_origen: sourceName,\n nombre_origen_normalizado: normalizeName(sourceName),\n cuenta_bancaria: String(request.bankAccount || '').replace(/[^0-9A-Za-z]+/g, ''),\n bamboo_employee_number: actualEmployeeNumber || null,\n bamboo_employee_id: bambooId || null,\n bamboo_nombre: actualName,\n motivo: request.reason,\n comentario: request.comment || null,\n activo: true,\n validado_por_email: request.requestedByEmail,\n validado_por_nombre: request.requestedByName,\n last_reported_at: now,\n updated_at: now,\n}));\n\nreturn [{\n json: {\n request,\n matchedBy,\n employee: {\n bambooId,\n employeeNumber: actualEmployeeNumber,\n name: actualName,\n status: clean(employee.status),\n location: clean(employee.location),\n },\n recipients,\n aliasPayload,\n },\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1200,
0
1456,
528
],
"id": "504eed05-c6be-442e-9707-8cd4aca1d19c",
"id": "bb82de3a-cbbf-479c-a2da-96b677cb6eda",
"name": "Resolver empleado BambooHR"
},
{
@@ -728,10 +728,10 @@
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
1440,
0
1696,
528
],
"id": "6fc69ac2-6999-4810-9e8d-675c4c4d40ac",
"id": "062d8846-d24a-4887-9ef3-7de4a5d204d4",
"name": "Guardar alias Supabase",
"retryOnFail": true,
"maxTries": 2,
@@ -744,10 +744,10 @@
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1680,
0
1936,
528
],
"id": "9d565bf5-a6df-4ac9-bad1-abe48a277c37",
"id": "3c1d6a0d-c096-4b31-9ba9-4ce2ec357f8e",
"name": "Preparar auditoría"
},
{
@@ -785,10 +785,10 @@
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
1920,
0
2176,
528
],
"id": "45f87d7b-a746-4eb2-a54e-d2de7645f854",
"id": "9cd76301-127f-449a-a8c5-1bcdfe79de9a",
"name": "Guardar solicitud Supabase",
"retryOnFail": true,
"maxTries": 2,
@@ -801,10 +801,10 @@
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2160,
0
2416,
528
],
"id": "68be3c1d-42eb-4bc5-aa35-36333261f2a6",
"id": "6f05bfa0-78b5-4447-a440-19f90c6f7bba",
"name": "Preparar correo RRHH"
},
{
@@ -819,10 +819,10 @@
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
2400,
0
2656,
528
],
"id": "28f7c657-0c5b-47c6-898b-f68f1cf21378",
"id": "9822f786-4c81-4a07-94ed-081e8485cbba",
"name": "Enviar correo RRHH",
"retryOnFail": true,
"maxTries": 3,
@@ -870,10 +870,10 @@
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
2640,
0
2896,
528
],
"id": "87b7910e-0465-40b1-89d4-6b160726b7f7",
"id": "3e801286-89a6-4e29-a443-4c1f5e5afe14",
"name": "Marcar correo enviado",
"retryOnFail": true,
"maxTries": 2,
@@ -898,10 +898,10 @@
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.5,
"position": [
2880,
0
3136,
528
],
"id": "1db48431-4661-49de-a495-66c740b2aac1",
"id": "4359eea0-0f16-4241-840f-565d56700bb5",
"name": "Respond to Webhook"
}
],
@@ -1040,15 +1040,15 @@
}
},
"authors": "Isaac Aracena",
"name": "Version 7e4daa40",
"name": "Version a190ab40",
"description": "",
"autosaved": true,
"workflowPublishHistory": [
{
"createdAt": "2026-08-11T18:47:55.639Z",
"id": 4454,
"createdAt": "2026-08-19T14:20:03.066Z",
"id": 4943,
"workflowId": "0yaiagL1tWdhRUXy",
"versionId": "7e4daa40-244f-43ed-9d74-14a9cb589ddf",
"versionId": "a190ab40-7527-4805-a7ac-cc26ed1e558b",
"event": "activated",
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
}