Middleware de Sincronización SINCO → Zoho CRM
Esta aplicación es un middleware: extrae información del ERP inmobiliario SINCO y la registra en Zoho CRM. Hoy automatiza tres cosas: mantener actualizados los tokens de acceso a SINCO, llevar los planes de pago y los trámites de cada negocio cerrado a los módulos Plan de Pagos y Trámites de Zoho, y actualizar los campos de escrituración directamente en el Deal.
Estos tres procesos corren solo para un listado confirmado de proyectos (ver sección 2) — negocios fuera de esa lista no se tocan. La sincronización corre automáticamente todos los días, y además puede dispararse a mano: por proyecto desde esta plataforma, o por negocio individual con un botón en el Deal de Zoho.
Procesos y cuándo se ejecutan
Resumen de todo lo que hace la plataforma.
| Proceso | Cuándo | Disparador |
|---|---|---|
| Sincronización de tokens | Todos los días a las 08:03 (hora Colombia) | Automático |
| Sincronización diaria de planes, trámites y escrituración | Todos los días a las 13:00 (hora Colombia) | Automático |
| Actualización de conteos | A las 13:00 (dentro de la sync) o bajo demanda | Automático Manual · Proyectos |
| Sincronización por proyecto | Bajo demanda | Manual · Proyectos |
| Sincronización por negocio | Bajo demanda | Manual · Botón en Zoho |
1. Sincronización de tokens de SINCO
Cómo la plataforma obtiene permiso para leer SINCO.
Para consultar SINCO se necesita un token de seguridad (JWT) por cada sociedad. Esos tokens viven en el módulo Sincronizaciones de Zoho (campo «Token Final») y Zoho los regenera todos los días a las 08:00. La plataforma los copia a su base de datos a las 08:03 — tres minutos después, para dar margen a que Zoho termine de regenerarlos y nunca leer un token a medio actualizar.
Cada token es válido desde las 08:00 hasta la medianoche de ese mismo día (unas 16 horas). Por eso la sincronización diaria de negocios corre en la tarde — mientras el token del día sigue vigente — y nunca de madrugada, cuando ya habría expirado.
2. Sincronización de planes de pago
El proceso principal: del negocio cerrado en SINCO al módulo Plan de Pagos.
Condición de entrada
Un Deal se sincroniza (por cualquier vía: automática, por proyecto o por el botón individual) solo si cumple ambas condiciones:
- 1Su fase es Cierre de negocio.
- 2Su Proyecto de interés está en la lista de proyectos confirmados por el cliente (15 proyectos, ~67 torres exactas — ver
lib/sync/allowed-projects.ts).
No hay filtro de año: se sincroniza el histórico completo de negocios en «Cierre de negocio» que pertenezcan a un proyecto de la lista. Un Deal fuera de la lista no se sincroniza en absoluto — ni planes de pago, ni trámites, ni escrituración — por ninguna de las tres vías (automática, por proyecto, ni por el botón). Esta restricción se revisa antes de consultar SINCO o Zoho, así que un negocio fuera de alcance no genera ningún llamado a esos sistemas.
Cómo se decide con qué token consultar
Cada negocio pertenece a una sociedad distinta, y cada sociedad tiene su propio token. La plataforma resuelve el token correcto siguiendo esta cadena automáticamente:
- 1Toma el Número de documento del comprador en el Deal.
- 2Sigue el campo «Proyecto de interés Sincroniza macro proyectos» del Deal.
- 3De ahí obtiene la Sociedad (módulo Sincroniza MacroProyectos).
- 4Con la Sociedad encuentra su Token Final en el módulo Sincronizaciones.
- 5Usa ese token para consultar SINCO por el número de documento.
Qué se consulta en SINCO
El servicio NegociosComprador (GET /Ventas/NumeroIdentificacion/{documento}) devuelve toda la información de ventas del comprador: proyectos, unidades y el plan de pagos con todas sus cuotas.
Qué cuotas se sincronizan
Para un negocio dentro de alcance (ver «Condición de entrada»), se sincronizan todas las cuotas del plan de pagos, incluyendo las que todavía no tienen mora ni pagos aplicados. Antes solo se traían las cuotas con movimiento (mora, pago o fecha de último pago); ese filtro se quitó — el cliente pidió el histórico completo, incluyendo cartera en cero, para los proyectos confirmados.
Qué módulo y qué campos se actualizan
Cada cuota se crea en el módulo Plan de Pagos de Zoho, enlazada al Deal correspondiente:
| Campo en Zoho (Plan de Pagos) | Dato de SINCO |
|---|---|
| Nombre del Concepto | concepto (ej. «Cuota 1», «Separación 1») |
| Tipo de Concepto | tipoConceptoPlanPago |
| Valor Pactado | valorPactado |
| Valor Pagado | valorPagado |
| Saldo Pendiente | saldo |
| Fecha Pactada de Pago | fechaPactada |
| Fecha del Último Pago | fechaUltimoPago |
| Días de Mora | diasMora |
| Oportunidades (enlace) | El Deal del comprador |
Trámites del negocio
La misma consulta a SINCO también trae los trámites del negocio (orden de separación, escrituración, etc.). Se sincronizan todos los trámites, cumplidos o pendientes — antes solo se traían los que ya tenían fechaCumplimiento, ese filtro también se quitó. Cada uno se crea en el módulo Trámites, enlazado al negocio por el campo «Oportunidad».
| Campo en Zoho (Trámites) | Dato de SINCO |
|---|---|
| Código | codigo |
| Nombre | nombre |
| Fecha Compromiso | fechaCompromiso |
| Fecha Cumplimiento | fechaCumplimiento |
| Observación Compromiso | observacionCompromiso |
| Observación Cumplimiento | observacionCumplimiento |
| Oportunidad (enlace) | El Deal del comprador |
3. Sincronización de escrituración
Actualiza directamente el Deal con el estado del proceso de escrituración.
Corre en la misma consulta a SINCO que planes de pago y trámites (no hace un llamado adicional), para todo negocio dentro de alcance — incluso si ese negocio no tiene cuotas ni trámites nuevos para sincronizar.
A diferencia de Plan de Pagos y Trámites (que crean registros nuevos), escrituración actualiza el Deal mismo: compara el valor derivado de SINCO contra el valor actual en Zoho, y solo envía el campo si cambió y el dato de SINCO no está vacío — nunca borra un valor existente en Zoho con un dato vacío de SINCO. Volver a correr la sincronización con los mismos datos de SINCO no hace nada (no hay cambios que enviar).
Campos que se actualizan
| Campo en Zoho (Deal) | Origen |
|---|---|
| Número de Escritura | escrituraNumero de la agrupación |
| Estado Escritura | Derivado de los trámites (ver abajo) |
| Fecha Compromiso Firma | Trámite ES4 · fechaCompromiso |
| Fecha Firma Real | Trámite ES4 · fechaCumplimiento |
| Fecha Entrega Escritura | Trámite ES14 · fechaCumplimiento |
Notaría (pendiente): no se sincroniza el nombre de la notaría — el campo correspondiente todavía no existe en el módulo Deals de Zoho. Cuando CRM lo cree, se puede agregar sin cambios de diseño.
Cómo se calcula el Estado de Escritura
Se evalúa el trámite cumplido de mayor prioridad, de arriba hacia abajo:
| Trámite cumplido | Estado resultante |
|---|---|
| ES14 | Lista para retiro |
| SU12 | Escritura registrada |
| SU11 | En registro |
| ES4 | Firmada por cliente |
| ES2 | Próxima a escriturar |
| (ninguno cumplido) | Sin iniciar |
Un comprador, varios proyectos
Un mismo comprador puede tener negocios en varios proyectos/torres. La plataforma identifica cuál de las «agrupaciones» que devuelve SINCO corresponde a este Deal comparando el nombre de proyecto exacto. Si no hay una coincidencia exacta y única, la escrituración de ese Deal se omite y queda registrada para revisión manual — nunca adivina cuál agrupación usar.
4. Automatización diaria
La sincronización de negocios corre sola todas las tardes, sin intervención.
Todos los días la plataforma sincroniza automáticamente los proyectos confirmados (planes de pago, trámites y escrituración juntos). El orden responde a la vigencia del token:
| Hora (Colombia) | Qué ocurre |
|---|---|
| 08:03 | Se copian los tokens del día desde Zoho. |
| 13:00 | Se actualizan los conteos y se encola la sincronización de los proyectos confirmados. |
| 13:00 – 23:00 | Se procesa la cola proyecto por proyecto, reintentando los que fallen, hasta terminar. |
¿Por qué no en la mañana? El token de SINCO solo vive hasta la medianoche. Corriendo desde las 13:00 se usa el token del día (aún vigente) y todo queda listo antes de que el equipo comercial ingrese a las 07:00 del día siguiente. La cola es persistente: si el servidor se reinicia, retoma donde quedó sin duplicar nada.
5. Sincronización manual por negocio (botón en Zoho)
Un botón en el Deal para sincronizar un solo negocio al instante.
Además de la corrida automática, el equipo puede sincronizar un negocio puntual sin esperar a la tarde. Se coloca un botón en el Deal de Zoho; al presionarlo, Zoho envía el número de documento del comprador a la plataforma, que consulta SINCO y sincroniza sus cuotas, trámites y escrituración — con las mismas reglas que la corrida automática (misma condición de entrada, mismos módulos) y sin duplicar lo que ya exista.
El endpoint (webhook)
| Método y URL | POST /api/webhooks/sync-deal |
| Autenticación | Secreto compartido CRON_SECRET, como ?secret=… en la URL o cabecera Authorization: Bearer …. |
| Parámetros | documento (obligatorio) · dealId (opcional, recomendado). |
| Respuesta | JSON con el resultado: cuotas y trámites creados / omitidos. |
Recomendación: enviar también el dealId. Un mismo documento puede tener varios negocios; con el dealId se sincroniza exactamente ese. Sin él, se sincronizan todos los negocios en «Cierre de negocio» que compartan ese documento.
Modelo de la función Deluge (botón en Zoho)
Se crea una función personalizada enlazada al botón del Deal. Reemplazar TU-DOMINIO y TU_CRON_SECRET por los valores reales del entorno:
// Función personalizada de Deluge, enlazada al botón del Deal.
// 'deal' es el registro del negocio sobre el que se presiona el botón.
payload = Map();
payload.put("documento", deal.get("N_mero_de_documento"));
payload.put("dealId", deal.get("id"));
response = invokeurl
[
url: "https://TU-DOMINIO/api/webhooks/sync-deal?secret=TU_CRON_SECRET"
type: POST
content-type: "application/json"
parameters: payload.toString()
];
info response; // { "ok": true, "paymentsCreated": 3, "tramitesCreated": 1, ... }Alternativa de autenticación por cabecera (en vez de ?secret= en la URL):
response = invokeurl
[
url: "https://TU-DOMINIO/api/webhooks/sync-deal"
type: POST
content-type: "application/json"
headers: {"Authorization": "Bearer TU_CRON_SECRET"}
parameters: payload.toString()
];Cada ejecución del botón queda registrada en Logs como una corrida con origen webhook, igual que las automáticas.
6. Cómo se evita duplicar información
Cómo sabe la plataforma que un dato ya fue sincronizado.
Cada cuota se identifica de forma única por la combinación Negocio + Concepto (por ejemplo, «Deal 12345 + Cuota 3»); cada trámite, por Negocio + Código. La plataforma lleva un registro propio de todo lo que ya creó en Zoho.
Importante (Plan de Pagos y Trámites): el comportamiento es crear o conservar. Si una cuota ya existe y sus datos cambiaron en SINCO (por ejemplo, un nuevo pago o más días de mora), hoy no se actualiza. La actualización de cuotas existentes está prevista como un paso siguiente.
Escrituración es distinta: como actualiza el Deal directamente en vez de crear registros nuevos, sí se actualiza cuando el dato cambia en SINCO — no necesita el mecanismo de «crear o conservar» de arriba. Ver sección 3.
7. Registro y auditoría (Logs)
Toda operación queda registrada con fecha y hora.
Cada proceso — sincronización de tokens, actualización de conteos y sincronización de planes de pago — escribe en un registro central. La sección Logs permite ver, por ejemplo, que «el proyecto X sincronizó 30 cuotas, 3 fallaron porque el documento no estaba en SINCO», con su fecha y hora exactas.
Anexo técnico
Módulos de Zoho involucrados y origen de los datos.
| Módulo de Zoho | Rol en la plataforma |
|---|---|
| Sincronizaciones | Guarda el Token Final por sociedad. |
| Deals (Negocios) | Origen: documento del comprador y fase del negocio. |
| Sincroniza MacroProyectos | Vincula el proyecto del Deal con su sociedad. |
| Proyectos Inmobiliarios | Agrupa los negocios por proyecto de interés. |
| Plan de Pagos | Destino: todas las cuotas sincronizadas desde SINCO. |
| Trámites | Destino: todos los trámites sincronizados desde SINCO. |
| Deals (Negocios) | También destino: los 5 campos de escrituración se actualizan (PATCH) directamente aquí. |
Despliegue. La plataforma se ejecuta en Docker (Dokploy): un contenedor web (interfaz + webhook) y un contenedor worker que ejecuta las tareas automáticas (tokens 08:03 y sincronización 13:00). El detalle técnico está en DEPLOY.md del repositorio.