Skip to content

Condicion de Venta - Documentacion Tecnica Frontend

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

Modulo: Ventas Feature: Condicion de Venta Fecha: 2026-02-09


Referencia de Negocio


Arquitectura Implementada

Este recurso esta implementado completamente en codigo legacy (vanilla JavaScript + PHP templates). No hay componentes React/TypeScript involucrados. El frontend se compone de:

ComponenteArchivoTipo
Vista PHPpublic/view/mod-ventas/cond-venta.phpTemplate PHP + HTML
Logica JSpublic/js/view/mod-ventas/cond-venta.jsModulo ES6 vanilla JS
Proxy Backendpublic/php/backend/condvta.phpProxy PHP al backend
Constantespublic/js/constants/modulo-venta/CondicionVenta.jsConstante frozen
Sidebarpublic/php/components/mod-venta/main-sidebar-venta.phpComponente de navegacion

Stack Tecnologico

  • HTML/CSS: AdminLTE 3 + Bootstrap 4
  • JavaScript: Vanilla JS con ES Modules
  • Tabla: jQuery DataTables
  • Modal: Bootstrap 4 modal (via template cloneNode)
  • Alertas: SweetAlert2
  • API: Clase ApiRequest legacy (FormData + fetch)

Componentes Implementados

1. Vista de Listado (cond-venta.php)

Ubicacion: public/view/mod-ventas/cond-venta.phpAcceso: ?loc=mvcvAutenticacion: Validacion de sesion PHP ($_SESSION['SD_USER'])

Estructura HTML:

  • Header: Titulo "Listado de condiciones de ventas" + breadcrumb (Home > Ventas > Cond. Venta)
  • Card: Contenedor con titulo "Condiciones de ventas" y tabla vacia (poblada por JS)
  • Template: <template id="modalCondVenta"> - Modal de edicion (clonado dinamicamente)
  • Sidebar: Sidebar del modulo ventas con item activo en "Cond. Venta"

Scripts cargados:

  • jQuery, Bootstrap 4, DataTables (con plugins responsive y buttons)
  • PDFMake, JSZip (exportacion de DataTables)
  • AdminLTE
  • Modulo principal: js/view/mod-ventas/cond-venta.js

Activacion de sidebar:

javascript
// Marca el item de navegacion como activo
navItemBases.classList.add('menu-is-opening', 'menu-open');
navLinkBases.classList.add('active');
navLinkActive = document.getElementById('idMainSideBarCondVenta');
navLinkActive.classList.add('active');

2. Logica Principal (cond-venta.js)

Ubicacion: public/js/view/mod-ventas/cond-venta.jsTipo: ES Module Imports:

  • ApiRequest desde ../../middleware/API.js
  • LANG_TABLE desde ../../util/constantes.js
  • reemplazarFila desde ../../util/datatable-methods.js
  • setInputBadge desde ../../util/inputs.js

DataTable

Inicializacion:

- Tabla jQuery DataTables con language en espanol
- Responsive: true
- Data: cargada via ApiRequest.get('condvta') (await)

Columnas definidas:

TituloDataRenderNotas
Codigoid-Muestra el codigo numerico
Nombrenombre-Muestra la descripcion
Recargoporcentaje_recargo> 0 ? data + '%' : nullCentrado, muestra %
AccionesnullBoton rojo con icono lapizNo ordenable, JSON en data-row

Evento de Edicion

  • Se escucha click en #btn_modificar via delegacion en la tabla
  • Se extrae data-row del boton (JSON parseado)
  • Se invoca createModal(row) con los datos de la fila

Funcion createModal(condvta)

Flujo:

  1. Clona el template #modalCondVenta
  2. Obtiene elementos del formulario (inputNombre, inputRecargo)
  3. Setea valores iniciales (nombre readonly, recargo editable)
  4. Aplica setInputBadge al input de recargo (badge tipo "P" - porcentaje)
  5. Registra listener input en inputRecargo para capturar valor
  6. En submit del form:
    • Valida que recargo >= 0
    • Si no hubo cambios, cierra modal sin peticion
    • Ejecuta ApiRequest.put('condvta', { recargo, id })
    • En exito: actualiza fila con reemplazarFila(), muestra toast de exito
    • En error: muestra modal de error
  7. Al cerrar modal: elimina el elemento DOM
  8. Al mostrar modal: focus en inputRecargo

3. Constante de Condicion de Venta (CondicionVenta.js)

Ubicacion: public/js/constants/modulo-venta/CondicionVenta.js

javascript
export const CondicionVenta = Object.freeze({
    CONTADO: 1,
    CTA_CTE: 2,
    TARJETA: 3
})

