Skip to content

Vendedores - Documentacion Tecnica Frontend

DOCUMENTACION RETROSPECTIVA - Generada a partir de codigo implementado el 2026-02-09

Modulo: Ventas Feature: Vendedores (ABM + Informe) Fecha: 2026-02-09


Documento de Negocio


Arquitectura Frontend Implementada

Tipo de implementacion: Legacy (vanilla JavaScript + PHP templates)

La funcionalidad de vendedores esta implementada completamente con tecnologia legacy:

  • Vistas PHP con AdminLTE
  • JavaScript vanilla con modulos ES6
  • jQuery + DataTables para el listado
  • jQuery UI para autocompletes
  • Bootstrap 4 modals para formularios
  • API.js (clase legacy) para comunicacion con backend

No hay componentes React para el ABM de vendedores. Existe un hook parcial en React (useVendedorData.ts) para consumo desde otros modulos.


Vistas Implementadas

1. Vista Principal - Manejo de Vendedores

Ubicacion: view/mod-ventas/vendedores.phpJavaScript: js/view/mod-ventas/vendedores.jsURL: ?loc=mvv

Componentes de la vista:

  • Header con titulo "Manejo de Vendedores" y boton "Nvo. Vendedor | Alt+A"
  • Breadcrumb: Home > Ventas > Vendedores
  • Tabla DataTables (#tablaVendedores) con columnas: Codigo, Descripcion, Acciones
  • Sidebar del modulo ventas con item "Vendedores" activo bajo "Bases"

Funcionalidad JavaScript (vendedores.js):

FuncionDescripcion
Inicializacion DataTableConfiguracion de tabla con columnas cven, nombre, acciones
GET 'ordven'Carga inicial de todos los vendedores
Click #idBtnConsultarVendedorAbre formulario en modo consulta (sin callback)
Click #idBtnmodificarVendedorAbre formulario en modo edicion (con callback para actualizar fila)
Click #idBtnEliminarVendedorConfirmacion + DELETE + refresco de tabla
Click #btn_altaAbre formulario en modo alta (con callback para agregar fila)

Patron de acciones en tabla: Cada fila tiene 3 botones:

  • Consultar (verde, icono ojo): createFormVendedor({ updateData }) sin callback
  • Modificar (amarillo, icono lapiz): createFormVendedor({ updateData, onSubmitCallback }) con callback
  • Eliminar (rojo, icono basura): Confirmacion SweetAlert + request.delete('ordven', { cven })

Exportacion: Botones DataTables para Excel y PDF integrados.


2. Formulario de Vendedor (Modal)

Template HTML: php/components/mod-venta/forms/vendedor.htmlJavaScript: js/components/forms/ventas/vendedor.js

Campos del formulario:

CampoIDTipo HTMLAtributosComportamiento
CodigoidInputCodigotextreadonly, maxlength=20Oculto en alta, visible en edicion/consulta
NombreidInputNombretextrequired, minlength=3, maxlength=35Focus inicial en alta
DomicilioidInputDomiciliotextminlength=3, maxlength=25Opcional
LocalidadidInputLocalidadtext-Autocomplete jQuery UI
DocumentoidInputDocumentotext-Formato con setInputIdentificacion()
ComisionidInputComisiontextrequired, step=0.01, data-badge-type="P"Badge porcentaje con setInputBadge()
TelefonoidInputTelefonotext-Formato con setInputTelefono()

Modos de operacion:

ModoupdateDataonSubmitCallbackComportamiento
Alta{}funcionCampos vacios, codigo oculto, focus en nombre
EdiciondatosfuncionCampos cargados, codigo visible readonly
ConsultadatosnullTodos los campos disabled, solo boton Aceptar

Logica del formulario (vendedor.js):

Estructura de datos interna:
vendedor = {
  cven: null,
  nombre: null,
  domicilio: null,
  localidad: null,
  telefono: null,
  comision: null,
  documento: null
}

Autocomplete de localidad:

  • Busqueda: request.get('localidad', { filter: term })
  • Formato label: {cod_post} | {nombre} | {provincia}
  • Al seleccionar: almacena data (ID) en vendedor.localidad

Validacion de comision (blur en campo):

  • Si valor > 100: ajusta a 100, muestra error, almacena 100

Submit del formulario:

  1. Valida formulario HTML nativo (isValidForm(form))
  2. Recopila valores de inputs
  3. Si vendedor.cven existe: request.put('ordven', vendedor) (modificacion)
  4. Si vendedor.cven es null: request.post('ordven', vendedor) (alta)
  5. Cierra modal y ejecuta callback

Gestion del modal:

  • El HTML del formulario se carga dinamicamente via getContentFile()
  • Se appenda al body del documento
  • Se destruye al cerrar (hidden.bs.modal)
  • Soporte para modales anidados (restaura modal-open class)

3. Vista de Informe - Lista de Vendedores

Ubicacion: view/mod-ventas/lista-vendedores.phpJavaScript: js/view/mod-ventas/list-vendedores.jsURL: ?loc=mvlv

Componentes de la vista:

  • Header con titulo "Informes"
  • Breadcrumb: Home > Ventas > Lista de vendedores
  • Formulario con campos "Desde Vendedor" y "Hasta Vendedor" (autocompletes)
  • Configuracion del informe (checkboxes deshabilitados: "Solo hoja de ruta", "Visitas quincenales"; select de dias deshabilitado)
  • Botones "Cancelar" y "Informe | Alt + I"

Funcionalidad JavaScript (list-vendedores.js):

Estructura del informe:
informe = {
  codReporte: 8,
  vendedorDesde: null,
  vendedorHasta: null
}

Inicializacion:

  1. Carga el primer vendedor: request.get('ordven', { first: true })
  2. Carga el ultimo vendedor: request.get('ordven', { last: true })
  3. Configura autocompletes para ambos campos
  4. Focus inicial en "Desde Vendedor"

Autocomplete vendedores:

  • Busqueda: request.get('ordven', { filter: term })
  • Formato label: {cven} | {nombre}
  • Al seleccionar: almacena data.cven

Validacion al enviar:

  • Si vendedorDesde > vendedorHasta: error y focus en campo desde

Generacion: generarInforme(informe) con codReporte 8


Integracion React Parcial

Hook useVendedorData

Ubicacion: ts/ventas/hooks/useVendedorData.ts

Proposito: Hook React para consumir vendedores desde otros componentes React del sistema (no para el ABM de vendedores).

Interfaz:

typescript
interface VendedorRecord {
    cven: number;
    nombre: string;
}

Parametros:

  • scope (string, default 'min'): Alcance de la consulta
  • skip (boolean, default false): Si debe omitir la consulta

Retorno: { records: VendedorRecord[], loading: boolean, error: string | null }

Endpoint: GET /vendedor?scope={scope} (via Axios directo)

Patron: useState + useEffect (NO usa TanStack Query)

Nota: A pesar de usar useState/useEffect, existen query keys definidas en ts/ventas/config/queryKeys.ts para vendedores:

typescript
vendedores: {
    all: () => createTenantQueryKey('ventas', 'vendedores'),
    lists: () => createTenantQueryKey('ventas', 'vendedores', 'list'),
    list: () => createTenantQueryKey('ventas', 'vendedores', 'list'),
}

Esto sugiere que hay preparacion para una futura migracion a TanStack Query.


State Management

Vista principal (vendedores.js)

  • DataTable: jQuery DataTables maneja el estado del listado
  • Datos de fila: Almacenados en atributo data-row como JSON serializado
  • Actualizacion: reemplazarFila() utility para actualizar fila individual, row.add() para nueva fila, row.remove() para eliminacion

Formulario (vendedor.js)

  • Estado local: Objeto JavaScript plano vendedor = { cven, nombre, ... }
  • Inputs DOM: Sincronizacion manual entre inputs y objeto de estado
  • Callback pattern: El formulario recibe onSubmitCallback para comunicar resultado al padre

Informe (list-vendedores.js)

  • Estado local: Objeto JavaScript plano informe = { codReporte, vendedorDesde, vendedorHasta }
  • Autocomplete state: Almacenamiento directo en propiedades del objeto informe

Integracion con Backend

Endpoints consumidos (via API.js proxy)

MetodoRecurso ProxyEndpoint RealProposito
GETordven/vendedorListar todos los vendedores
GETordven?id=/vendedor?id=Obtener vendedor por ID
GETordven?filter=/vendedor?filter=Busqueda autocomplete (limite 10)
GETordven?first=true/vendedor?first=truePrimer vendedor
GETordven?last=true/vendedor?last=trueUltimo vendedor
POSTordven/vendedorCrear vendedor
PUTordven/vendedorActualizar vendedor
DELETEordven/vendedor/Eliminar vendedor (soft delete)
GETlocalidad?filter=/localidad?filter=Busqueda localidades (autocomplete en formulario)
GETlocalidad?id=/localidad?id=Obtener localidad por ID (carga en edicion)

Endpoint consumido (via Axios directo, React)

MetodoEndpointProposito
GET/vendedor?scope=Hook useVendedorData para otros modulos React

Routing

URLVistaPermiso Requerido
?loc=mvvvendedores.php (ABM)VENTAS_BASES_VENDEDORES
?loc=mvlvlista-vendedores.php (Informe)VENTAS_INF_VENDEDORES

Navegacion: Ambas vistas estan accesibles desde el sidebar del modulo Ventas:

  • "Bases" > "Vendedores" -> ABM
  • "Informes" > "Vendedores" -> Informe PDF

Bibliotecas y Dependencias

Vista Principal (ABM)

  • jQuery 3.x
  • Bootstrap 4 (AdminLTE)
  • jQuery DataTables + plugins (responsive, buttons, PDF, Excel)
  • jQuery UI (autocomplete en formulario)
  • SweetAlert (confirmaciones, alertas, toasts)
  • API.js (comunicacion backend legacy)
  • BS Stepper (CSS cargado pero no usado en esta vista)

Vista Informe

  • jQuery 3.x
  • Bootstrap 4 (AdminLTE)
  • jQuery UI (autocomplete)
  • SweetAlert
  • API.js
  • informes.js (generacion de PDF via servicio externo)

Utilidades Importadas

UtilidadOrigenUso
createFormVendedorforms/ventas/vendedor.jsCrear/mostrar formulario modal
ApiRequestmiddleware/API.jsComunicacion con backend
reemplazarFilautil/datatable-methods.jsActualizar fila en DataTable
LANG_TABLEutil/constantes.jsLocalizacion de DataTables
getContentFileutil/export-methods.jsCarga dinamica de HTML
isValidFormutil/form-methods.jsValidacion HTML5 nativa
validateTypeutil/input-functions.jsValidacion de tipo en inputs
setInputIdentificacionutil/inputs.jsFormato de documento
setInputTelefonoutil/inputs.jsFormato de telefono
setInputBadgeutil/inputs.jsBadge visual en input
setAutocompleteutil/inputs.jsConfiguracion de autocomplete jQuery UI
generarInformemiddleware/informes.jsGeneracion de PDF

Preguntas Tecnicas Pendientes

Aclaraciones Requeridas: Hay aspectos tecnicos que requieren validacion. Ver: Preguntas sobre Vendedores

Principales aspectos frontend pendientes:

  • Hook useVendedorData usa useState en lugar de TanStack Query (query keys ya existen)
  • Implementacion completamente legacy, candidata a migracion React
  • Checkboxes y select de dias deshabilitados en vista de informe (funcionalidad futura?)

Referencias


NOTA IMPORTANTE: Esta documentacion fue generada automaticamente analizando el codigo implementado. Validar cambios futuros contra este baseline.