Appearance
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:
| Componente | Archivo | Tipo |
|---|---|---|
| Vista PHP | public/view/mod-ventas/cond-venta.php | Template PHP + HTML |
| Logica JS | public/js/view/mod-ventas/cond-venta.js | Modulo ES6 vanilla JS |
| Proxy Backend | public/php/backend/condvta.php | Proxy PHP al backend |
| Constantes | public/js/constants/modulo-venta/CondicionVenta.js | Constante frozen |
| Sidebar | public/php/components/mod-venta/main-sidebar-venta.php | Componente 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
ApiRequestlegacy (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:
ApiRequestdesde../../middleware/API.jsLANG_TABLEdesde../../util/constantes.jsreemplazarFiladesde../../util/datatable-methods.jssetInputBadgedesde../../util/inputs.js
DataTable
Inicializacion:
- Tabla jQuery DataTables con language en espanol
- Responsive: true
- Data: cargada via ApiRequest.get('condvta') (await)Columnas definidas:
| Titulo | Data | Render | Notas |
|---|---|---|---|
| Codigo | id | - | Muestra el codigo numerico |
| Nombre | nombre | - | Muestra la descripcion |
| Recargo | porcentaje_recargo | > 0 ? data + '%' : null | Centrado, muestra % |
| Acciones | null | Boton rojo con icono lapiz | No ordenable, JSON en data-row |
Evento de Edicion
- Se escucha
clicken#btn_modificarvia delegacion en la tabla - Se extrae
data-rowdel boton (JSON parseado) - Se invoca
createModal(row)con los datos de la fila
Funcion createModal(condvta)
Flujo:
- Clona el template
#modalCondVenta - Obtiene elementos del formulario (inputNombre, inputRecargo)
- Setea valores iniciales (nombre readonly, recargo editable)
- Aplica
setInputBadgeal input de recargo (badge tipo "P" - porcentaje) - Registra listener
inputen inputRecargo para capturar valor - 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
- Al cerrar modal: elimina el elemento DOM
- 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:
- Valida sesion de usuario
- Si se proporciona
id, valida que sea integer - Crea instancia de
Request(HTTP client interno) - Realiza GET a backend
condvtacon parametros - Decodifica JSON de respuesta
- Retorna
dataal frontend
Flujo PUT:
- Valida sesion de usuario
- Lee body JSON del request
- Valida:
id(required, integer),recargo(required, numeric, min:0) - Crea instancia de
Request - Realiza PUT a backend
condvtacon body - Retorna status code del backend
5. Uso en Facturacion
Archivos involucrados:
public/js/view/mod-ventas/facturacion/index.js- Carga de condicionespublic/js/view/mod-ventas/facturacion/form-header.js- Selector y logicapublic/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 comprobanteSelector 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:
- Validacion CTA_CTE: Si se selecciona CTA_CTE y el cliente no tiene
tiene_ctacte, se revierte a CONTADO y muestra error - Validacion Tarjeta en modo prueba: Si
es_tarjetay modulo Tesoreria activo y modo prueba, se revierte a CONTADO - Habilitacion selector tarjeta: Si
es_tarjeta, habilitaselectTarjetay carga tarjetas (lazy loading primera vez) - Deshabilitacion selector tarjeta: Si no es tarjeta, deshabilita
selectTarjeta - Asignacion al comprobante:
comprobante.condicionVenta = cond - 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
| Endpoint | Metodo | Modulo | Proposito |
|---|---|---|---|
condvta | GET | Cond. Venta | Listar condiciones (tabla y facturacion) |
condvta | PUT | Cond. Venta | Actualizar recargo |
mod-ventas/tarjetas | GET | Tarjetas | Cargar 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)
| Variable | Tipo | Alcance | Proposito |
|---|---|---|---|
table | DataTable | Modulo | Instancia de la tabla |
recargo | number | Funcion (createModal) | Valor actual del recargo en edicion |
En facturacion (form-header.js, index.js, comprobante.js)
| Variable | Tipo | Alcance | Proposito |
|---|---|---|---|
condiciones | Array | Closure (setCondicionesVenta) | Todas las condiciones cargadas |
defaultData.condicionVenta | Object | Modulo (index.js) | Condicion por defecto |
comprobante._condicionVenta | Object | Objeto comprobante | Condicion seleccionada actual |
tarjetas | Map | Closure (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)
| Validacion | Ubicacion | Tipo |
|---|---|---|
| Recargo >= 0 | submit handler | Negocio (JS) |
| Sin cambios = cerrar sin peticion | submit handler | UX |
En proxy (public/php/backend/condvta.php)
| Campo | Reglas | Mensaje 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:0 | Mensajes por defecto del validador |
En facturacion (form-header.js)
| Validacion | Condicion | Accion |
|---|---|---|
| Cliente sin CTA_CTE | condicion === CTA_CTE && !cliente.tiene_ctacte | Revertir a CONTADO |
| Tarjeta en prueba | es_tarjeta && Tesoreria activo && modo prueba | Revertir a CONTADO |
| Sin tarjetas | es_tarjeta && tarjetas vacio | Mostrar error |
Patrones UI Implementados
Patron de Modal con Template
- Se define un
<template>en el HTML con la estructura del modal - Al editar, se clona el template con
cloneNode(true) - Se inyectan datos y event listeners en el clon
- Se muestra el modal con
$(modal).modal('show') - 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 --> RRecomendaciones de Migracion a React
Si se decidiera migrar este recurso a la arquitectura moderna React/TypeScript:
- Crear tipos:
ts/ventas/CondicionVenta/types/condicionVenta.types.ts - Crear schema Zod:
ts/ventas/CondicionVenta/schemas/condicionVenta.schema.ts - Crear servicio:
ts/ventas/CondicionVenta/services/condicionVenta.service.ts(axios directo) - Crear hook:
ts/ventas/CondicionVenta/hooks/useCondicionVenta.ts(TanStack Query) - Crear componentes:
CondicionVentaTable,CondicionVentaEditModal - Crear vista:
ts/ventas/CondicionVenta/views/CondicionVentaView.tsx - Eliminar proxy: Consumir API directamente via axios con interceptores
- Mantener constante: Migrar
CondicionVenta.jsa TypeScript enum o const assertion
Referencias
NOTA IMPORTANTE: Esta documentacion fue generada automaticamente analizando el codigo implementado. Validar cambios futuros contra este baseline.