Uso: Importada en form-header.js del modulo de facturacion para comparaciones de logica de negocio.


4. Proxy Backend (public/php/backend/condvta.php)

Ubicacion: public/php/backend/condvta.php

Funcion: Actua como intermediario entre el frontend JS y el backend PHP.

Flujo GET:

  1. Valida sesion de usuario
  2. Si se proporciona id, valida que sea integer
  3. Crea instancia de Request (HTTP client interno)
  4. Realiza GET a backend condvta con parametros
  5. Decodifica JSON de respuesta
  6. Retorna data al frontend

Flujo PUT:

  1. Valida sesion de usuario
  2. Lee body JSON del request
  3. Valida: id (required, integer), recargo (required, numeric, min:0)
  4. Crea instancia de Request
  5. Realiza PUT a backend condvta con body
  6. Retorna status code del backend

5. Uso en Facturacion

Archivos involucrados:

  • public/js/view/mod-ventas/facturacion/index.js - Carga de condiciones
  • public/js/view/mod-ventas/facturacion/form-header.js - Selector y logica
  • public/js/view/mod-ventas/facturacion/comprobante.js - Objeto comprobante

Carga de condiciones (index.js)

1. await ApiRequest.get('condvta') -> obtiene array de condiciones
2. Encuentra condicion por defecto: condiciones.find(e => e.defecto) ?? condiciones[0]
3. Llama formHeader.setCondicionesVenta(condiciones)
4. Asigna condicion por defecto al comprobante

Selector de condicion (form-header.js)

Elemento DOM: <select id="idSelectCondVenta">

Poblado: Se crean opciones con formato:

  • Si tiene recargo: "Nombre | X.XXX %"
  • Sin recargo: "Nombre"
  • Opcion seleccionada: la marcada como defecto

Evento change del select:

  1. Validacion CTA_CTE: Si se selecciona CTA_CTE y el cliente no tiene tiene_ctacte, se revierte a CONTADO y muestra error
  2. Validacion Tarjeta en modo prueba: Si es_tarjeta y modulo Tesoreria activo y modo prueba, se revierte a CONTADO
  3. Habilitacion selector tarjeta: Si es_tarjeta, habilita selectTarjeta y carga tarjetas (lazy loading primera vez)
  4. Deshabilitacion selector tarjeta: Si no es tarjeta, deshabilita selectTarjeta
  5. Asignacion al comprobante: comprobante.condicionVenta = cond
  6. Recargo en factura: Si tipo comprobante es FACTURA, setea inputRecargo.value = cond.porcentaje_recargo

Objeto comprobante (comprobante.js)

Propiedades:

  • _condicionVenta: Almacena el objeto de condicion de venta seleccionada
  • Getter/setter condicionVenta: Acceso a la propiedad

En el payload de facturacion:

javascript
{
    condicionVenta: this.condicionVenta.id,
    condicionVentaRecargo: this.porcentaje_recargo
}

Integracion con Backend

Endpoints Consumidos

EndpointMetodoModuloProposito
condvtaGETCond. VentaListar condiciones (tabla y facturacion)
condvtaPUTCond. VentaActualizar recargo
mod-ventas/tarjetasGETTarjetasCargar tarjetas (lazy, solo si es_tarjeta)

Patron de comunicacion: ApiRequest legacy (FormData + fetch + proxy PHP)

Datos recibidos del backend

typescript
// Estructura de datos por condicion de venta
interface CondicionVenta {
    id: number;           // Codigo
    nombre: string;       // Descripcion
    defecto: boolean;     // Condicion por defecto
    es_tarjeta: boolean;  // Tipo tarjeta
    porcentaje_recargo: number;  // % de recargo
}

Datos enviados al backend (PUT)

typescript
// Payload de modificacion de recargo
{
    id: number;      // Codigo de la condicion
    recargo: number; // Nuevo porcentaje de recargo
}

State Management

Tipo: Variables locales de modulo (vanilla JS)

En cond-venta.js (Vista de listado)

VariableTipoAlcanceProposito
tableDataTableModuloInstancia de la tabla
recargonumberFuncion (createModal)Valor actual del recargo en edicion

En facturacion (form-header.js, index.js, comprobante.js)

VariableTipoAlcanceProposito
condicionesArrayClosure (setCondicionesVenta)Todas las condiciones cargadas
defaultData.condicionVentaObjectModulo (index.js)Condicion por defecto
comprobante._condicionVentaObjectObjeto comprobanteCondicion seleccionada actual
tarjetasMapClosure (form-header)Tarjetas cargadas (lazy loading)

Routing

