Skip to content

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

ArchivoTipoProposito
view/mod-ventas/lista-precios-rango.phpVista PHPTemplate HTML con formulario y modal
js/view/mod-ventas/lista-precios-rango.jsJavaScript ES6 ModuleLogica de interaccion y comunicacion con API

Punto de Entrada

  • URL: ?loc=mvlpar
  • Registrada en index.php caso mvlpar
  • 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:

CampoIDTipoEstadoDescripcion
Lista origenidInputOrigennumberActivoNumero de lista de precios de origen
Lista destinoidInputDestinonumberActivoNumero de lista de precios destino
Origen (moneda)idSelectOrigenselectDeshabilitadoOpciones: $ / U$S
Destino (moneda)idSelectDestinoselectDeshabilitadoOpciones: $ / U$S
Por codigo articuloidInputCodigoProductoradioDeshabilitadoOpcion de tipo de codigo
Por codigo comercialidInputCodigoComercialradioDeshabilitadoOpcion de tipo de codigo
% de VariacionidInputPorcentajeVariacionradioActivo (checked)Metodo de variacion seleccionado
PorcentajeidInputPorcentajetextActivoValor del porcentaje a aplicar
Margenes por proveedoridInputMargenesradioDeshabilitadoOpcion de variacion alternativa
OrdenidSelectOrdenselectDeshabilitadoNumerico / Alfabetico
Desde proveedoridInputProveedorDesdetextDeshabilitadoFiltro por proveedor (no implementado)
Hasta proveedoridInputProveedorHastatextDeshabilitadoFiltro por proveedor (no implementado)
Desde agrupacionselectAgrupacionDesdeselectActivoRubro inicio del rango
Hasta agrupacionselectAgrupacionHastaselectActivoRubro fin del rango
Desde linea-textDeshabilitadoFiltro por linea (no implementado)
Hasta linea-textDeshabilitadoFiltro por linea (no implementado)
Desde articuloidInputProductoDesdetextActivoPrimer articulo del rango (con autocomplete)
Hasta articuloidInputProductoHastatextActivoUltimo articulo del rango (con autocomplete)

Botones:

  • "Aceptar" (idBtnRegistrar): submit del formulario
  • "Cancelar": redirige a ?loc=mv (menu ventas)

Modal Bootstrap con la tabla de precios generados y formulario de confirmacion.

Elementos del modal:

ElementoIDTipoDescripcion
Lista destino (readonly)idInputListaDestinonumberMuestra el numero de lista destino
Codigo internoidInputCodigoInternoradioChecked por defecto
Codigo comercialidInputCodigoComercialradioDeshabilitado
Tabla de preciostablaListaPreciosDataTableMuestra articulos con precios calculados

Columnas de la tabla (DataTable):

ColumnaTituloCampoEditable
0NumeroidNo
1DenominacionnombreNo
2PrecioprecioSi (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

MetodoEndpointPropositoMomento
GET/rubroObtener lista de agrupaciones/rubrosInicializacion
GET/productoObtener primer producto del rangoInicializacion
GET/productoObtener ultimo producto del rangoInicializacion
GET/productoBusqueda con autocomplete (desde)Interaccion usuario
GET/productoBusqueda con autocomplete (hasta)Interaccion usuario
GET/productoObtener productos con precios para vista previaSubmit formulario
POST/lista-precioGenerar lista de precios en destinoSubmit 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 Created

Flujos 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

  1. Usuario hace clic en una celda de la columna "Precio" (columna indice 2)
  2. Se obtiene el valor actual y la descripcion del producto
  3. Se muestra un prompt via modalInput (SweetAlert)
  4. Si el usuario ingresa un valor valido (numerico, no vacio):
    • Se reemplaza la coma decimal por punto
    • Se actualiza la celda en el DataTable
  5. Si el valor es invalido o se cancela, no se modifica

Estado de Carga

  • Inicializacion: showPopupLoading('info', 'Cargando datos') con Swal.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

CampoValidacionMomentoTipo
Lista origenHTML required + validacion JS (numerico >= 0)blurEstructural
Lista destinoHTML required + validacion JS (numerico >= 0)blurEstructural
PorcentajeInput badge (badge type "P")blurVisual
Producto desdeHTML required + autocompletesubmitEstructural
Producto hastaHTML required + autocompletesubmitEstructural
Precio editadonumerico, no vacio, no NaNpromptEstructural

Routing

URLVistaPermiso
?loc=mvlparview/mod-ventas/lista-precios-rango.phpVENTAS_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

PluginVersionUso
jQueryBundledDOM manipulation, AJAX
Bootstrap 4BundledLayout, modales
AdminLTEBundledFramework admin
jQuery DataTablesBundledTabla interactiva
jQuery UIBundledAutocomplete
SweetAlert2BundledAlertas y prompts

Modulos JavaScript Importados

ModuloUbicacionProposito
ApiRequestjs/middleware/API.jsComunicacion con backend (legacy)
LANG_TABLEjs/util/constantes.jsTraduccion al espanol de DataTables
createOptionjs/util/input-functions.jsCrear opciones en selects dinamicamente
setAutocompletejs/util/inputs.jsConfigurar autocompletado en inputs
setInputBadgejs/util/inputs.jsConfigurar badge visual en input porcentaje

Funciones globales usadas (no importadas):

  • showPopupLoading() - Mostrar indicador de carga
  • showModal() - Mostrar alerta de resultado
  • modalInput() - Mostrar prompt para editar precio
  • setFormatoMoneda() - Formatear numero como moneda
  • back() - Navegar a seccion anterior
  • Swal - Instancia global de SweetAlert2

Consideraciones de Migracion a React

Esta vista es candidata a migracion a React/TypeScript. Elementos a considerar:

  1. Reemplazo de DataTable: Usar componente de tabla React (ej: TanStack Table o tabla custom)
  2. Reemplazo de Autocomplete jQuery UI: Usar ControlledAutoComplete de core/components
  3. Reemplazo de SweetAlert2: Usar sistema de modales y notificaciones de React
  4. Reemplazo de ApiRequest: Usar Axios con interceptores (ts/api/api.ts) + TanStack Query
  5. Estado: Migrar variables globales a useState/useReducer
  6. Validaciones: Implementar con Zod + React Hook Form
  7. 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.