fix(auditoria completa): bloqueos de Mi Dia, cobranza (saldos y fechas), captura (departamento y rol), contactos (privacidad), cotizador (QR) y validaciones de API

This commit is contained in:
2026-09-21 07:18:39 +00:00
parent 75956a709f
commit 5e9b2ac456
16 changed files with 259 additions and 71 deletions

View File

@@ -374,11 +374,16 @@ export class CrmLocalService {
nombreLead: oportunidad.nombreLead,
telefono: oportunidad.telefono,
email: oportunidad.email,
origen: oportunidad.origen,
desarrollo: oportunidad.desarrollo,
modelo: oportunidad.modelo,
board: 'APARTADO',
etapa: 'Pago Apartado',
datosJson: oportunidad.datosJson,
// Fecha límite del apartado en la COLUMNA: la leen el KPI "Apartados
// por vencer", el cron de avisos y la lista de Mi día (antes sólo se
// calculaba en el JSON del alta y la columna quedaba vacía).
fechaLimite: fechaLimiteApartado(oportunidad.datosJson),
pendienteSync: true,
},
}),
@@ -445,7 +450,24 @@ export class CrmLocalService {
}
/** Singleton usado por los controllers (los tests instancian el suyo o mockean prisma) */
export const crmLocal = new CrmLocalService()/** Sólo dígitos de un teléfono (quita +52, espacios, guiones, paréntesis) */
export const crmLocal = new CrmLocalService()/** Fecha límite de un apartado: la del JSON si existe, si no hoy + 15 días */
function fechaLimiteApartado(datosJson: string | null): Date {
try {
const datos = datosJson ? (JSON.parse(datosJson) as Record<string, unknown>) : {}
const fecha = datos['fechaLimite']
if (typeof fecha === 'string' && fecha.trim() !== '') {
const d = new Date(fecha.length === 10 ? `${fecha}T00:00:00.000Z` : fecha)
if (!Number.isNaN(d.getTime())) return d
}
} catch {
/* JSON corrupto: se calcula por defecto */
}
const limite = new Date()
limite.setDate(limite.getDate() + 15)
return limite
}
/** Sólo dígitos de un teléfono (quita +52, espacios, guiones, paréntesis) */
function soloDigitos(telefono: string): string {
return telefono.replace(/\D/g, '')
}