Modulo nuevo (solo admin) para dar de alta desarrollos sin tocar codigo: - CRUD de la ficha, modelos e inventario (alta manual y generador por rango) - Reglas del cotizador por desarrollo, editables y persistidas en la BD - El cotizador consume las reglas desde /desarrollos/reglas-cotizador y cae a las constantes con aviso cuando un desarrollo aun no tiene reglas guardadas - Micrositio publico en /d/:clave (sin sesion) con ficha, modelos y disponibilidad; jamas expone datos de clientes ni cotizaciones Integracion: - La landing monta el modulo en el grid (clave 'desarrollos', solo admin) y el micrositio fuera del login; el rol manager NO accede (matriz y API con 403) - La tabla de roles de Configuracion ahora lista todos los modulos - Se alinea la FK de ReglaCotizadorDesarrollo con la BD viva (Desarrollo.id) Verificado: 708 pruebas del API, 115 del cotizador y 89 de la landing en verde; 12/12 cotizaciones identicas antes y despues del cambio de reglas; prueba en vivo del API con alta, modelos, inventario, reglas, micrositio y baja (30/30).
47 lines
1.8 KiB
TypeScript
47 lines
1.8 KiB
TypeScript
/**
|
|
* Numeración de unidades: el patrón admite `{clave}` (clave del desarrollo) y
|
|
* `{n}` (número consecutivo del rango).
|
|
*/
|
|
|
|
export const MAX_UNIDADES_GENERADOR = 1000
|
|
|
|
export function aplicarPatron(patron: string, clave: string, n: number): string {
|
|
return patron.split('{clave}').join(clave).split('{n}').join(String(n))
|
|
}
|
|
|
|
/** Primeros `max` códigos del rango (vista previa antes de confirmar) */
|
|
export function generarCodigos(
|
|
patron: string,
|
|
clave: string,
|
|
desde: number,
|
|
hasta: number,
|
|
max = 5,
|
|
): string[] {
|
|
if (!patron.includes('{n}') || !Number.isInteger(desde) || !Number.isInteger(hasta) || hasta < desde) {
|
|
return []
|
|
}
|
|
const cantidad = Math.min(hasta - desde + 1, Math.max(0, max))
|
|
return Array.from({ length: cantidad }, (_, i) => aplicarPatron(patron, clave, desde + i))
|
|
}
|
|
|
|
/** Total de unidades que crearía el generador con el rango actual */
|
|
export function totalDelRango(desde: number, hasta: number): number {
|
|
if (!Number.isInteger(desde) || !Number.isInteger(hasta) || hasta < desde) return 0
|
|
return hasta - desde + 1
|
|
}
|
|
|
|
/** Devuelve el mensaje de error del generador o null si todo está bien */
|
|
export function validarGenerador(patron: string, desde: number, hasta: number): string | null {
|
|
if (patron.trim() === '') return 'Escribe el patrón de código de la unidad.'
|
|
if (!patron.includes('{n}')) return 'El patrón debe incluir {n} para numerar las unidades.'
|
|
if (/[^A-Za-z0-9{}_-]/.test(patron)) {
|
|
return 'El patrón solo admite letras, números, guiones, {clave} y {n}.'
|
|
}
|
|
if (!Number.isInteger(desde) || !Number.isInteger(hasta)) return 'El rango debe usar números enteros.'
|
|
if (hasta < desde) return 'El valor "hasta" debe ser mayor o igual que "desde".'
|
|
if (hasta - desde + 1 > MAX_UNIDADES_GENERADOR) {
|
|
return `El rango no puede superar ${MAX_UNIDADES_GENERADOR} unidades por vez.`
|
|
}
|
|
return null
|
|
}
|