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:
@@ -1,15 +1,19 @@
|
||||
import { useMemo, useState } from 'react'
|
||||
import type { Unidad, DescuentosPropuestas } from '../types'
|
||||
import type { Unidad, DescuentosPropuestas, ParametrosDesarrollo } from '../types'
|
||||
import {
|
||||
APARTADO_DEFAULT,
|
||||
DESCUENTOS_DEFAULT,
|
||||
calcularNumMensualidades,
|
||||
calcularPropuestas,
|
||||
obtenerPrecioLista,
|
||||
resolverNumMensualidades,
|
||||
type PropuestaResultado,
|
||||
} from '../lib/calculations'
|
||||
import { DESARROLLO_DEFAULT, descuentosDefault, obtenerDesarrollo } from '../data/desarrollos'
|
||||
|
||||
interface UseCotizacionResult {
|
||||
desarrollo: string
|
||||
/** Cambia de desarrollo: limpia la unidad elegida y reinicia los descuentos */
|
||||
setDesarrollo: (id: string) => void
|
||||
params: ParametrosDesarrollo
|
||||
unidad: Unidad | null
|
||||
setUnidad: (u: Unidad | null) => void
|
||||
acabados: boolean
|
||||
@@ -19,24 +23,34 @@ interface UseCotizacionResult {
|
||||
descuentos: DescuentosPropuestas
|
||||
setDescuento: (clave: keyof DescuentosPropuestas, valor: number) => void
|
||||
precioLista: number
|
||||
numMeses: number
|
||||
numMeses: number | null
|
||||
propuestas: PropuestaResultado[]
|
||||
}
|
||||
|
||||
/** Estado central de la cotización: unidad, acabados, apartado y descuentos */
|
||||
/** Estado central de la cotización: desarrollo, unidad, acabados, apartado y descuentos */
|
||||
export function useCotizacion(): UseCotizacionResult {
|
||||
const [desarrollo, setDesarrolloState] = useState<string>(DESARROLLO_DEFAULT)
|
||||
const [unidad, setUnidad] = useState<Unidad | null>(null)
|
||||
const [acabados, setAcabados] = useState(false)
|
||||
const [apartado, setApartado] = useState<number>(APARTADO_DEFAULT)
|
||||
const [descuentos, setDescuentos] = useState<DescuentosPropuestas>({ ...DESCUENTOS_DEFAULT })
|
||||
const [descuentos, setDescuentos] = useState<DescuentosPropuestas>(descuentosDefault(DESARROLLO_DEFAULT))
|
||||
|
||||
const params = obtenerDesarrollo(desarrollo)
|
||||
|
||||
const setDesarrollo = (id: string) => {
|
||||
setDesarrolloState(id)
|
||||
setUnidad(null)
|
||||
setAcabados(false)
|
||||
setDescuentos(descuentosDefault(id))
|
||||
}
|
||||
|
||||
const setDescuento = (clave: keyof DescuentosPropuestas, valor: number) => {
|
||||
setDescuentos((prev) => ({ ...prev, [clave]: valor }))
|
||||
}
|
||||
|
||||
const numMeses = useMemo(
|
||||
() => (unidad ? calcularNumMensualidades(unidad.fechaEntrega) : 0),
|
||||
[unidad],
|
||||
() => (unidad ? resolverNumMensualidades(unidad, params) : null),
|
||||
[unidad, params],
|
||||
)
|
||||
|
||||
const precioLista = useMemo(
|
||||
@@ -46,10 +60,13 @@ export function useCotizacion(): UseCotizacionResult {
|
||||
|
||||
const propuestas = useMemo(() => {
|
||||
if (!unidad) return []
|
||||
return calcularPropuestas({ unidad, acabados, apartado, descuentos })
|
||||
}, [unidad, acabados, apartado, descuentos])
|
||||
return calcularPropuestas({ unidad, acabados, apartado, descuentos, desarrollo })
|
||||
}, [unidad, acabados, apartado, descuentos, desarrollo])
|
||||
|
||||
return {
|
||||
desarrollo,
|
||||
setDesarrollo,
|
||||
params,
|
||||
unidad,
|
||||
setUnidad,
|
||||
acabados,
|
||||
|
||||
Reference in New Issue
Block a user