feat(cotizador): multi-desarrollo — ATELIER, ESTANZA, SENDA, SOLANA + DIAGONAL

- Motor de cálculo parametrizado por desarrollo (enganches, descuentos, splits,
  fuente de N, quirk Infonavit-lista); DIAGONAL byte-idéntico
- 285 unidades (5 desarrollos) en seeds, API (?desarrollo=) y board Monday
- Selector de desarrollo en UI, propuestas por config, PDF multi-desarrollo
- Knowledge IA: catálogo por desarrollo + matriz de diferencias (10 docs)
- Tests: cotizador 53, api 99 — fixtures de los Excel validados al centavo
This commit is contained in:
2026-08-22 04:31:21 +00:00
parent 05c44478ec
commit afb454b54c
33 changed files with 2074 additions and 338 deletions

View File

@@ -254,17 +254,23 @@ export class MondayService {
return Number.isFinite(n) ? n : 0
}
const status = textoDe('Disponibilidad').toUpperCase()
// La columna "Meses para firma" es opcional (solo la usa SOLANA)
const colMeses = cols.get('Meses para firma')
const mesesTexto = colMeses ? (porId.get(colMeses.id)?.text ?? '') : ''
const mesesNum = Number(mesesTexto)
return {
codigo: item.name,
modelo: textoDe('Modelo'),
fechaEntrega: textoDe('Fecha entrega'),
fechaEntrega: textoDe('Fecha entrega') || null,
supEstacionamiento: numeroDe('Sup. estacionamiento'),
supConstruccion: numeroDe('Sup. construcción'),
supExcedente: numeroDe('Sup. excedente'),
precioSinAcabados: numeroDe('Precio sin acabados'),
precioConAcabados: numeroDe('Precio con acabados'),
status: status === 'APARTADA' || status === 'VENDIDA' ? status : 'DISPONIBLE',
// Se conserva el status real del board (VENDIDO, ESCRITURADO, BLOQUEADO, ...)
status: status || 'DISPONIBLE',
desarrollo: textoDe('Desarrollo'),
mesesParaFirma: mesesTexto !== '' && Number.isFinite(mesesNum) ? mesesNum : null,
}
}