feat(pendientes): cotizador (mensualidades, bloqueo de unidad, totales, numMensualidades), cobranza (recibos, atrasos, mora configurable, recordatorios), soporte (adjuntos, filtros, estados), clientes maestro (catalogos reales), contactos (ficha y duplicados) y permisos de captura por rol
This commit is contained in:
@@ -344,8 +344,16 @@ export class CrmLocalService {
|
||||
* oportunidad pasan a apuntar al apartado para que sobrevivan al cambio de
|
||||
* board. Idempotente con el mismo dedup `apartado-creado:<opId>` de las
|
||||
* automatizaciones.
|
||||
*
|
||||
* `opciones.unidadCodigo` deja la unidad apartada en el `datosJson` del
|
||||
* apartado (la cotización del vendedor o la unidad de interés): es lo que
|
||||
* después leen el bloqueo de inventario y Mi día.
|
||||
*/
|
||||
async apartar(oportunidadIdLocal: string, usuarioId?: string) {
|
||||
async apartar(
|
||||
oportunidadIdLocal: string,
|
||||
usuarioId?: string,
|
||||
opciones: { unidadCodigo?: string | undefined } = {},
|
||||
) {
|
||||
// Sombra para ids heredados sin fila local
|
||||
const oportunidad = await this.filaLocal(
|
||||
oportunidadIdLocal,
|
||||
@@ -362,6 +370,7 @@ export class CrmLocalService {
|
||||
}
|
||||
|
||||
const apartadoId = idLocal()
|
||||
const datosJson = conUnidadCodigo(oportunidad.datosJson, opciones.unidadCodigo)
|
||||
const resultados = await prisma.$transaction([
|
||||
prisma.leadCaptura.update({
|
||||
where: { leadId: oportunidadIdLocal },
|
||||
@@ -379,11 +388,11 @@ export class CrmLocalService {
|
||||
modelo: oportunidad.modelo,
|
||||
board: 'APARTADO',
|
||||
etapa: 'Pago Apartado',
|
||||
datosJson: oportunidad.datosJson,
|
||||
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),
|
||||
fechaLimite: fechaLimiteApartado(datosJson),
|
||||
pendienteSync: true,
|
||||
},
|
||||
}),
|
||||
@@ -472,6 +481,25 @@ function soloDigitos(telefono: string): string {
|
||||
return telefono.replace(/\D/g, '')
|
||||
}
|
||||
|
||||
/**
|
||||
* `datosJson` con la unidad apartada dentro (mezcla, no reemplaza: conserva
|
||||
* fechaCita, fechaLimite y el perfilamiento de la captura). Sin unidadCodigo
|
||||
* devuelve el JSON original tal cual.
|
||||
*/
|
||||
function conUnidadCodigo(datosJson: string | null, unidadCodigo?: string): string | null {
|
||||
const unidad = unidadCodigo?.trim()
|
||||
if (!unidad) return datosJson
|
||||
let datos: Record<string, unknown> = {}
|
||||
if (datosJson) {
|
||||
try {
|
||||
datos = JSON.parse(datosJson) as Record<string, unknown>
|
||||
} catch {
|
||||
datos = {}
|
||||
}
|
||||
}
|
||||
return JSON.stringify({ ...datos, unidadCodigo: unidad })
|
||||
}
|
||||
|
||||
/**
|
||||
* Busca un contacto por teléfono (últimos 10 dígitos) en CUALQUIER tablero.
|
||||
* Así el mismo número no se duplica entre Leads, Oportunidades y Apartados.
|
||||
|
||||
Reference in New Issue
Block a user