{ "updatedAt": "2026-07-16T16:24:51.988Z", "createdAt": "2026-07-09T13:23:03.746Z", "id": "QDKFgvoJKviQbDl3", "name": "Portal de Verificación de Nómina GT - Históricos", "description": "Consulta los reportes históricos del Portal de Verificación de Nómina de Guatemala almacenados en Supabase, normaliza la información para el formato requerido por la aplicación y devuelve los registros al portal para su visualización y filtrado.", "active": true, "isArchived": false, "nodes": [ { "parameters": { "path": "cruce-cuentas-gt-historicos", "responseMode": "responseNode", "options": {} }, "type": "n8n-nodes-base.webhook", "typeVersion": 2.1, "position": [ -368, -16 ], "id": "47845bfd-64f5-47ec-89e6-c0faa317e08b", "name": "Webhook Históricos GT", "webhookId": "e92a1ebc-80e5-4afe-b38d-48a92c4b7fea" }, { "parameters": { "jsCode": "const items = $input.all();\n\nfunction formatDate(value) {\n if (!value) return '';\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return String(value).slice(0, 10);\n return date.toISOString().slice(0, 10);\n}\n\nfunction toNumber(value) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction normalizeStatus(value, discrepancias) {\n const status = String(value || '').toLowerCase();\n\n if (status === 'resuelto') return 'resuelto';\n if (status === 'procesado' && toNumber(discrepancias) === 0) return 'procesado';\n\n return 'pendiente_revision';\n}\n\nfunction statusLabel(status) {\n if (status === 'resuelto') return 'RESUELTO';\n if (status === 'procesado') return 'PROCESADO';\n return 'PENDIENTE REVISIÓN';\n}\n\nconst reports = items.map((item) => {\n const row = item.json || {};\n\n const discrepancias = toNumber(row.discrepancias);\n const bancoSinNomina = toNumber(row.banco_sin_nomina);\n const nominaSinCuenta = toNumber(row.nomina_sin_cuenta);\n const bancoSinBamboo = toNumber(row.banco_sin_bamboo);\n const nominaSinBamboo = toNumber(row.nomina_sin_bamboo);\n const bambooSinNomina = toNumber(row.bamboo_sin_nomina);\n\n const totalPendientes =\n discrepancias +\n bancoSinNomina +\n nominaSinCuenta +\n bancoSinBamboo +\n nominaSinBamboo +\n bambooSinNomina;\n\n const estado = normalizeStatus(row.estado, totalPendientes);\n\n return {\n id: row.id,\n\n fecha: formatDate(row.period_end || row.ejecutado_en || row.created_at),\n fechaEjecucion: row.ejecutado_en || row.created_at,\n\n periodo: row.period_label || '',\n year: row.year,\n month: row.month,\n periodType: row.period_type,\n periodStart: row.period_start,\n periodEnd: row.period_end,\n\n archivoNomina: row.payroll_file_name || '',\n archivosBanco: row.bank_file_names || [],\n\n coincidencias: toNumber(row.coincidencias),\n discrepancias,\n bancoSinNomina,\n nominaSinCuenta,\n bancoSinBamboo,\n nominaSinBamboo,\n bambooSinNomina,\n totalPendientes,\n\n totalNomina: toNumber(row.total_nomina),\n totalBanco: toNumber(row.total_banco),\n diferenciaTotal: toNumber(row.diferencia_total),\n\n estado,\n estadoLabel: statusLabel(estado),\n\n reportUrl: row.report_url || '',\n spreadsheetId: row.spreadsheet_id || '',\n\n ejecutadoPorNombre: row.ejecutado_por_nombre || '',\n ejecutadoPorEmail: row.ejecutado_por_email || '',\n\n resueltoPorNombre: row.resuelto_por_nombre || '',\n resueltoPorEmail: row.resuelto_por_email || '',\n resueltoEn: row.resuelto_en || null,\n comentarioResolucion: row.comentario_resolucion || '',\n };\n});\n\nreturn [\n {\n json: {\n ok: true,\n stage: 'historicos_gt_listos',\n count: reports.length,\n reports,\n },\n },\n];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 48, -16 ], "id": "0fb42965-9a23-42e1-bd82-152452dc54ed", "name": "Normalizar históricos para app" }, { "parameters": { "url": "https://dbit.digitalcompass.agency/rest/v1/cruces_cuentas_gt_reportes?select=*&order=ejecutado_en.desc&limit=100", "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" } ] }, "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ -160, -16 ], "id": "3b8cd950-a973-433e-82a1-fcd67bc9a483", "name": "Consultar históricos Supabase" }, { "parameters": { "respondWith": "json", "responseBody": "={{ $json }}", "options": { "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": [ 272, -16 ], "id": "31c2d67f-3989-4342-9be3-ed718fc63e79", "name": "Responder históricos app" } ], "connections": { "Webhook Históricos GT": { "main": [ [ { "node": "Consultar históricos Supabase", "type": "main", "index": 0 } ] ] }, "Consultar históricos Supabase": { "main": [ [ { "node": "Normalizar históricos para app", "type": "main", "index": 0 } ] ] }, "Normalizar históricos para app": { "main": [ [ { "node": "Responder históricos app", "type": "main", "index": 0 } ] ] } }, "settings": { "executionOrder": "v1", "binaryMode": "separate", "availableInMCP": true }, "staticData": null, "meta": null, "versionId": "be3117ab-887b-453d-a236-0e75d8c2818d", "activeVersionId": "be3117ab-887b-453d-a236-0e75d8c2818d", "versionCounter": 61, "triggerCount": 1, "shared": [ { "updatedAt": "2026-07-09T13:23:03.750Z", "createdAt": "2026-07-09T13:23:03.750Z", "role": "workflow:owner", "workflowId": "QDKFgvoJKviQbDl3", "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-09T13:50:34.000Z", "createdAt": "2026-07-09T13:50:28.749Z", "versionId": "be3117ab-887b-453d-a236-0e75d8c2818d", "workflowId": "QDKFgvoJKviQbDl3", "nodes": [ { "parameters": { "path": "cruce-cuentas-gt-historicos", "responseMode": "responseNode", "options": {} }, "type": "n8n-nodes-base.webhook", "typeVersion": 2.1, "position": [ -368, -16 ], "id": "47845bfd-64f5-47ec-89e6-c0faa317e08b", "name": "Webhook Históricos GT", "webhookId": "e92a1ebc-80e5-4afe-b38d-48a92c4b7fea" }, { "parameters": { "jsCode": "const items = $input.all();\n\nfunction formatDate(value) {\n if (!value) return '';\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return String(value).slice(0, 10);\n return date.toISOString().slice(0, 10);\n}\n\nfunction toNumber(value) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction normalizeStatus(value, discrepancias) {\n const status = String(value || '').toLowerCase();\n\n if (status === 'resuelto') return 'resuelto';\n if (status === 'procesado' && toNumber(discrepancias) === 0) return 'procesado';\n\n return 'pendiente_revision';\n}\n\nfunction statusLabel(status) {\n if (status === 'resuelto') return 'RESUELTO';\n if (status === 'procesado') return 'PROCESADO';\n return 'PENDIENTE REVISIÓN';\n}\n\nconst reports = items.map((item) => {\n const row = item.json || {};\n\n const discrepancias = toNumber(row.discrepancias);\n const bancoSinNomina = toNumber(row.banco_sin_nomina);\n const nominaSinCuenta = toNumber(row.nomina_sin_cuenta);\n const bancoSinBamboo = toNumber(row.banco_sin_bamboo);\n const nominaSinBamboo = toNumber(row.nomina_sin_bamboo);\n const bambooSinNomina = toNumber(row.bamboo_sin_nomina);\n\n const totalPendientes =\n discrepancias +\n bancoSinNomina +\n nominaSinCuenta +\n bancoSinBamboo +\n nominaSinBamboo +\n bambooSinNomina;\n\n const estado = normalizeStatus(row.estado, totalPendientes);\n\n return {\n id: row.id,\n\n fecha: formatDate(row.period_end || row.ejecutado_en || row.created_at),\n fechaEjecucion: row.ejecutado_en || row.created_at,\n\n periodo: row.period_label || '',\n year: row.year,\n month: row.month,\n periodType: row.period_type,\n periodStart: row.period_start,\n periodEnd: row.period_end,\n\n archivoNomina: row.payroll_file_name || '',\n archivosBanco: row.bank_file_names || [],\n\n coincidencias: toNumber(row.coincidencias),\n discrepancias,\n bancoSinNomina,\n nominaSinCuenta,\n bancoSinBamboo,\n nominaSinBamboo,\n bambooSinNomina,\n totalPendientes,\n\n totalNomina: toNumber(row.total_nomina),\n totalBanco: toNumber(row.total_banco),\n diferenciaTotal: toNumber(row.diferencia_total),\n\n estado,\n estadoLabel: statusLabel(estado),\n\n reportUrl: row.report_url || '',\n spreadsheetId: row.spreadsheet_id || '',\n\n ejecutadoPorNombre: row.ejecutado_por_nombre || '',\n ejecutadoPorEmail: row.ejecutado_por_email || '',\n\n resueltoPorNombre: row.resuelto_por_nombre || '',\n resueltoPorEmail: row.resuelto_por_email || '',\n resueltoEn: row.resuelto_en || null,\n comentarioResolucion: row.comentario_resolucion || '',\n };\n});\n\nreturn [\n {\n json: {\n ok: true,\n stage: 'historicos_gt_listos',\n count: reports.length,\n reports,\n },\n },\n];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 48, -16 ], "id": "0fb42965-9a23-42e1-bd82-152452dc54ed", "name": "Normalizar históricos para app" }, { "parameters": { "url": "https://dbit.digitalcompass.agency/rest/v1/cruces_cuentas_gt_reportes?select=*&order=ejecutado_en.desc&limit=100", "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" } ] }, "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ -160, -16 ], "id": "3b8cd950-a973-433e-82a1-fcd67bc9a483", "name": "Consultar históricos Supabase" }, { "parameters": { "respondWith": "json", "responseBody": "={{ $json }}", "options": { "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": [ 272, -16 ], "id": "31c2d67f-3989-4342-9be3-ed718fc63e79", "name": "Responder históricos app" } ], "connections": { "Webhook Históricos GT": { "main": [ [ { "node": "Consultar históricos Supabase", "type": "main", "index": 0 } ] ] }, "Consultar históricos Supabase": { "main": [ [ { "node": "Normalizar históricos para app", "type": "main", "index": 0 } ] ] }, "Normalizar históricos para app": { "main": [ [ { "node": "Responder históricos app", "type": "main", "index": 0 } ] ] } }, "authors": "Isaac Aracena", "name": "Version be3117ab", "description": "", "autosaved": true, "workflowPublishHistory": [ { "createdAt": "2026-07-09T13:50:34.232Z", "id": 2709, "workflowId": "QDKFgvoJKviQbDl3", "versionId": "be3117ab-887b-453d-a236-0e75d8c2818d", "event": "activated", "userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029" } ] } }