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:
2026-09-21 08:34:53 +00:00
parent b5a20aed4e
commit 2fc80e7f9e
66 changed files with 3792 additions and 436 deletions

View File

@@ -23,18 +23,24 @@ interface Fila {
/**
* Comparador de 2 unidades (del mismo o distinto desarrollo), lado a lado,
* con la propuesta activa calculada por el motor con los parámetros de cada
* desarrollo.
* desarrollo. Solo ofrece unidades DISPONIBLES: no se compara (ni se cotiza)
* inventario apartado, vendido o bloqueado.
*/
export function ComparadorUnidades({ unidades, tipo, apartado, acabados }: Props) {
const [abierto, setAbierto] = useState(false)
const [codigoA, setCodigoA] = useState('')
const [codigoB, setCodigoB] = useState('')
const disponibles = useMemo(
() => unidades.filter((u) => (u.status ?? '').trim().toUpperCase() === 'DISPONIBLE'),
[unidades],
)
const porCodigo = useMemo(() => {
const m = new Map<string, Unidad>()
for (const u of unidades) m.set(`${u.desarrollo ?? 'DIAGONAL'}|${u.codigo}`, u)
for (const u of disponibles) m.set(`${u.desarrollo ?? 'DIAGONAL'}|${u.codigo}`, u)
return m
}, [unidades])
}, [disponibles])
const unidadA = porCodigo.get(codigoA) ?? null
const unidadB = porCodigo.get(codigoB) ?? null
@@ -82,7 +88,7 @@ export function ComparadorUnidades({ unidades, tipo, apartado, acabados }: Props
>
<option value="">Selecciona una unidad…</option>
{LISTA_DESARROLLOS.map((dev) => {
const delDesarrollo = unidades.filter((u) => (u.desarrollo ?? 'DIAGONAL') === dev)
const delDesarrollo = disponibles.filter((u) => (u.desarrollo ?? 'DIAGONAL') === dev)
if (delDesarrollo.length === 0) return null
return (
<optgroup key={dev} label={obtenerDesarrollo(dev).nombre}>
@@ -172,8 +178,8 @@ export function ComparadorUnidades({ unidades, tipo, apartado, acabados }: Props
</tbody>
</table>
<p className="mt-6 text-xs text-[#64748B] dark:text-[#94A3B8]">
Cada unidad se calcula con los parámetros de su desarrollo y el mismo apartado.
El enganche ya incluye la deducción del apartado.
Solo se ofrecen unidades DISPONIBLES. Cada unidad se calcula con los parámetros de
su desarrollo y el mismo apartado. El enganche ya incluye la deducción del apartado.
</p>
</div>
)}