Appearance
Lista de Precios - Automatico por Rango - Documentacion Tecnica Frontend
DOCUMENTACION RETROSPECTIVA - Generada a partir de codigo implementado el 2026-02-09
Modulo: Ventas Feature: Lista de Precios - Automatico por Rango Fecha: 2026-02-09
Referencia de Negocio
Tecnologia Implementada
Stack: Legacy (PHP + Vanilla JavaScript + jQuery)
Esta funcionalidad esta implementada con el patron legacy del sistema:
- Vista PHP server-side rendered (
lista-precios-rango.php) - JavaScript vanilla con modulos ES6 (
lista-precios-rango.js) - jQuery DataTables para tabla de datos
- jQuery UI Autocomplete para busqueda de articulos
- SweetAlert2 para modales de interaccion y notificaciones
- Bootstrap 4 para layout y componentes visuales
- AdminLTE como framework de administracion
NO esta migrada a React/TypeScript.
Arquitectura de la Vista
Archivos Implementados
| Archivo | Tipo | Proposito |
|---|---|---|
view/mod-ventas/lista-precios-rango.php | Vista PHP | Template HTML con formulario y modal |
js/view/mod-ventas/lista-precios-rango.js | JavaScript ES6 Module | Logica de interaccion y comunicacion con API |
Punto de Entrada
- URL:
?loc=mvlpar - Registrada en
index.phpcasomvlpar - Ruta en sidebar: Ventas > Bases > Lista de precios > Automatico por rango
Componentes de la Vista
Formulario Principal (idFormListaPrecios)
Formulario HTML con los parametros de generacion.
Campos implementados:
| Campo | ID | Tipo | Estado | Descripcion |
|---|---|---|---|---|
| Lista origen | idInputOrigen | number | Activo | Numero de lista de precios de origen |
| Lista destino | idInputDestino | number | Activo | Numero de lista de precios destino |
| Origen (moneda) | idSelectOrigen | select | Deshabilitado | Opciones: $ / U$S |
| Destino (moneda) | idSelectDestino | select | Deshabilitado | Opciones: $ / U$S |
| Por codigo articulo | idInputCodigoProducto | radio | Deshabilitado | Opcion de tipo de codigo |
| Por codigo comercial | idInputCodigoComercial | radio | Deshabilitado | Opcion de tipo de codigo |
| % de Variacion | idInputPorcentajeVariacion | radio | Activo (checked) | Metodo de variacion seleccionado |
| Porcentaje | idInputPorcentaje | text | Activo | Valor del porcentaje a aplicar |
| Margenes por proveedor | idInputMargenes | radio | Deshabilitado | Opcion de variacion alternativa |
| Orden | idSelectOrden | select | Deshabilitado | Numerico / Alfabetico |
| Desde proveedor | idInputProveedorDesde | text | Deshabilitado | Filtro por proveedor (no implementado) |
| Hasta proveedor | idInputProveedorHasta | text | Deshabilitado | Filtro por proveedor (no implementado) |
| Desde agrupacion | selectAgrupacionDesde | select | Activo | Rubro inicio del rango |
| Hasta agrupacion | selectAgrupacionHasta | select | Activo | Rubro fin del rango |
| Desde linea | - | text | Deshabilitado | Filtro por linea (no implementado) |
| Hasta linea | - | text | Deshabilitado | Filtro por linea (no implementado) |
| Desde articulo | idInputProductoDesde | text | Activo | Primer articulo del rango (con autocomplete) |
| Hasta articulo | idInputProductoHasta | text | Activo | Ultimo articulo del rango (con autocomplete) |
Botones:
- "Aceptar" (
idBtnRegistrar): submit del formulario - "Cancelar": redirige a
?loc=mv(menu ventas)
Modal de Vista Previa (idModalListaPrecios)
Modal Bootstrap con la tabla de precios generados y formulario de confirmacion.
Elementos del modal:
| Elemento | ID | Tipo | Descripcion |
|---|---|---|---|
| Lista destino (readonly) | idInputListaDestino | number | Muestra el numero de lista destino |
| Codigo interno | idInputCodigoInterno | radio | Checked por defecto |
| Codigo comercial | idInputCodigoComercial | radio | Deshabilitado |
| Tabla de precios | tablaListaPrecios | DataTable | Muestra articulos con precios calculados |
Columnas de la tabla (DataTable):
| Columna | Titulo | Campo | Editable |
|---|---|---|---|
| 0 | Numero | id | No |
| 1 | Denominacion | nombre | No |
| 2 | Precio | precio | Si (clic para editar) |
State Management
Variables de Estado (JavaScript)
Objeto filtros:
{
proveedorDesde: null, // No implementado (siempre null)
proveedorHasta: null, // No implementado (siempre null)
rubroDesde: null, // ID primer rubro (cargado al inicializar)
rubroHasta: null, // ID ultimo rubro (cargado al inicializar)
}Objeto actualizacionLista:
{
productoDesde: null, // ID primer producto del rango
productoHasta: null, // ID ultimo producto del rango
origen: null, // Numero de lista de origen
destino: null, // Numero de lista de destino
porcentaje: null, // Porcentaje de variacion
}DataTable (tabla):
- Almacena temporalmente los productos con precios calculados
- Permite edicion inline de la columna precio
- Se limpia al cerrar el modal
Integracion con Backend
API Client
Usa clase legacy ApiRequest de js/middleware/API.js (no Axios moderno).
Endpoints Consumidos
| Metodo | Endpoint | Proposito | Momento |
|---|---|---|---|
| GET | /rubro | Obtener lista de agrupaciones/rubros | Inicializacion |
| GET | /producto | Obtener primer producto del rango | Inicializacion |
| GET | /producto | Obtener ultimo producto del rango | Inicializacion |
| GET | /producto | Busqueda con autocomplete (desde) | Interaccion usuario |
| GET | /producto | Busqueda con autocomplete (hasta) | Interaccion usuario |
| GET | /producto | Obtener productos con precios para vista previa | Submit formulario |
| POST | /lista-precio | Generar lista de precios en destino | Submit modal |
Detalle de Llamadas API
Inicializacion - Carga de rubros:
GET /rubro
Response: [{id, concepto}, ...]Inicializacion - Primer producto del rango:
GET /producto
Params: {first: true, scope: 'min', proveedor: null|[desde,hasta], rubro: [rubroDesde, rubroHasta]}
Response: {id, nombre}Inicializacion - Ultimo producto del rango:
GET /producto
Params: {last: true, scope: 'min', proveedor: null|[desde,hasta], rubro: [rubroDesde, rubroHasta]}
Response: {id, nombre}Autocomplete de productos:
GET /producto
Params: {filter: term, scope: 'min', proveedor: null|[desde,hasta], rubro: [rubroDesde, rubroHasta]}
Response: [{id, nombre}, ...]
Transform: -> [{label: "id | nombre", value: {id, nombre}}, ...]Vista previa de precios:
GET /producto
Params: {id: [productoDesde, productoHasta], lista: origen, scope: 'lista_precio'}
Response: [{id, nombre, precio}, ...]
Transform: precio = precio * (porcentaje / 100 + 1)Generacion de lista:
POST /lista-precio
Body: {
method: 'por_rango',
origen: number,
destino: number,
listas: [{id, nombre, precio}, ...] // Datos de la tabla DataTable
}
Response: 201 CreatedFlujos de UI
Flujo Principal: Generacion por Rango
mermaid
flowchart TD
A[Abrir vista lista-precios-rango] --> B[Cargar rubros y productos - IIFE]
B --> C[Usuario completa formulario]
C --> D{Submit formulario}
D --> E[GET /producto con scope lista_precio]
E --> F[Calcular precios con % variacion en JS]
F --> G[Mostrar modal con DataTable]
G --> H{Usuario revisa precios}
H -->|Editar precio| I[Clic en celda precio]
I --> J[modalInput - SweetAlert prompt]
J --> K[Actualizar celda en DataTable]
K --> H
H -->|Aceptar| L[POST /lista-precio method=por_rango]
L --> M[Mensaje exito]
M --> N[Cerrar modal]
H -->|Cancelar| N
N --> O[Limpiar tabla y volver al formulario]Flujo de Edicion Inline de Precio
- Usuario hace clic en una celda de la columna "Precio" (columna indice 2)
- Se obtiene el valor actual y la descripcion del producto
- Se muestra un prompt via
modalInput(SweetAlert) - Si el usuario ingresa un valor valido (numerico, no vacio):
- Se reemplaza la coma decimal por punto
- Se actualiza la celda en el DataTable
- Si el valor es invalido o se cancela, no se modifica
Estado de Carga
- Inicializacion:
showPopupLoading('info', 'Cargando datos')conSwal.close()al completar - Vista previa:
showPopupLoading('info', 'Cargando datos')antes de buscar productos - Generacion:
showPopupLoading('info', 'Generando lista de precios')durante POST
Manejo de Errores
- Lista invalida:
showModal('error', 'La lista especificada es invalida')en blur de inputs origen/destino - Exito:
showModal('success', 'Lista de precio generada')al completar generacion - No hay manejo explicito de errores de red o respuestas 4xx/5xx en el codigo JS analizado
Validaciones del Frontend
| Campo | Validacion | Momento | Tipo |
|---|---|---|---|
| Lista origen | HTML required + validacion JS (numerico >= 0) | blur | Estructural |
| Lista destino | HTML required + validacion JS (numerico >= 0) | blur | Estructural |
| Porcentaje | Input badge (badge type "P") | blur | Visual |
| Producto desde | HTML required + autocomplete | submit | Estructural |
| Producto hasta | HTML required + autocomplete | submit | Estructural |
| Precio editado | numerico, no vacio, no NaN | prompt | Estructural |
Routing
| URL | Vista | Permiso |
|---|---|---|
?loc=mvlpar | view/mod-ventas/lista-precios-rango.php | VENTAS_BASES_LISTA-PRECIO_RANGO |
Navegacion en sidebar:
- Nivel 1: Ventas (id:
idNavMainSideBarBases) - Nivel 2: Lista de precios (id:
idNavMainSideBarListaPrecios) - Nivel 3: Automatico por rango (id:
idMainSideBarListaPreciosAutomRango)
Dependencias de Plugins
| Plugin | Version | Uso |
|---|---|---|
| jQuery | Bundled | DOM manipulation, AJAX |
| Bootstrap 4 | Bundled | Layout, modales |
| AdminLTE | Bundled | Framework admin |
| jQuery DataTables | Bundled | Tabla interactiva |
| jQuery UI | Bundled | Autocomplete |
| SweetAlert2 | Bundled | Alertas y prompts |
Modulos JavaScript Importados
| Modulo | Ubicacion | Proposito |
|---|---|---|
ApiRequest | js/middleware/API.js | Comunicacion con backend (legacy) |
LANG_TABLE | js/util/constantes.js | Traduccion al espanol de DataTables |
createOption | js/util/input-functions.js | Crear opciones en selects dinamicamente |
setAutocomplete | js/util/inputs.js | Configurar autocompletado en inputs |
setInputBadge | js/util/inputs.js | Configurar badge visual en input porcentaje |
Funciones globales usadas (no importadas):
showPopupLoading()- Mostrar indicador de cargashowModal()- Mostrar alerta de resultadomodalInput()- Mostrar prompt para editar preciosetFormatoMoneda()- Formatear numero como monedaback()- Navegar a seccion anteriorSwal- Instancia global de SweetAlert2
Consideraciones de Migracion a React
Esta vista es candidata a migracion a React/TypeScript. Elementos a considerar:
- Reemplazo de DataTable: Usar componente de tabla React (ej: TanStack Table o tabla custom)
- Reemplazo de Autocomplete jQuery UI: Usar
ControlledAutoCompletedecore/components - Reemplazo de SweetAlert2: Usar sistema de modales y notificaciones de React
- Reemplazo de ApiRequest: Usar Axios con interceptores (
ts/api/api.ts) + TanStack Query - Estado: Migrar variables globales a useState/useReducer
- Validaciones: Implementar con Zod + React Hook Form
- Estructura propuesta:
ts/ventas/ListaPrecios/ ├── components/ │ ├── ListaPreciosRangoForm/ │ │ └── index.tsx │ ├── ListaPreciosPreviewTable/ │ │ └── index.tsx │ └── Modals/ │ └── PriceEditModal.tsx ├── views/ │ └── ListaPreciosRangoView.tsx ├── hooks/ │ └── useListaPreciosRango.ts ├── services/ │ └── listaPrecio.service.ts ├── schemas/ │ └── listaPrecioRango.schema.ts └── types/ └── listaPrecio.types.ts
Preguntas Tecnicas Pendientes
Aclaraciones Requeridas: Hay aspectos tecnicos que requieren validacion. Ver: Preguntas sobre Lista de Precios Rango
Referencias
NOTA IMPORTANTE: Esta documentacion fue generada automaticamente analizando el codigo implementado. Validar cambios futuros contra este baseline.