Ruta de acceso: ?loc=mvcv

Resolucion en index.php:

php
case 'mvcv': // Modulo de ventas: Condiciones de ventas
    require_once('view/mod-ventas/cond-venta.php');
    break;

Navegacion en sidebar: Ventas > Bases > Cond. Venta

  • Requiere permiso: VENTAS_BASES_COND-VENTA
  • ID del link: idMainSideBarCondVenta
  • ID del padre: idNavMainSideBarBases / idMainSideBarBases

Validaciones del Frontend

En cond-venta.js (Modal de edicion)

ValidacionUbicacionTipo
Recargo >= 0submit handlerNegocio (JS)
Sin cambios = cerrar sin peticionsubmit handlerUX

En proxy (public/php/backend/condvta.php)

CampoReglasMensaje personalizado
id (GET)integer"La condicion de venta seleccionada es invalida"
id (PUT)required, integer"La condicion de venta seleccionada es invalida"
recargo (PUT)required, numeric, min:0Mensajes por defecto del validador

En facturacion (form-header.js)

ValidacionCondicionAccion
Cliente sin CTA_CTEcondicion === CTA_CTE && !cliente.tiene_ctacteRevertir a CONTADO
Tarjeta en pruebaes_tarjeta && Tesoreria activo && modo pruebaRevertir a CONTADO
Sin tarjetases_tarjeta && tarjetas vacioMostrar error

Patrones UI Implementados

Patron de Modal con Template

  1. Se define un <template> en el HTML con la estructura del modal
  2. Al editar, se clona el template con cloneNode(true)
  3. Se inyectan datos y event listeners en el clon
  4. Se muestra el modal con $(modal).modal('show')
  5. Al cerrar, se destruye el DOM del modal clonado (modal.remove())

Ventaja: Cada instancia de modal es independiente, sin conflictos de estado.

Patron de Actualizacion de Fila en DataTable

Se utiliza reemplazarFila(table, 'id', condvta.id, condvta) para actualizar la fila en la tabla sin recargar todos los datos.

Patron de Lazy Loading (Tarjetas en facturacion)

Las tarjetas solo se cargan del servidor la primera vez que el usuario selecciona una condicion tipo tarjeta. Se almacenan en un Map y se reutilizan.


Preguntas Tecnicas Pendientes

Aclaraciones Requeridas: Hay aspectos tecnicos que requieren validacion. Ver: Preguntas sobre Condicion de Venta

Preguntas relevantes al frontend: #2 (edicion limitada), #3 (campo defecto), #5 (valores posibles), #10 (restriccion tarjeta en prueba).


Diagrama de Flujo de Seleccion en Facturacion

mermaid
flowchart TD
    A([Usuario cambia condicion de venta]) --> B{Es CTA_CTE?}
    B -->|Si| C{Cliente tiene CTA_CTE?}
    C -->|No| D[Revertir a CONTADO + Error]
    C -->|Si| H[Asignar condicion]
    B -->|No| E{Es Tarjeta?}
    E -->|Si| F{Tesoreria activo + modo prueba?}
    F -->|Si| G[Revertir a CONTADO + Info]
    F -->|No| I[Habilitar selector tarjeta]
    I --> J{Tarjetas cargadas?}
    J -->|No| K[Cargar tarjetas del servidor]
    K --> L{Hay tarjetas?}
    L -->|No| M[Error: debe cargar tarjetas]
    L -->|Si| N[Poblar selector]
    J -->|Si| N
    N --> H
    E -->|No| O[Deshabilitar selector tarjeta]
    O --> H
    H --> P{Es Factura?}
    P -->|Si| Q[Setear recargo en input]
    P -->|No| R([Fin])
    Q --> R

Recomendaciones de Migracion a React

Si se decidiera migrar este recurso a la arquitectura moderna React/TypeScript:

  1. Crear tipos: ts/ventas/CondicionVenta/types/condicionVenta.types.ts
  2. Crear schema Zod: ts/ventas/CondicionVenta/schemas/condicionVenta.schema.ts
  3. Crear servicio: ts/ventas/CondicionVenta/services/condicionVenta.service.ts (axios directo)
  4. Crear hook: ts/ventas/CondicionVenta/hooks/useCondicionVenta.ts (TanStack Query)
  5. Crear componentes: CondicionVentaTable, CondicionVentaEditModal
  6. Crear vista: ts/ventas/CondicionVenta/views/CondicionVentaView.tsx
  7. Eliminar proxy: Consumir API directamente via axios con interceptores
  8. Mantener constante: Migrar CondicionVenta.js a TypeScript enum o const assertion

Referencias


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