Implementación de Funcionalidad: InsertarEmpleados (incluye controller, modelo y htmls)

 

Fecha: 22 de abril de 2026

Hora de inicio: 1:00 p.m. 

Hora de finalización: 5:00 p.m.

Horas trabajadas: 4h

Después de implementar la autenticación, el siguiente paso era crear la página principal de la aplicación: el listado de empleados. Esta página es la parte principal desde el cual se puede consultar empleado, editar, eliminar, o ver movimientos. El desafío principal fue implementar un filtro flexible (por nombre o cédula) que se detectara automáticamente, mantener los ids de empleados ocultos al usuario como indicaba el requerimiento, y usar JavaScript para permitir la selección interactiva de empleados.


Actividades realizadas

1:00 p.m.- 1:40 p.m.

Implementación de modelo_empleado.py

Se creó el módulo app/model/modelo_empleado.py con funciones para operaciones sobre empleados. La primera función implementada fue listar_empleados():

    Img 1: método listar_empleados

Esta función ejecuta el SP dbo.ListarEmpleados que devuelve dos resultsets: primero la lista de empleados, luego el código de resultado. El patrón es simple aquí (no hay complicaciones de bitácora intercalada como en Login). El SP devuelve exactamente dos resultsets en orden. Por eso el código usa cursor.fetchall() para obtener todas las filas del primer resultset, luego cursor.nextset() para avanzar al segundo, y finalmente cursor.fetchone()[0] para leer el código de resultado.

Los parámetros filtro_nombre y filtro_cedula se pasan al SP como None si no hay filtro, permitiendo que el SP busque todas los empleados. El SP internamente ejecuta diferentes lógicas según cuál filtro sea NOT NULL.

2:00 p.m. - 3:25 p.m

Implementación de controlador_empleado.py


    Img 2: listar_empleados_views

Protección de sesión:

La ruta comienza verificando que exista una sesión activa. Si el usuario intenta acceder sin haber hecho login, se redirige a auth.login_view. Importante porque la página de empleados no debería ser pública

Detección automática de filtro:

El filtro viene como query parameter en la URL (GET /empleados?filtro=603). El controlador obtiene este valor con request.args.get('filtro', '').strip(). El .strip() elimina espacios en blanco al inicio y final, y la cadena vacía por defecto evita errores si no hay filtro.

Luego, se decide automáticamente si el filtro es para cédula o nombre:

                                            Img 3: Filtro

isdigit() devuelve True solo si la cadena contiene exclusivamente dígitos 0-9. Si el usuario ingresa "603", es cédula. Si ingresa "Perez", es nombre. Si ingresa "603A" (mezcla), se trata como nombre (porque no es exclusivamente dígitos).

El SP ListarEmpleados espera recibir ambos parámetros (@inFiltroNombre y @inFiltroCedula), pero solo uno estará lleno (el otro será NULL). El SP internamente hace la búsqueda en la columna correcta.

Llamada al modelo y manejo de errores:

Se llama a listar_empleados() pasando los filtros, id del usuario y IP. Si el result_code no es 0, se obtiene el mensaje de error de la BD mediante obtener_mensaje_error(result_code) y se muestra con flash().

Finalmente, se renderiza index.html pasando la lista de empleados y el filtro usado (para que el formulario muestre lo que el usuario escribió).


3:40 p.m. - 5:00 p.m.

Implementación de index.html

    Img 4: index.html

Filtro de Búsqueda

                                            Img: form para filtro

Un formulario simple GET que envía el filtro a la misma ruta /empleados. El campo de texto tiene value="{{ filtro }}" para que se mantenga lo que el usuario escribió después de filtrar.

Tabla de empleados:


                                    Img 5: tabla para empleados con Scroll

Estructura de columnas:

El SP ListarEmpleados devuelve un recordset con 6 columnas en este orden:

  • emp[0]: id (no se muestra)
  • emp[1]: Nombre
  • emp[2]: ValorDocumentoIdentidad (cédula)
  • emp[3]: FechaContratacion
  • emp[4]: SaldoVacaciones
  • emp[5]: NombrePuesto

En la tabla se muestran solo 5 columnas (sin el id), pero en el orden visual: Nombre, Cédula, Puesto, Fecha, Saldo.

IDs ocultos al usuario:

El requerimiento R2 del enunciado indicó explícitamente: "La selección del empleado para realizar alguna operación NO DEBE hacerse mediante la captura de su id. En esta tarea los ids estarán escondidos". Por eso:

  • El id (emp[0]) nunca se muestra en la tabla
  • El id viaja en el atributo id="fila-{{ emp[0] }}" del elemento <tr>, oculto al HTML pero accesible desde JavaScript
  • El id se pasa a la función seleccionar() via el atributo onclick

Errores Encontrados

Error 1: Código de error 50008 al filtrar

Al intentar filtrar empleados, la aplicación devolvía error 50008 ("Error de base de datos") sin importar el filtro.

Causa: El SP ListarEmpleados llama a RegistrarBitacora para registrar que el usuario hizo una consulta con filtro. RegistrarBitacora requiere que la tabla TipoEvento tenga los registros de tipos de eventos. En ese momento, la tabla estaba vacía porque Valeria aún no había completado su parte del script de carga XML, que inserta los TipoEvento.

Solución temporal: Insertar manualmente los registros de TipoEvento en SSMS mientras Valeria terminaba su parte. Los tipos de evento requeridos son: Login Exitoso (1), Login No Exitoso (2), Login deshabilitado (3), Logout (4), etc. Una vez Valeria completó el script, este error desapareció.

Error 2 :Índices de columnas incorrectos en la tabla HTML

Los datos en la tabla HTML aparecían en orden incorrecto. Por ejemplo, el puesto se mostraba en la columna de cédula.

Causa: El SP ListarEmpleados devuelve las columnas en un orden específico, pero el HTML las referenciaba con índices de array incorrectos. El SP devuelve en este orden:

  • emp[0]: id
  • emp[1]: Nombre
  • emp[2]: ValorDocumentoIdentidad
  • emp[3]: FechaContratacion
  • emp[4]: SaldoVacaciones
  • emp[5]: NombrePuesto

Pero el HTML los mapeabea bien, la solución fue simplemente mapearlos en el orden correcto.

Error 4 — Filtro vacío causaba error

Si el usuario no escribía nada en el filtro y presionaba "Filtrar", se obtenía un error.

Causa: Cuando el filtro venía vacío desde el formulario, Python pasaba un string vacío '' al SP en lugar de None. El SP esperaba None para distinguir entre "sin filtro" vs "filtro vacío".

Solución: Usar .strip() para eliminar espacios, y verificar con if filtro: antes de asignar los parámetros:

    

                                            Img 6: Filtro para evitar el error

Si filtro es una cadena vacía después de .strip(), la condición if (filtro): es False, así que ambos parámetros quedan en None, y el SP devuelve todos los empleados.

Forma de trabajo del equipo

Yo (JJ) implementé modelo_empleado.py, controlador_empleado.py, index.html y la lógica de filtro/selección. Todo lo anterior en las partes relacionadas con el index.html. El tiempo más largo se dedicó a debugging de los 4 errores. La comunicación se hizo mediante whatsApp.


Referencias consultadas

Comentarios

Entradas más populares de este blog

Creación del SP de Cargar Datos

Implementación de funcionalidades: Editar Empleado y Eliminar Empleado

Implementación de funcionalidad: Consultar Empleado