From b8c1ee476a3f17e42f9923b8e88a182a901f2c08 Mon Sep 17 00:00:00 2001 From: Isaac_Aracena Date: Sun, 19 Jul 2026 04:01:36 +0000 Subject: [PATCH] =?UTF-8?q?Create=20backup:=20Portal=20de=20Verificaci?= =?UTF-8?q?=C3=B3n=20de=20N=C3=B3mina=20TT=20-=20Env=C3=ADo=20de=20Reporte?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...icacion-de-nomina-tt-envio-de-reporte.json | 694 ++++++++++++++++++ 1 file changed, 694 insertions(+) create mode 100644 portal-de-verificacion-de-nomina-tt-envio-de-reporte.json diff --git a/portal-de-verificacion-de-nomina-tt-envio-de-reporte.json b/portal-de-verificacion-de-nomina-tt-envio-de-reporte.json new file mode 100644 index 0000000..f0abf0c --- /dev/null +++ b/portal-de-verificacion-de-nomina-tt-envio-de-reporte.json @@ -0,0 +1,694 @@ +{ + "updatedAt": "2026-07-16T16:23:39.126Z", + "createdAt": "2026-07-14T15:32:29.194Z", + "id": "aihmNdYFskfvf3XF", + "name": "Portal de Verificación de Nómina TT - Envío de Reporte", + "description": "Gestiona la resolución de reportes del Portal de Verificación de Nómina de Trinidad y Tobago: valida la solicitud recibida desde la aplicación, marca el reporte como resuelto en Supabase, registra los datos de la resolución, notifica por correo al equipo responsable de TT y devuelve la confirmación final al portal, incluyendo manejo de solicitudes inválidas.", + "active": true, + "isArchived": false, + "nodes": [ + { + "parameters": { + "httpMethod": "POST", + "path": "cruce-cuentas-tt-marcar-resuelto", + "responseMode": "responseNode", + "options": {} + }, + "type": "n8n-nodes-base.webhook", + "typeVersion": 2.1, + "position": [ + -752, + 112 + ], + "id": "1affa570-6b53-43d0-afab-25aaf5b8da2d", + "name": "Webhook Marcar Resuelto", + "webhookId": "b0f8173c-c81a-4d32-9205-ab0102dec679" + }, + { + "parameters": { + "jsCode": "const body = $input.first().json.body || $input.first().json || {};\n\nfunction clean(value) {\n return String(value ?? '').replace(/\\s+/g, ' ').trim();\n}\n\nconst reportId = clean(body.reportId || body.id);\nconst comentarioResolucion = clean(body.comentarioResolucion || body.comentario || '');\nconst resueltoPorNombre = clean(body.resueltoPorNombre || body.userName || 'Usuario GLM');\nconst resueltoPorEmail = clean(body.resueltoPorEmail || body.userEmail || '');\n\nconst errors = [];\n\nif (!reportId) {\n errors.push('No se recibió el ID del reporte.');\n}\n\nif (!comentarioResolucion) {\n errors.push('Debe indicar un comentario de resolución.');\n}\n\nif (comentarioResolucion.length < 10) {\n errors.push('El comentario de resolución debe ser más descriptivo.');\n}\n\nif (errors.length > 0) {\n return [\n {\n json: {\n ok: false,\n stage: 'validacion_resolucion',\n errors,\n reportId,\n },\n },\n ];\n}\n\nreturn [\n {\n json: {\n ok: true,\n stage: 'resolucion_validada',\n reportId,\n comentarioResolucion,\n resueltoPorNombre,\n resueltoPorEmail,\n resolvedAt: new Date().toISOString(),\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + -544, + 112 + ], + "id": "5e78d132-c731-4d6a-8926-8afa88e5df12", + "name": "Validar resolución" + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict", + "version": 3 + }, + "conditions": [ + { + "id": "c89884c6-de96-4b08-bd20-54644bb95bc7", + "leftValue": "={{ $json.ok }}", + "rightValue": "", + "operator": { + "type": "boolean", + "operation": "true", + "singleValue": true + } + } + ], + "combinator": "and" + }, + "options": {} + }, + "type": "n8n-nodes-base.if", + "typeVersion": 2.3, + "position": [ + -336, + 112 + ], + "id": "cc34f3e6-40f2-43e3-99f1-0aea4fb502c4", + "name": "¿Solicitud válida?" + }, + { + "parameters": { + "method": "PATCH", + "url": "={{ 'https://dbit.digitalcompass.agency/rest/v1/cruces_cuentas_gt_reportes?id=eq.' + encodeURIComponent($json.reportId) + '&country=eq.TT' }}", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "apikey", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Authorization", + "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Prefer", + "value": "return=representation" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{\n {\n estado: 'resuelto',\n resuelto_por_nombre: $json.resueltoPorNombre,\n resuelto_por_email: $json.resueltoPorEmail,\n resuelto_en: $json.resolvedAt,\n comentario_resolucion: $json.comentarioResolucion,\n updated_at: $json.resolvedAt\n }\n}}", + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 0, + 0 + ], + "id": "52b2af1a-ac9f-4b47-9950-2f91e32084b0", + "name": "Actualizar reporte Supabase" + }, + { + "parameters": { + "jsCode": "const input = $input.first().json || {};\nconst report = Array.isArray(input) ? input[0] : input;\n\nif (!report || !report.id) {\n throw new Error(\n 'No se encontró un reporte de Trinidad y Tobago con el ID recibido.'\n );\n}\n\nif (String(report.country || '').toUpperCase() !== 'TT') {\n throw new Error(\n 'El reporte localizado no pertenece a Trinidad y Tobago.'\n );\n}\nconst original = $('Validar resolución').first().json || {};\n\n\nfunction escapeHtml(value) {\n return String(value ?? '')\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction numberValue(value) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nconst periodo = report.period_label || 'Período no especificado';\nconst reportUrl = report.report_url || '';\n\nconst discrepancias = numberValue(report.discrepancias);\nconst bancoSinNomina = numberValue(report.banco_sin_nomina);\nconst bancoSinBamboo = numberValue(report.banco_sin_bamboo);\nconst nominaSinCuenta = numberValue(report.nomina_sin_cuenta);\n\nconst resolvedAt = original.resolvedAt || new Date().toISOString();\n\nconst resolvedDateLabel = new Date(resolvedAt).toLocaleString('es-DO', {\n timeZone: 'America/Port_of_Spain',\n dateStyle: 'long',\n timeStyle: 'short',\n});\n\nconst resolvedByName =\n original.resueltoPorNombre || 'Usuario GLM';\n\nconst resolvedByEmail =\n original.resueltoPorEmail || '';\n\nconst resolutionComment =\n original.comentarioResolucion || 'Sin comentario registrado.';\n\nconst logoUrl =\n 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png';\n\nconst subject =\n `Reporte resuelto - Cruce de Cuentas Trinidad y Tobago - ${periodo}`;\n\nconst textBody = `\nHola equipo,\n\nSe marcó como resuelto un reporte de Cruce de Cuentas Trinidad y Tobago.\n\nPeríodo:\n${periodo}\n\nResuelto por:\n${resolvedByName}${resolvedByEmail ? ` (${resolvedByEmail})` : ''}\n\nFecha/hora:\n${resolvedDateLabel}\n\nResumen:\n- Discrepancias: ${discrepancias}\n- Banco sin nómina: ${bancoSinNomina}\n- Banco sin Bamboo: ${bancoSinBamboo}\n- Nómina sin cuenta: ${nominaSinCuenta}\n\nComentario:\n${resolutionComment}\n\nGoogle Sheet:\n${reportUrl || 'No disponible'}\n\nSaludos,\nPortal Cruce de Cuentas GLM\n`.trim();\n\nconst htmlBody = `\n\n\n\n \n \n ${escapeHtml(subject)}\n\n\n\n\n \n \n \n\n \n\n \n \n \n \n \n\n \n  \n \n\n \n \n
\n Cruce de Cuentas Trinidad y Tobago\n
\n\n

\n Reporte marcado como resuelto\n

\n \n \n\n \n \n

\n Hola equipo,\n

\n\n

\n El siguiente reporte fue revisado y marcado como\n resuelto.\n

\n \n \n\n \n \n \n \n \n Período\n \n\n \n ${escapeHtml(periodo)}\n \n \n\n \n \n Resuelto por\n \n\n \n ${escapeHtml(resolvedByName)}\n ${\n resolvedByEmail\n ? `
${escapeHtml(resolvedByEmail)}`\n : ''\n }\n \n \n\n \n \n Fecha y hora\n \n\n \n ${escapeHtml(resolvedDateLabel)}\n \n \n \n \n \n\n \n \n
\n Resumen del reporte\n
\n \n \n\n \n \n \n \n \n
\n ${discrepancias}\n
\n\n
\n Discrepancias\n
\n \n\n \n
\n ${bancoSinBamboo}\n
\n\n
\n Banco sin Bamboo\n
\n \n\n \n
\n ${bancoSinNomina}\n
\n\n
\n Banco sin nómina\n
\n \n\n \n
\n ${nominaSinCuenta}\n
\n\n
\n Nómina sin cuenta\n
\n \n \n \n \n \n\n \n \n
\n Comentario de resolución\n
\n \n \n\n \n \n
\n ${escapeHtml(resolutionComment).replace(/\\n/g, '
')}\n
\n \n \n\n ${\n reportUrl\n ? `\n \n \n \n Abrir Google Sheet\n \n \n \n `\n : ''\n }\n\n \n \n Mensaje automático del Portal Cruce de Cuentas GLM.\n \n \n\n \n \n \n \n\n\n\n`.trim();\n\nreturn [\n {\n json: {\n to: 'jgomez@gomezleemarketing.com, mgomez@gomezleemarketing.com, ymadera@gomezleemarketing.com',\n cc: 'iaracena@gomezleemarketing.com',\n subject,\n textBody,\n htmlBody,\n report,\n resolution: original,\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 208, + 0 + ], + "id": "966b80c6-0935-46fe-a700-d073bbc95b2f", + "name": "Preparar correo equipo TT" + }, + { + "parameters": { + "sendTo": "={{$json.to}}", + "subject": "={{$json.subject}}", + "message": "={{ $json.htmlBody }}", + "options": { + "appendAttribution": false, + "ccList": "={{ $json.cc }}" + } + }, + "type": "n8n-nodes-base.gmail", + "typeVersion": 2.2, + "position": [ + 416, + 0 + ], + "id": "dc52381c-3e76-4991-bc09-a87472d51d64", + "name": "Enviar correo equipo TT", + "webhookId": "da3b90f2-2e52-4a99-beea-5bc580486f75", + "credentials": { + "gmailOAuth2": { + "id": "UDcO1FLJqA453V2D", + "name": "Gmail account 3" + } + } + }, + { + "parameters": { + "jsCode": "const original = $('Validar resolución').first().json || {};\nconst updatedResponse = $('Actualizar reporte Supabase').first().json || {};\nconst updatedReport = Array.isArray(updatedResponse) ? updatedResponse[0] : updatedResponse;\n\nreturn [\n {\n json: {\n ok: true,\n stage: 'reporte_resuelto',\n message: 'Reporte marcado como resuelto correctamente.',\n report: {\n id: original.reportId,\n estado: 'resuelto',\n estadoLabel: 'RESUELTO',\n country: 'TT',\n countryName: 'Trinidad y Tobago',\n resueltoPorNombre: original.resueltoPorNombre,\n resueltoPorEmail: original.resueltoPorEmail,\n resueltoEn: original.resolvedAt,\n comentarioResolucion: original.comentarioResolucion,\n reportUrl: updatedReport.report_url || '',\n },\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 624, + 0 + ], + "id": "d0b12567-ae34-4d7a-8b8c-70e4e855bf35", + "name": "Preparar respuesta resuelto" + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "={{ $json }}", + "options": { + "responseCode": 200, + "responseHeaders": { + "entries": [ + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "name": "Access-Control-Allow-Methods", + "value": "GET,POST,OPTIONS" + }, + { + "name": "Access-Control-Allow-Headers", + "value": "Content-Type, Authorization" + } + ] + } + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + 832, + 0 + ], + "id": "f6ea0dba-e017-41f8-9cb4-2685a608a58d", + "name": "Responder resuelto app" + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "={{ $json }}", + "options": { + "responseCode": 400, + "responseHeaders": { + "entries": [ + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "name": "Access-Control-Allow-Methods", + "value": "GET,POST,OPTIONS" + }, + { + "name": "Access-Control-Allow-Headers", + "value": "Content-Type, Authorization" + } + ] + } + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + -128, + 208 + ], + "id": "4fbe8e29-c6b3-4095-8474-4d82a1e8c639", + "name": "Responder error resolución" + } + ], + "connections": { + "Webhook Marcar Resuelto": { + "main": [ + [ + { + "node": "Validar resolución", + "type": "main", + "index": 0 + } + ] + ] + }, + "Validar resolución": { + "main": [ + [ + { + "node": "¿Solicitud válida?", + "type": "main", + "index": 0 + } + ] + ] + }, + "¿Solicitud válida?": { + "main": [ + [ + { + "node": "Actualizar reporte Supabase", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Responder error resolución", + "type": "main", + "index": 0 + } + ] + ] + }, + "Actualizar reporte Supabase": { + "main": [ + [ + { + "node": "Preparar correo equipo TT", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar correo equipo TT": { + "main": [ + [ + { + "node": "Enviar correo equipo TT", + "type": "main", + "index": 0 + } + ] + ] + }, + "Enviar correo equipo TT": { + "main": [ + [ + { + "node": "Preparar respuesta resuelto", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar respuesta resuelto": { + "main": [ + [ + { + "node": "Responder resuelto app", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "settings": { + "executionOrder": "v1", + "binaryMode": "separate", + "availableInMCP": true + }, + "staticData": null, + "meta": null, + "versionId": "b0f2b478-c6fc-4ebe-9e0c-9fecc23b2471", + "activeVersionId": "b0f2b478-c6fc-4ebe-9e0c-9fecc23b2471", + "versionCounter": 10, + "triggerCount": 1, + "shared": [ + { + "updatedAt": "2026-07-14T15:32:29.214Z", + "createdAt": "2026-07-14T15:32:29.214Z", + "role": "workflow:owner", + "workflowId": "aihmNdYFskfvf3XF", + "projectId": "PJpTANzTXIFibWsW", + "project": { + "updatedAt": "2026-04-22T14:25:09.686Z", + "createdAt": "2026-04-22T14:22:54.790Z", + "id": "PJpTANzTXIFibWsW", + "name": "Isaac Aracena ", + "type": "personal", + "icon": null, + "description": null, + "creatorId": "0a88c0b1-928e-4412-896e-c5d1c99b2029" + } + } + ], + "tags": [], + "activeVersion": { + "updatedAt": "2026-07-14T15:33:26.000Z", + "createdAt": "2026-07-14T15:32:29.220Z", + "versionId": "b0f2b478-c6fc-4ebe-9e0c-9fecc23b2471", + "workflowId": "aihmNdYFskfvf3XF", + "nodes": [ + { + "parameters": { + "httpMethod": "POST", + "path": "cruce-cuentas-tt-marcar-resuelto", + "responseMode": "responseNode", + "options": {} + }, + "type": "n8n-nodes-base.webhook", + "typeVersion": 2.1, + "position": [ + -752, + 112 + ], + "id": "1affa570-6b53-43d0-afab-25aaf5b8da2d", + "name": "Webhook Marcar Resuelto", + "webhookId": "b0f8173c-c81a-4d32-9205-ab0102dec679" + }, + { + "parameters": { + "jsCode": "const body = $input.first().json.body || $input.first().json || {};\n\nfunction clean(value) {\n return String(value ?? '').replace(/\\s+/g, ' ').trim();\n}\n\nconst reportId = clean(body.reportId || body.id);\nconst comentarioResolucion = clean(body.comentarioResolucion || body.comentario || '');\nconst resueltoPorNombre = clean(body.resueltoPorNombre || body.userName || 'Usuario GLM');\nconst resueltoPorEmail = clean(body.resueltoPorEmail || body.userEmail || '');\n\nconst errors = [];\n\nif (!reportId) {\n errors.push('No se recibió el ID del reporte.');\n}\n\nif (!comentarioResolucion) {\n errors.push('Debe indicar un comentario de resolución.');\n}\n\nif (comentarioResolucion.length < 10) {\n errors.push('El comentario de resolución debe ser más descriptivo.');\n}\n\nif (errors.length > 0) {\n return [\n {\n json: {\n ok: false,\n stage: 'validacion_resolucion',\n errors,\n reportId,\n },\n },\n ];\n}\n\nreturn [\n {\n json: {\n ok: true,\n stage: 'resolucion_validada',\n reportId,\n comentarioResolucion,\n resueltoPorNombre,\n resueltoPorEmail,\n resolvedAt: new Date().toISOString(),\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + -544, + 112 + ], + "id": "5e78d132-c731-4d6a-8926-8afa88e5df12", + "name": "Validar resolución" + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict", + "version": 3 + }, + "conditions": [ + { + "id": "c89884c6-de96-4b08-bd20-54644bb95bc7", + "leftValue": "={{ $json.ok }}", + "rightValue": "", + "operator": { + "type": "boolean", + "operation": "true", + "singleValue": true + } + } + ], + "combinator": "and" + }, + "options": {} + }, + "type": "n8n-nodes-base.if", + "typeVersion": 2.3, + "position": [ + -336, + 112 + ], + "id": "cc34f3e6-40f2-43e3-99f1-0aea4fb502c4", + "name": "¿Solicitud válida?" + }, + { + "parameters": { + "method": "PATCH", + "url": "={{ 'https://dbit.digitalcompass.agency/rest/v1/cruces_cuentas_gt_reportes?id=eq.' + encodeURIComponent($json.reportId) + '&country=eq.TT' }}", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "apikey", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Authorization", + "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Prefer", + "value": "return=representation" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{\n {\n estado: 'resuelto',\n resuelto_por_nombre: $json.resueltoPorNombre,\n resuelto_por_email: $json.resueltoPorEmail,\n resuelto_en: $json.resolvedAt,\n comentario_resolucion: $json.comentarioResolucion,\n updated_at: $json.resolvedAt\n }\n}}", + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 0, + 0 + ], + "id": "52b2af1a-ac9f-4b47-9950-2f91e32084b0", + "name": "Actualizar reporte Supabase" + }, + { + "parameters": { + "jsCode": "const input = $input.first().json || {};\nconst report = Array.isArray(input) ? input[0] : input;\n\nif (!report || !report.id) {\n throw new Error(\n 'No se encontró un reporte de Trinidad y Tobago con el ID recibido.'\n );\n}\n\nif (String(report.country || '').toUpperCase() !== 'TT') {\n throw new Error(\n 'El reporte localizado no pertenece a Trinidad y Tobago.'\n );\n}\nconst original = $('Validar resolución').first().json || {};\n\n\nfunction escapeHtml(value) {\n return String(value ?? '')\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction numberValue(value) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nconst periodo = report.period_label || 'Período no especificado';\nconst reportUrl = report.report_url || '';\n\nconst discrepancias = numberValue(report.discrepancias);\nconst bancoSinNomina = numberValue(report.banco_sin_nomina);\nconst bancoSinBamboo = numberValue(report.banco_sin_bamboo);\nconst nominaSinCuenta = numberValue(report.nomina_sin_cuenta);\n\nconst resolvedAt = original.resolvedAt || new Date().toISOString();\n\nconst resolvedDateLabel = new Date(resolvedAt).toLocaleString('es-DO', {\n timeZone: 'America/Port_of_Spain',\n dateStyle: 'long',\n timeStyle: 'short',\n});\n\nconst resolvedByName =\n original.resueltoPorNombre || 'Usuario GLM';\n\nconst resolvedByEmail =\n original.resueltoPorEmail || '';\n\nconst resolutionComment =\n original.comentarioResolucion || 'Sin comentario registrado.';\n\nconst logoUrl =\n 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png';\n\nconst subject =\n `Reporte resuelto - Cruce de Cuentas Trinidad y Tobago - ${periodo}`;\n\nconst textBody = `\nHola equipo,\n\nSe marcó como resuelto un reporte de Cruce de Cuentas Trinidad y Tobago.\n\nPeríodo:\n${periodo}\n\nResuelto por:\n${resolvedByName}${resolvedByEmail ? ` (${resolvedByEmail})` : ''}\n\nFecha/hora:\n${resolvedDateLabel}\n\nResumen:\n- Discrepancias: ${discrepancias}\n- Banco sin nómina: ${bancoSinNomina}\n- Banco sin Bamboo: ${bancoSinBamboo}\n- Nómina sin cuenta: ${nominaSinCuenta}\n\nComentario:\n${resolutionComment}\n\nGoogle Sheet:\n${reportUrl || 'No disponible'}\n\nSaludos,\nPortal Cruce de Cuentas GLM\n`.trim();\n\nconst htmlBody = `\n\n\n\n \n \n ${escapeHtml(subject)}\n\n\n\n\n \n \n \n\n \n\n \n \n \n \n \n\n \n  \n \n\n \n \n
\n Cruce de Cuentas Trinidad y Tobago\n
\n\n

\n Reporte marcado como resuelto\n

\n \n \n\n \n \n

\n Hola equipo,\n

\n\n

\n El siguiente reporte fue revisado y marcado como\n resuelto.\n

\n \n \n\n \n \n \n \n \n Período\n \n\n \n ${escapeHtml(periodo)}\n \n \n\n \n \n Resuelto por\n \n\n \n ${escapeHtml(resolvedByName)}\n ${\n resolvedByEmail\n ? `
${escapeHtml(resolvedByEmail)}`\n : ''\n }\n \n \n\n \n \n Fecha y hora\n \n\n \n ${escapeHtml(resolvedDateLabel)}\n \n \n \n \n \n\n \n \n
\n Resumen del reporte\n
\n \n \n\n \n \n \n \n \n
\n ${discrepancias}\n
\n\n
\n Discrepancias\n
\n \n\n \n
\n ${bancoSinBamboo}\n
\n\n
\n Banco sin Bamboo\n
\n \n\n \n
\n ${bancoSinNomina}\n
\n\n
\n Banco sin nómina\n
\n \n\n \n
\n ${nominaSinCuenta}\n
\n\n
\n Nómina sin cuenta\n
\n \n \n \n \n \n\n \n \n
\n Comentario de resolución\n
\n \n \n\n \n \n
\n ${escapeHtml(resolutionComment).replace(/\\n/g, '
')}\n
\n \n \n\n ${\n reportUrl\n ? `\n \n \n \n Abrir Google Sheet\n \n \n \n `\n : ''\n }\n\n \n \n Mensaje automático del Portal Cruce de Cuentas GLM.\n \n \n\n \n \n \n \n\n\n\n`.trim();\n\nreturn [\n {\n json: {\n to: 'jgomez@gomezleemarketing.com, mgomez@gomezleemarketing.com, ymadera@gomezleemarketing.com',\n cc: 'iaracena@gomezleemarketing.com',\n subject,\n textBody,\n htmlBody,\n report,\n resolution: original,\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 208, + 0 + ], + "id": "966b80c6-0935-46fe-a700-d073bbc95b2f", + "name": "Preparar correo equipo TT" + }, + { + "parameters": { + "sendTo": "={{$json.to}}", + "subject": "={{$json.subject}}", + "message": "={{ $json.htmlBody }}", + "options": { + "appendAttribution": false, + "ccList": "={{ $json.cc }}" + } + }, + "type": "n8n-nodes-base.gmail", + "typeVersion": 2.2, + "position": [ + 416, + 0 + ], + "id": "dc52381c-3e76-4991-bc09-a87472d51d64", + "name": "Enviar correo equipo TT", + "webhookId": "da3b90f2-2e52-4a99-beea-5bc580486f75", + "credentials": { + "gmailOAuth2": { + "id": "UDcO1FLJqA453V2D", + "name": "Gmail account 3" + } + } + }, + { + "parameters": { + "jsCode": "const original = $('Validar resolución').first().json || {};\nconst updatedResponse = $('Actualizar reporte Supabase').first().json || {};\nconst updatedReport = Array.isArray(updatedResponse) ? updatedResponse[0] : updatedResponse;\n\nreturn [\n {\n json: {\n ok: true,\n stage: 'reporte_resuelto',\n message: 'Reporte marcado como resuelto correctamente.',\n report: {\n id: original.reportId,\n estado: 'resuelto',\n estadoLabel: 'RESUELTO',\n country: 'TT',\n countryName: 'Trinidad y Tobago',\n resueltoPorNombre: original.resueltoPorNombre,\n resueltoPorEmail: original.resueltoPorEmail,\n resueltoEn: original.resolvedAt,\n comentarioResolucion: original.comentarioResolucion,\n reportUrl: updatedReport.report_url || '',\n },\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 624, + 0 + ], + "id": "d0b12567-ae34-4d7a-8b8c-70e4e855bf35", + "name": "Preparar respuesta resuelto" + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "={{ $json }}", + "options": { + "responseCode": 200, + "responseHeaders": { + "entries": [ + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "name": "Access-Control-Allow-Methods", + "value": "GET,POST,OPTIONS" + }, + { + "name": "Access-Control-Allow-Headers", + "value": "Content-Type, Authorization" + } + ] + } + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + 832, + 0 + ], + "id": "f6ea0dba-e017-41f8-9cb4-2685a608a58d", + "name": "Responder resuelto app" + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "={{ $json }}", + "options": { + "responseCode": 400, + "responseHeaders": { + "entries": [ + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "name": "Access-Control-Allow-Methods", + "value": "GET,POST,OPTIONS" + }, + { + "name": "Access-Control-Allow-Headers", + "value": "Content-Type, Authorization" + } + ] + } + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + -128, + 208 + ], + "id": "4fbe8e29-c6b3-4095-8474-4d82a1e8c639", + "name": "Responder error resolución" + } + ], + "connections": { + "Webhook Marcar Resuelto": { + "main": [ + [ + { + "node": "Validar resolución", + "type": "main", + "index": 0 + } + ] + ] + }, + "Validar resolución": { + "main": [ + [ + { + "node": "¿Solicitud válida?", + "type": "main", + "index": 0 + } + ] + ] + }, + "¿Solicitud válida?": { + "main": [ + [ + { + "node": "Actualizar reporte Supabase", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Responder error resolución", + "type": "main", + "index": 0 + } + ] + ] + }, + "Actualizar reporte Supabase": { + "main": [ + [ + { + "node": "Preparar correo equipo TT", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar correo equipo TT": { + "main": [ + [ + { + "node": "Enviar correo equipo TT", + "type": "main", + "index": 0 + } + ] + ] + }, + "Enviar correo equipo TT": { + "main": [ + [ + { + "node": "Preparar respuesta resuelto", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar respuesta resuelto": { + "main": [ + [ + { + "node": "Responder resuelto app", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "authors": "Isaac Aracena", + "name": "Version b0f2b478", + "description": "", + "autosaved": true, + "workflowPublishHistory": [ + { + "createdAt": "2026-07-14T15:33:25.979Z", + "id": 2909, + "workflowId": "aihmNdYFskfvf3XF", + "versionId": "b0f2b478-c6fc-4ebe-9e0c-9fecc23b2471", + "event": "activated", + "userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029" + } + ] + } +} \ No newline at end of file