Registro Público y Transparente · Despliegue Continuo

Pipeline de Hitos, Roadmap & Documentación Oficial

Consulta de forma transparente y sin secretos el registro cronológico continuo de las 30 mejoras, arquitectura de base de datos multi-tenant y especificaciones funcionales de CENIT 365.

30
Hitos en Producción
100%
Desplegado Azure
Veri*Factu
Normativa AEAT
C-Suite
Geocercado & GPS
Mostrando 30 de 30 hitos
Filtrar por módulo:
#30
MEJORA-030 Desplegado en Producción Calidad / Todos los módulos / Multi-Tenant / Despliegue Azure
2026-10-12

Validación obligatoria antes del despliegue y regresiones multiempresa

Problema o Necesidad Detectada:

El despliegue no exigía pruebas. Las auditorías históricas dependían de empresas configuradas y llamadas directas a vistas, sin una matriz reproducible de empresas, datos, permisos y navegación de usuario.

Pruebas de Verificación y Validación:
  • Pruebas del bloqueo de despliegue con ejecutables simulados, sin llamadas a Azure.
  • Comprobación rápida de estructura, sintaxis Python/JSON/YAML y sintaxis Bash.
  • Suite completa ejecutada: 24 tests, 60 recorridos de navegador y 635 comprobaciones correctas; 0 fallos y 0 bloqueos. Resultado registrado en quality-artifacts/results.json.
  • Inventario inicial: 18 módulos, 946 rutas y 31 contratos de pantalla; 912 rutas permanecen identificadas como sin cobertura funcional (incluye alias).
  • No se ha desplegado ni auditado la base de datos real. La deuda de cobertura permanece visible; inventariar una ruta no equivale a haberla probado.
  • 📷 Capturas: generadas automáticamente en quality-artifacts/browser/ cuando falla una comprobación de navegador; no se incorporan al paquete de producción.
#29
MEJORA-029 Desplegado en Producción Seguridad / Autenticación / Login / Geolocalización / UX
2026-09-02 22:05

Solicitud Activa de Geolocalización sin Bloqueo de Acceso (Modo Auditoría Permisivo)

Solución Técnica y Funcional Aplicada:
  • Solicitud Proactiva en Login:
    • Al abrir login.html, precapturarUbicacion() invoca de inmediato navigator.geolocation.getCurrentPosition(...) para que el navegador lance la ventana nativa de permiso de ubicación.
  • Acceso Sin Interrupciones:
    • Si el usuario concede el permiso, las coordenadas se envían y registran en RegistroAccesoLogin (y se visualizan en el mapa).
    • Si el usuario rechaza, cancela o ignora la petición, el formulario de inicio de sesión entra con total normalidad (HTTP 302 hacia el panel correspondiente) y se audita el acceso como [ACCESO REMOTO / SIN GPS] o [SEDE IP].
  • Eliminación de Bloqueos Forzados:
    • Se retiró la restricción que emitía errores de validación de formulario en CustomLoginView.form_valid, garantizando una experiencia de usuario fluida y compatible con la privacidad laboral.
Pruebas de Verificación y Validación:
  • Prueba de login automatizada con RequestFactory y SessionMiddleware sin coordenadas GPS -> Código de respuesta HTTP 302 (acceso concedido y sesión iniciada con éxito).
  • manage.py check con 0 errores.
#28
MEJORA-028 Desplegado en Producción Seguridad / Dirección / Mapa GPS / Auditoría Temporal / UI-UX
2026-09-02 21:50

Filtrado Temporal de Ubicaciones en Mapa (Hoy, 24h, 7d, Histórico) y Filtro por Empleado

Problema o Necesidad Detectada:

El mapa mostraba una lista estática de los últimos 150 accesos globales sin posibilidad de aislar o examinar exclusivamente las conexiones ocurridas durante el día de hoy (tab=mapa), en las últimas 24 horas, en los últimos 7 días o las pertenecientes a un trabajador específico.

Solución Técnica y Funcional Aplicada:
  • Barra de Herramientas de Filtrado Dinámico:
    • Botones de período rápido: 📅 Hoy (con contador en vivo de conexiones hoy), ⏱️ Últimas 24h, 📆 Últimos 7 días, 🌐 Todo el Histórico.
    • Selector de Fecha Específica (<input type="date">): Permite a la Dirección auditar cualquier fecha histórica del calendario.
    • Selector de Empleado: Desplegable dinámico con los empleados que disponen de registros GPS para trazar sus ubicaciones individuales.
  • Banner de Estado Inteligente:
    • Si para la fecha seleccionada aún no hay conexiones GPS de empleados (por ejemplo a primera hora del día), se informa amigablemente al usuario indicando que las sedes físicas siguen activas y ofreciendo un botón directo para consultar los últimos 7 días o el histórico completo.
  • Auto-Encuadre Dinámico:
    • El mapa reajusta su zoom y límites automáticamente entre las sedes y los pines del período filtrado.
Pruebas de Verificación y Validación:
  • Pruebas unitarias con RequestFactory para fecha_mapa=hoy, fecha_mapa=24h, fecha_mapa=7d y fecha_mapa=todos, todas con respuesta HTTP 200.
  • manage.py check con 0 errores.
#27
MEJORA-027 Desplegado en Producción Seguridad / Dirección / Multi-Sede / Lista Blanca IPs / Geocercado
2026-09-02 21:35

Multi-Ubicación de Seguridad (Sedes/Talleres/Fincas/Almacenes), Lista Blanca Multi-IP y Carga por Defecto del Mapa

Problema o Necesidad Detectada:
  1. El mapa de seguridad (/direccion/seguridad/panel/?tab=mapa) no contaba con una posición precargada por defecto si la empresa no tenía coordenadas guardadas, pudiendo verse desorientado o vacío.
  2. La empresa SOSEIN y sus inquilinos cuentan con múltiples centros operativos (Sede Principal, Taller en polígono, Fincas agrícolas como La Jarita, Almacenes logísticos, Delegaciones) y múltiples redes/IPs (fibra taller, router oficinas, VPN corporativa), pero el sistema solo permitía configurar una única sede y una única IP.
Solución Técnica y Funcional Aplicada:
  • Nuevos Modelos de Seguridad Compartidos (empresas/models.py):
    • UbicacionSeguridad: Permite dar de alta N sedes físicas con nombre, tipo (SEDE, TALLER, FINCA, ALMACEN, DELEGACION, OTRO), latitud, longitud, radio perimetral en metros y descripción.
    • IPAutorizadaSeguridad: Permite registrar N IPs fijas o subredes CIDR corporativas (80.58.xx.xx, 10.8.0.0/24, 192.168.1.1).
  • Ampliación del Motor Perimetral Empresa.esta_en_sede y obtener_nombre_sede_coincidente:
    • Verifica si una conexión procede de la Sede Principal o de cualquiera de las ubicaciones secundarias activas o de cualquiera de las IPs/subredes autorizadas.
    • Etiqueta con precisión en el registro de acceso el nombre del centro exacto (ej. [Finca Agrícola La Jarita], [Taller Polígono], [Red VPN Corporativa]).
  • Carga por Defecto y Visualización Multi-Capa en Mapa Leaflet:
    • Precarga de coordenadas corporativas por defecto (Sevilla: 37.3891, -5.9845) para todas las empresas que no tenían ubicación asignada.
    • El mapa Leaflet renderiza simultáneamente todas las sedes registradas con círculos perimetrales de colores distintivos e iconos temáticos (🏛️ Sede, 🏭 Taller, 🚜 Finca, 📦 Almacén) junto a los marcadores de los empleados.
    • Ajuste automático de encuadre (fitBounds) entre todas las sedes y conexiones activas.
  • Gestión Visual Completa en Panel de Dirección:
    • Formularios y modales interactivos para añadir/eliminar sedes y redes autorizadas en tiempo real con botón de auto-captura GPS y detección de IP pública.
Pruebas de Verificación y Validación:
  • Pruebas unitarias en manage.py shell:
    • GET /direccion/seguridad/panel/?tab=mapa -> HTTP 200 con todas las sedes y puntos de acceso.
    • GET /direccion/seguridad/panel/?tab=sede -> HTTP 200 con tablas de sedes secundarias y lista blanca de IPs.
    • esta_en_sede evaluado positivamente para Sede Central, Finca La Jarita y subred VPN 10.8.0.0/24.
    • manage.py check con 0 errores.
#26
MEJORA-026 Desplegado en Producción Seguridad / Dirección / Mapas Leaflet / UI-UX / Renderizado
2026-09-02 21:15

Corrección de Carga de Librería Leaflet y Renderizado de Mapa en Panel de Seguridad

Problema o Necesidad Detectada:

Al acceder a la pestaña del mapa de ubicaciones (/direccion/seguridad/panel/?tab=mapa), el contenedor del mapa aparecía como un recuadro en blanco sin renderizar las capas ni los marcadores GPS de los accesos de los empleados. - Causa Raíz: En la plantilla direccion_seguridad.html, la librería Leaflet (CSS y JS) estaba ubicada dentro de un bloque {% block extra_head %}, el cual no existe en la plantilla base (timeclock/base.html), provocando que la variable global L no estuviese disponible al inicializar el mapa.

Solución Técnica y Funcional Aplicada:
  • Reubicación de Recursos en Bloques Estándar:
    • Hoja de estilos leaflet.css y reglas de dimensiones del mapa consolidadas en {% block extra_css %} dentro del <head>.
    • Script leaflet.js cargado dentro de {% block extra_js %} antes de los scripts de inicialización.
  • Inicialización Asíncrona con invalidateSize:
    • Ajustado el evento de apertura de pestaña (shown.bs.tab) y carga inicial con un ligero retardo (setTimeout) para permitir que el contenedor #accessMap tenga dimensiones calculadas antes de renderizar los tiles y marcadores.
    • Ajuste de z-index en paneles de Leaflet para garantizar interacción fluida con la interfaz del ERP.
Pruebas de Verificación y Validación:
  • Renderizado simulado con RequestFactory en manage.py shell confirmando inclusión de leaflet.css, leaflet.js, contenedor accessMap y script initLeafletMap con respuesta HTTP 200.
#25
MEJORA-025 Desplegado en Producción Seguridad / Privacidad RGPD / Control de Acceso / Ergonomía UI
2026-09-02 21:00

Eliminación de Sondeo Intrusivo en Recargas y Exención de Control GPS por Privacidad RGPD

Problema o Necesidad Detectada:
  1. Al navegar o recargar cualquier página del ERP, el navegador solicitaba repetitivamente la ubicación geográfica de forma intrusiva.
  2. En el servidor, cada recarga disparaba un pulso con desplazamiento falso (+999999m), saturando el registro de auditoría.
  3. Los empleados que expresamente solicitaron no rastrear su ubicación (derecho a la privacidad / RGPD) o cuyos dispositivos carecen de GPS quedaban bloqueados sin poder entrar a trabajar remotamente.
Solución Técnica y Funcional Aplicada:
  • Eliminación Total de Sondeo en Recargas: Suprimido el script de sondeo continuo en timeclock/templates/timeclock/base.html. La geolocalización solo se solicita 1 única vez durante el inicio de sesión en login.html.
  • Corrección de Cálculo de Desplazamiento: En api_actualizar_ubicacion_seguridad (timeclock/views.py), si no existen coordenadas previas en sesión, el desplazamiento se fija en 0 (sin generar falsos registros). Solo se audita si hay un movimiento físico real de más de 1 km y tras al menos 30 minutos.
  • Limpieza de Base de Datos: Eliminados los registros espurios generados en pruebas anteriores.
  • Nuevo Campo y Switch de Exención en Empleado (timeclock/models.py & rrhh/templates/rrhh/empleado_form.html):
    • Añadido campo exento_control_gps al modelo Empleado (migración 0085 aplicada en todos los esquemas multi-tenant).
    • Switch en la ficha de edición de empleado: [x] Exento de Control GPS / Privacidad RGPD (Autorizado por Dirección).
  • Acceso Remoto Sin Rastreo para Empleados Exentos:
    • En CustomLoginView.form_valid, si el empleado está exento (o es directivo/socio), accede directamente desde cualquier localización sin exigir GPS ni almacenar coordenadas, registrándolo en auditoría como [ACCESO REMOTO / EXENTO GPS].
Pruebas de Verificación y Validación:
  • Validado en manage.py shell con esquema soseinsa:
    • Empleado con exento_control_gps=True inicia sesión sin bloqueo ni GPS.
    • 0 solicitudes de geolocalización en recargas y navegación.
    • manage.py check con 0 errores.
#24
MEJORA-024 Desplegado en Producción Seguridad / Anti-Espionaje / Control Perimetral / Geocercado / Auditoría en Tiempo Real
2026-09-02 20:30

Control de Acceso Perimetral (Geocercado Anti-Espionaje) y Auditoría Dinámica en Desplazamiento

Problema o Necesidad Detectada:

Para prevenir el espionaje industrial, el uso indebido de credenciales compartidas o el acceso a datos estratégicos de la empresa desde ubicaciones no autorizadas, la dirección necesitaba: 1. Si un usuario se encuentra fuera de las instalaciones/sede de la empresa, obligarle a compartir su ubicación GPS para poder entrar. 2. Si el usuario se niega a entregar su ubicación estando fuera de la oficina, bloquear el acceso preventivamente. 3. Si un usuario ya ha iniciado sesión legítimamente y durante su jornada de trabajo se desplaza físicamente a otra localización, capturar automáticamente en segundo plano su nueva posición y registrar un pulso de auditoría con el desplazamiento. 4. Si el usuario se conecta desde la red fija de la oficina (IP corporativa/router sede) o dentro del radio perimetral, permitir el acceso directo como [SEDE CENTRAL] sin molestias.

Solución Técnica y Funcional Aplicada:
  • Ampliación del Modelo Empresa (empresas/models.py):
    • Nuevos campos perimetrales: latitud_sede, longitud_sede, radio_sede_metros (por defecto 500m), ip_sede (IP corporativa del router) y switch exigir_gps_fuera_sede.
    • Método esta_en_sede(ip=None, lat=None, lon=None) con cálculo geodésico de gran círculo (fórmula de Haversine) con radio de la Tierra a nivel submétrico.
    • Migración empresas.0010 ejecutada y aplicada en todos los esquemas multi-tenant.
  • Bloqueo y Exigencia Perimetral en Login (timeclock/views.py & templates/registration/login.html):
    • En CustomLoginView.form_valid: si la empresa tiene activo exigir_gps_fuera_sede y el usuario no está en la sede ni entrega coordenadas, se bloquea el formulario con el mensaje: 🔒 ACCESO PERIMETRAL: Estás accediendo desde fuera de las instalaciones de la empresa. Por seguridad, es obligatorio permitir y activar la geolocalización en tu navegador o dispositivo para poder entrar.
  • Endpoint de Actualización y Auditoría en Desplazamiento (timeclock/views.py):
    • Endpoint /api/seguridad/actualizar-ubicacion/ para recibir pulsos asíncronos en segundo plano (latitud, longitud).
    • Compara con las coordenadas previas de la sesión (last_geo_lat, last_geo_lon). Si el usuario se ha desplazado más de 250 metros, crea automáticamente un registro en RegistroAccesoLogin etiquetado como [EN DESPLAZAMIENTO] (+XXXm) junto a su User-Agent, fecha, hora e IP.
  • Monitor en Segundo Plano en Frontend (timeclock/templates/timeclock/base.html):
    • Script para usuarios autenticados que escucha navigator.geolocation.watchPosition y sondeos periódicos cada 5 minutos.
    • Calcula en el navegador la distancia recorrida mediante Haversine antes de emitir peticiones, evitando sobrecarga de red y enviando el pulso a la API de seguridad únicamente cuando hay un cambio de posición significativo (>250m).
  • Panel C-Suite de Configuración de Sede y Mapa de Perímetro (timeclock/templates/timeclock/direccion_seguridad.html):
    • Pestaña interactiva Perímetro y Sede (Anti-Espionaje) y botón directo en cabecera.
    • Mini-mapa Leaflet interactivo con marcador arrastrable y círculo perimetral dinámico que se redimensiona en tiempo real al cambiar el radio (250m, 500m, 1.000m, 2.500m).
    • Botones de acción instantánea: "🎯 Capturar mi ubicación actual como Sede" y "🌐 Usar mi IP actual".
    • El mapa general de conexiones dibuja el perímetro oficial de la sede corporativa en azul (L.circle) y el pin de la oficina central para comparar visualmente los accesos remotos y desplazamientos de la plantilla.
Pruebas de Verificación y Validación:
  • Test unitario y sintético ejecutado en manage.py shell con esquema soseinsa:
    • En sede por IP: True.
    • En sede por GPS dentro de radio (100m): True.
    • Fuera de sede (Madrid a 400km): False.
    • Simulación de desplazamiento >1.200m: crea registro de auditoría [EN DESPLAZAMIENTO] (+1212m) y responde HTTP 200 JSON.
    • Guardado de sede y radio en base de datos verificado con redirección 302 y persistencia en modelo.
#23
MEJORA-023 Desplegado en Producción Seguridad / Autenticación / Geolocalización GPS / Auditoría de Accesos
2026-09-02 20:00

Corrección y Pre-Captura Asíncrona de Geolocalización GPS en Inicio de Sesión

Problema o Necesidad Detectada:

En el panel de ciberseguridad (/direccion/seguridad/), los inicios de sesión recientes aparecían frecuentemente como "Sin ubicación / SIN UBICACION" debido a: 1. Un fallo de sintaxis en el cierre de la función de envío de formulario en el script JavaScript de templates/registration/login.html. 2. La solicitud de geolocalización se realizaba exclusivamente en el momento de pulsar "Entrar" con un timeout demasiado corto (1.6s), haciendo que si el navegador no entregaba las coordenadas inmediatamente, el formulario se enviara sin coordenadas.

Solución Técnica y Funcional Aplicada:
  • Pre-captura Asíncrona en Segundo Plano (precapturarUbicacion): En cuanto la pantalla de login se carga (DOMContentLoaded), el navegador inicia silenciosamente la obtención de coordenadas GPS mientras el usuario escribe su DNI/usuario y PIN. Cuando pulsa "Entrar", las coordenadas ya están disponibles instantáneamente (0 ms de espera).
  • Fallback con Timeout Ampliado: Si el usuario pulsa "Entrar" antes de que la pre-captura finalice, se espera hasta 2.0s para resolver las coordenadas con alta precisión (enableHighAccuracy: true).
  • Extracción Blindada en Backend (CustomLoginView): Parseo seguro tanto de form.cleaned_data como de request.POST con conversión controlada a números decimales y almacenamiento en RegistroAccesoLogin.
Pruebas de Verificación y Validación:
  • Validado mediante script de prueba simulando peticiones de autenticación con coordenadas GPS y comprobando el guardado exacto de latitud y longitud en RegistroAccesoLogin.
#22
MEJORA-022 Desplegado en Producción Navegación / UI-UX / Menú Lateral (Sidebar) / Dirección / Seguridad
2026-09-02 19:50

Desglose de Accesos en Menú Lateral: Panel de Control y Sistemas & Seguridad

Problema o Necesidad Detectada:

En la sección "Dirección & Sistemas" del menú lateral (timeclock/base.html) existía únicamente un acceso englobado bajo el nombre "Panel Ejecutivo", dificultando a los directores acceder de forma directa y clara al Panel de Control financiero/operativo y al nuevo módulo de Sistemas y Seguridad (/direccion/seguridad/).

Solución Técnica y Funcional Aplicada:
  • Estructuración en Dos Bloques Independientes:
    1. Panel de Control (direccion_home):
    2. Icono de velocímetro (bi-speedometer2), acceso directo al cuadro de mando financiero (KPIs, rentabilidad, actividad diaria, proyectos, incidencias y Kanban).
    3. Sistemas & Seguridad (direccion_seguridad / direccion_seguridad_dashboard):
    4. Icono de escudo de seguridad (bi-shield-lock-fill), acceso directo al panel de ciberseguridad y auditoría (conexiones de trabajadores, geolocalización GPS, fichajes/terminales, bloqueos IP, intentos fallidos y dispositivos IoT/actuadores).
    5. Añadido alias de URL name='direccion_seguridad' en timeclock/urls.py para compatibilidad completa.
Pruebas de Verificación y Validación:
  • Validado en manage.py shell con esquema soseinsa confirmando que ambas rutas (/direccion/ y /direccion/seguridad/) renderizan con código HTTP 200 y destacan activamente su correspondiente elemento en el menú lateral.
#21
MEJORA-021 Desplegado en Producción Kiosko / Rendimiento / Base de Datos / Optimización ORM
2026-09-02 19:40

Optimización de Rendimiento y Eliminación de Queries N+1 en Kiosko (/kiosko/acciones/)

Problema o Necesidad Detectada:

La pantalla principal del Kiosko (/kiosko/acciones/) tardaba más de 5.9 segundos en cargar debido a más de 54 consultas SQL por petición, provocadas principalmente por: 1. Llamadas a inc.get_foto() en cada una de las 26 incidencias del bucle (consultando ContentType y ProjectImage más de 26 veces de forma síncrona, cuando la foto ni siquiera se renderizaba). 2. Múltiples consultas separadas al modelo Fichaje para calcular el estado, el último fichaje, el primer fichaje de hoy y el conteo. 3. Llamada a {{ notificaciones.count }} en la plantilla ejecutando un SELECT COUNT(*) adicional en base de datos.

Solución Técnica y Funcional Aplicada:
  • Eliminación del Cuello de Botella N+1: Retirada la llamada innecesaria a get_foto() en el diccionario de incidencias abiertas.
  • Consolidación de Fichajes en Memoria: Una única consulta fichajes_hoy recupera los fichajes del día y calcula en Python en 0ms el primer fichaje, último fichaje y estado del operario.
  • Uso de select_related('user') en Empleado: Evita consultas lazy adicionales a auth_user.
  • Optimización de Template: Reemplazado {{ notificaciones.count }} por {{ notificaciones|length }}.
  • 📈 Resultados:
  • Consultas SQL: Reducidas de 54 queries a 23 queries (-57% de tráfico a base de datos).
  • Tiempo de Carga: Reducido de 5.910 ms a ~2.900 ms (más del doble de velocidad).
Pruebas de Verificación y Validación:
  • Medido y validado con benchmark de profiling en manage.py shell con esquema soseinsa, certificando respuesta con código HTTP 200, renderizado íntegro y reducción de tiempo demostrada.
#20
MEJORA-020 Desplegado en Producción Kiosko / Control Horario / UI-UX / Ergonomía Táctil
2026-09-02 19:25

Control Táctil Condicional de Entrada y Salida según Estado en Kiosko (/kiosko/acciones/)

Problema o Necesidad Detectada:

En la pantalla principal del terminal Kiosko (/kiosko/acciones/), los botones de Entrada y Salida aparecían siempre activos y con color brillante simultáneamente, pudiendo causar confusión a los operarios sobre qué acción correspondía pulsar en cada momento (ej. intentar fichar entrada cuando ya estaban dentro o salida cuando estaban fuera).

Solución Técnica y Funcional Aplicada:
  • Lógica de Estado Condicional en Template:
    • Si el trabajador está DENTRO (estado == 'DENTRO'):
    • El botón Entrada pasa a modo bloqueado y grisáceo (action-card-disabled) con icono de confirmación y texto (Ya Registrada).
    • El botón Salida permanece activo, interactivo y en color destacado listo para registrar el fin de jornada y parte de trabajo (Finalizar & Parte).
    • Si el trabajador está FUERA (estado != 'DENTRO'):
    • El botón Entrada permanece activo en verde vibrante (action-card-in) con texto Iniciar Jornada.
    • El botón Salida pasa a modo bloqueado y grisáceo (action-card-disabled) con icono de candado y texto (Ficha entrada primero).
  • Estilos de Atenuación Ergonómica (action-card-disabled):
    • Gradiente neutro suave, opacidad reducida (opacity: 0.40), escala de grises (filter: grayscale(0.85)), puntero bloqueado (cursor: not-allowed; pointer-events: none;) y eliminación de efectos de elevación táctil para transmitir claramente la indisponibilidad de la acción.
Pruebas de Verificación y Validación:
  • Validado en manage.py shell con esquema soseinsa tanto para trabajadores con jornada activa (DENTRO) como fuera de jornada (FUERA), confirmando que se renderizan con código HTTP 200 las clases y textos correspondientes.
#19
MEJORA-019 Desplegado en Producción RRHH / Gestión de Personal / Vacaciones & Permisos / UI-UX
2026-09-02 19:10

Visualización de Días de Vacaciones Disponibles y Consumidos en Plantilla de Empleados (/rrhh/empleados/)

Problema o Necesidad Detectada:

En el listado principal de empleados (/rrhh/empleados/) no se mostraba el balance de vacaciones de cada trabajador (días asignados, consumidos y disponibles en el año en curso), lo que obligaba a acceder a la configuración específica de vacaciones o a la ficha individual para consultar estos datos.

Solución Técnica y Funcional Aplicada:
  • Cálculo Masivo Optimizado sin N+1:
    • En empleado_lista (rrhh/views.py), se calcula de forma centralizada en solo dos consultas agregadas (AsignacionVacaciones y SolicitudAusencia aprobadas de tipo VACACIONES en el año en curso) el saldo para todos los empleados de la lista.
    • Se tienen en cuenta las proporcionalidades para altas en el año actual (22 días o prorrateo según fecha de alta).
  • Columna Dedicada de Vacaciones en la Tabla:
    • Incorporada columna interactiva con chips de colores inteligentes según días disponibles:
    • 🟢 Verde: > 5 días disponibles.
    • 🟡 Ámbar: 1 a 5 días disponibles.
    • 🔴 Rojo: 0 o negativos (saldo agotado/excedido).
    • Desglose detallado: Días Disponibles, contador de Consumidos / Total y mini barra de progreso porcentual.
Pruebas de Verificación y Validación:
  • Validado en manage.py shell con esquema soseinsa comprobando que responde con código HTTP 200 y renderiza correctamente los saldos de todos los empleados en ambas pestañas (altas y bajas).
#18
MEJORA-018 Desplegado en Producción Kiosko / Producción / Taller / Incidencias / Operativa de Planta
2026-09-02 18:50

Panel de Incidencias Abiertas y Cierre Rápido en Terminal Kiosko (/kiosko/acciones/)

Problema o Necesidad Detectada:

Los operarios y trabajadores no veían en su panel de Kiosko (/kiosko/acciones/) las incidencias que tenían abiertas o asignadas en sus proyectos y armarios de trabajo. Para cerrarlas o reportar su estado debían navegar por múltiples menús o requerían permisos de dirección, dificultando el seguimiento diario y el desbloqueo ágil de armarios en producción.

Solución Técnica y Funcional Aplicada:
  • Consulta Unificada de Incidencias por Trabajador:
    • En kiosko_acciones (timeclock/views.py), se consultan en tiempo real las incidencias abiertas (ABIERTA, EN_CURSO, EN_ESPERA) asignadas al empleado, creadas por él, o vinculadas a sus proyectos y armarios asignados (Incidencia de taller, IncidenciaProyecto, IncidenciaUnidad).
    • Se unifican en la lista contextual mis_incidencias_abiertas con badges de tipo, estado, fecha relativa y horas imputadas.
  • Nueva Vista de Cierre Rápido (kiosko_incidencia_cerrar):
    • Implementada vista @require_http_methods(["POST"]) en timeclock/views.py y registrada en timeclock/urls.py.
    • Permite a los operarios cerrar la incidencia (CERRADA / RESUELTA), cambiarla a EN_CURSO o EN_ESPERA, imputar horas reales dedicadas y añadir un comentario explicativo de la solución.
    • Si el armario estaba BLOQUEADO y no quedan incidencias bloqueantes, transiciona automáticamente el estado del armario a EN_CURSO.
    • Soporte completo para AJAX (JSON) y formularios estándar.
  • Interfaz C-Suite Táctil en kiosko_acciones.html:
    • Tarjeta destacada con cabecera de alerta, contador de incidencias pendientes y grid responsive de tarjetas de incidencia.
    • Modal interactivo táctil para cada incidencia con selectores rápidos, campos de horas y comentario de resolución.
    • Handler JavaScript handleCierreIncidencia para actualización asíncrona fluida sin parpadeos.
Pruebas de Verificación y Validación:
  • Validado en manage.py shell con esquema soseinsa tanto para operarios con múltiples incidencias (ej. ***66828*, ***60525*) como para el endpoint de resolución AJAX, respondiendo con código HTTP 200 y confirmación JSON {"status": "success"}.
#17
MEJORA-017 Desplegado en Producción Dirección / Seguridad / Auditoría de Accesos / Geolocalización GPS / WAF
2026-09-02 18:40

Auditoría de Conexiones de Empleados, Geolocalización GPS y Seguridad Perimetral (/direccion/seguridad/)

Problema o Necesidad Detectada:

El panel de seguridad (/direccion/seguridad/) se mostraba completamente vacío debido a que únicamente consultaba tablas de bloqueos (BloqueoSeguridadIP) e intentos fallidos (IntentoLoginFallido), las cuales estaban en 0 registros. No mostraba los más de 3.500 inicios de sesión reales de trabajadores almacenados en RegistroAccesoLogin ni sus 1.215 coordenadas GPS capturadas, ni capturaba la IP cliente en el modelo.

Solución Técnica y Funcional Aplicada:
  • Ampliación del Modelo RegistroAccesoLogin:
    • Añadido campo ip_address con índice en timeclock/models.py y aplicada migración 0084 en todos los esquemas multi-tenant.
    • Implementadas propiedades para detección inteligente de dispositivo/navegador (dispositivo_info: iPhone, Android, Mac, Windows, Linux, Safari, Chrome...), detección de coordenadas (tiene_gps) y enlace automático a Google Maps (google_maps_url).
  • Captura Automática de IP en Inicios de Sesión:
    • CustomLoginView.form_valid extrae la IP real del cliente mediante get_client_ip(self.request) y la persiste en cada login.
  • Dashboard C-Suite Multidimensional con 5 Pestañas:
    1. Conexiones de Empleados: Tabla detallada con avatares, nombres, DNI, departamento, timestamp relativo, IP, badges de dispositivo/navegador y coordenadas GPS con botón de apertura en Google Maps y paginación rápida (40/pág).
    2. Mapa Interactivo de Ubicaciones (Leaflet + OpenStreetMap): Renderizado cartográfico en tiempo real de los logins de empleados con pines interactivos, popups con datos del trabajador, dispositivo y enlace directo a Google Maps con zoom centrado automático (fitBounds).
    3. Fichajes & Terminales: Auditoría de fichajes (Fichaje), tipos de evento (Entrada/Salida) y terminales de origen (tablet-kiosko, móvil o web).
    4. Bloqueos de Seguridad IP: Control de listas negras, reincidencias y botón de desbloqueo manual vía AJAX.
    5. Registro de Intentos Fallidos: Auditoría de credenciales inválidas y User Agents atacantes.
  • Filtros Avanzados en Vivo:
    • Buscador por texto (empleado, DNI, IP, navegador), selector de estado GPS (Todos, Solo con GPS, Sin coordenadas) y selector de dispositivo (Móviles, PC/Mac).
Pruebas de Verificación y Validación:
  • Comprobado en manage.py shell en esquema soseinsa respondiendo 200 OK en todas las rutas y filtros (/direccion/seguridad/, ?tab=mapa, ?gps=con_gps&dispositivo=movil) con renderizado completo de más de 3.500 conexiones y visualización de mapa con 150 coordenadas.
#16
MEJORA-016 Desplegado en Producción Dirección / Cuadro de Mando Ejecutivo / Finanzas / UI-UX C-Suite
2026-09-02 18:20

Rediseño C-Suite del Cuadro de Mando Estratégico de Dirección (/direccion/)

Problema o Necesidad Detectada:

El panel centralizado de dirección (/direccion/) presentaba limitaciones operativas y visuales: 1. Estaba fijado de forma rígida al mes en curso sin posibilidad de consultar meses anteriores o navegar por periodos históricos. 2. Carecía de herramientas visuales interactivas para análisis de tendencias de rentabilidad y desglose de costes. 3. La estructura consistía en una pila vertical monótona de tarjetas sin jerarquía ejecutiva ni filtros en tablas. 4. No proporcionaba métricas explícitas de margen operativo (EBITDA teórico proyectado) ni alertas directivas inteligentes.

Solución Técnica y Funcional Aplicada:
  • Selector Temporal Dinámico:
    • Añadido soporte para ?mes=MM&año=YYYY con auto-submit, botones de salto rápido de mes anterior/siguiente y acceso directo a "Hoy / Mes en Curso".
  • Hero Ribbon Ejecutivo (4 KPIs Clave):
    • Facturación Emitida vs Compras.
    • Coste de Personal Total (Bruto, SS Empresa, Neto).
    • Flujo de Caja Teórico Mensual.
    • Margen Operativo Bruto (EBITDA Teórico Estimado) y % de Rentabilidad con semáforo inteligente.
  • Visualización Interactiva con Chart.js:
    • Gráfico de Tendencia Financiera (6 Meses): Comparativa histórica de Facturación vs Compras vs Masa Salarial.
    • Gráfico Donut de Estructura de Costes: Reparto porcentual entre Personal, Compras/Suministros, Gastos Fijos e Impuestos.
  • Navegación Segmentada por Pestañas:
    • [Finanzas & Tesorería], [Operaciones & Pipeline], [Control de Nóminas], [Presencia & Equipo Hoy] y [Accesos Rápidos].
  • Buscadores Instantáneos en Tiempo Real (JavaScript 0ms):
    • Filtrado en vivo de trabajadores en la tabla de nóminas y en la tabla de presencia diaria.
  • Exclusión Contable de Albaranes de Cliente:
    • Se garantiza que los albaranes de material aportado por clientes (origen='CLIENTE') se excluyen estrictamente del cálculo de previsión de albaranes pendientes de facturar (prevision_albaranes_mes), computando únicamente compras reales a proveedores (origen='COMPRA').
  • Alertas Directivas Contextuales:
    • Avisos inteligentes para incidencias abiertas, nóminas en borrador, albaranes recibidos sin factura y partes sin validar.
Pruebas de Verificación y Validación:
  • Validado en manage.py shell con esquema multi-tenant soseinsa tanto en mes actual como en meses filtrados (?mes=7&año=2026), respondiendo con código HTTP 200 y renderizado íntegro de todos los componentes y gráficos.
#15
MEJORA-015 Desplegado en Producción RRHH / Rendimiento ORM / Optimización N+1
2026-09-02 16:25

Optimización Extrema del Listado de Empleados (Reducción de 177 a 11 Consultas SQL)

Problema o Necesidad Detectada:

La carga de la vista de empleados (/rrhh/empleados/) era notablemente lenta (más de 16 segundos en SOSEIN) debido a: 1. Problema N+1 en Empleado.rol_sistema: La propiedad llamaba repetidamente a self.user.groups.filter(...), invalidando la caché de prefetch_related y disparando hasta 3 consultas a la base de datos por cada fila y por cada acceso en la plantilla. 2. Conteo de documentos en plantilla: Se invocaba emp.documentos.count en cada fila en lugar de aprovechar los documentos precargados en memoria. 3. Cálculo redundante de KPIs: Se ejecutaban 5 consultas de agregación y joins sobre grupos para los contadores superiores.

Solución Técnica y Funcional Aplicada:
  • Optimización de rol_sistema en timeclock/models.py:
    • Modificado para evaluar los nombres de grupos directamente sobre la lista en memoria self.user.groups.all(), aprovechando al 100% prefetch_related('user__groups') con 0 consultas extra a la base de datos.
  • Optimización de Plantilla en rrhh/templates/rrhh/empleado_lista.html:
    • Sustituido {{ emp.documentos.count }} por {{ emp.documentos.all|length }} para usar la caché en memoria.
  • Cálculo O(N) en memoria de KPIs en rrhh/views.py:
    • Los totales de roles (Dirección, Gestor, Operaciones y Socios) se calculan en una sola pasada en Python sobre la lista precargada.
Pruebas de Verificación y Validación:
  • Benchmark en manage.py shell: Las consultas se redujeron de 177 queries a 11-19 queries (reducción del 89%), logrando tiempos de respuesta instantáneos.
#14
MEJORA-014 Desplegado en Producción RRHH / Directorio de Personal / UI & Accesibilidad
2026-09-02 16:20

Rediseño de Alto Contraste para Avatares y Distintivo de Socios

Problema o Necesidad Detectada:

En el listado general de empleados (/rrhh/empleados/), los trabajadores configurados como socios se renderizaban con una combinación de clases Bootstrap (bg-warning bg-opacity-20 text-warning) que provocaba que las iniciales fuesen amarillas sobre fondo amarillo, quedando invisibles y mostrando un círculo naranja sólido. Asimismo, el distintivo de socio bajo el rol de dirección usaba un emoji que perdía definición.

Solución Técnica y Funcional Aplicada:
  • Avatar de Socios con Alto Contraste:
    • Diseñado un degradado ámbar/dorado prémium (linear-gradient(135deg, #f59e0b, #d97706)) con iniciales en blanco nítido (#ffffff), borde dorado y micro-badge flotante inferior derecho con la estrella de socio (bi-star-fill).
  • Distintivo de Socio Nítido:
    • Reemplazado el emoji por un badge estilizado con fondo ámbar suave, borde definido y tipografía en negrita (<i class="bi bi-star-fill text-warning"></i> Socio).
Pruebas de Verificación y Validación:
  • Renderizado validado con manage.py shell en ambos esquemas (soseinsa y cenitsmartfarmingsl), con contraste tipográfico óptimo e iniciales legibles.
#13
MEJORA-013 Desplegado en Producción BBDD / Limpieza de Datos Multi-Tenant / RRHH & Contabilidad
2026-09-02 16:15

Depuración y Eliminación Completa de Registros Duplicados de Empleado en SOSEIN

Problema o Necesidad Detectada:

Debido al fallback silencioso histórico previo a MEJORA-009, el empleado Operario de Planta (***46791*) fue creado erróneamente en el esquema de SOSEIN S.A. junto a una nómina escaneada y la subcuenta contable 465.20, cuando su relación laboral pertenece a CENIT 2030 S.L.

Solución Técnica y Funcional Aplicada:
  • En el esquema soseinsa:
    • Eliminada la nómina duplicada ID 10.
    • Eliminada la subcuenta contable asignada 465.20.
    • Eliminado por completo el registro de empleado ***46791*.
  • En el esquema cenitsmartfarmingsl (CENIT):
    • Verificado que su ficha de empleado, nóminas (ID 6 y 7) y subcuenta contable 465.03 permanecen 100% íntegras y operativas.
Pruebas de Verificación y Validación:
  • Consulta en manage.py shell confirmando que ***46791* no existe en soseinsa (resultado None) y que su ficha en cenitsmartfarmingsl responde HTTP 200 OK.
#12
MEJORA-012 Desplegado en Producción RRHH / Plantillas / Enrutamiento de Nóminas
2026-09-02 16:10

Corrección de Enrutamiento de Nóminas y Primary Key DNI en Ficha de Empleado

Problema o Necesidad Detectada:

Al abrir la edición de empleados que disponían de nóminas subidas (como ***46791* Operario de Planta), la plantilla arrojaba un error 500 NoReverseMatch debido a que la etiqueta de enlace invocaba una ruta inexistente (financiero_nominas) y pasaba el atributo empleado.id en lugar de la clave primaria del modelo (empleado.dni o empleado.pk).

Solución Técnica y Funcional Aplicada:
  • Corregido el enlace de acceso directo en rrhh/templates/rrhh/empleado_form.html para apuntar a la URL oficial {% url 'nomina_lista' %}?empleado={{ empleado.dni }}.
  • Ajustado el enlace de ausencias a {% url 'rrhh_gestion' %}.
Pruebas de Verificación y Validación:
  • Prueba de renderizado ejecutada con éxito en manage.py shell para el empleado ***46791* en ambos esquemas (cenitsmartfarmingsl y soseinsa), obteniendo respuesta HTTP 200 con el badge de nóminas operativo.
#11
MEJORA-011 Desplegado en Producción UI / Base Layout / Navegación Multi-Tenant
2026-09-02 16:05

Eliminación de Selector Desplegable de Empresas y Fijación de Branding Estático

Problema o Necesidad Detectada:

Tanto en la barra superior (topbar) como en la cabecera del menú lateral (sidebar) se mostraba un selector desplegable interactivo ("CAMBIAR ORGANIZACIÓN") que listaba otras empresas del sistema. Esta opción resultaba confusa e innecesaria dentro de una sesión activa, ya que el cambio de sociedad debe gestionarse de forma explícita cerrando sesión y seleccionando la entidad en la pantalla de bienvenida.

Solución Técnica y Funcional Aplicada:
  • Supresión Completa de Menús Desplegables de Cambio de Empresa:
    • Eliminado el botón y dropdown interactivo "Cambiar Organización" de la barra superior en timeclock/templates/timeclock/base.html.
    • Convertida la cabecera del sidebar en un bloque de identidad estático, limpio y corporativo que muestra el logotipo, nombre de la sociedad activa y CIF del tenant actual.
  • Limpieza de Inyección de Contexto Global:
    • Eliminada la consulta y variable empresas_disponibles en empresas/context_processors.py para evitar fugas innecesarias de listados de sociedades en el contexto de plantilla.
Pruebas de Verificación y Validación:
  • Renderizado validado con manage.py check y prueba en manage.py shell: 0 dropdowns de conmutación en topbar ni sidebar, visualización limpia del entorno de trabajo activo.
#10
MEJORA-010 Desplegado en Producción RRHH / Gestión de Personal / Ficha de Empleado
2026-09-02 16:00

Rediseño Premium y Modular de la Ficha de Empleado (Edición y Alta)

Problema o Necesidad Detectada:

La vista de edición de empleado (/rrhh/empleados/<id>/editar/) utilizaba un layout angosto y desestructurado (col-md-8 col-lg-6) con campos apilados sin jerarquía visual, multi-select nativo tosco para departamentos ("mantén Ctrl"), sin resumen del perfil en cabecera y con una sección de documentación poco integrada.

Solución Técnica y Funcional Aplicada:
  • Hero Header de Identidad del Empleado:
    • Cabecera estilo tarjeta oscura con degradado, avatar con iniciales dinámicas, nombre completo, badges de estado (Activo/Baja), rol en sistema (Dirección, Gestor, Operaciones), insignia societaria y accesos directos a nóminas vinculadas y ausencias.
  • Layout Modular de 2 Columnas (8/4):
    • Sección 1 (Identidad & Datos Personales): DNI/NIE, NUSS, PIN de 4 dígitos con toggle de visibilidad (ojo 👁️), Fecha de Alta, Nacimiento, Nombre y Apellidos.
    • Sección 2 (Rol & Áreas de Trabajo Permitidas):
    • Selector de Rol Segmentado con 3 Cards: 🔧 Operaciones, 📋 Gestor y 🛡️ Dirección con sincronización instantánea y descripciones claras.
    • Grid de Áreas / Departamentos Interactivas: Checkboxes visuales con iconos temáticos y botones de acción rápida ("Marcar todas" / "Desmarcar").
    • Sección 3 (Condición Societaria & Tesorería): Switch para socios/administradores (Cta. 551), porcentaje de participación en capital, subcuenta contable asignada e IBAN personal.
    • Sección 4 (Contacto, Vestuario & Ajustes): Emails corporativos, teléfonos con iconos, selector visual de tallas (Chaqueta, Pantalón, Zapato) y switches de visibilidad en directorio.
    • Columna Lateral (Repositorio Documental Digital):
    • Formulario integrado de subida con clasificación por tipo (Contrato, DNI, CV, Título, Nómina).
    • Listado de documentos con previsualización, descarga directa y eliminación segura.
    • Barra Flotante de Acciones Inferior:
    • Atajo de teclado universal Ctrl+S / ⌘S para guardar de forma instantánea.
Pruebas de Verificación y Validación:
  • Validación con manage.py shell en esquemas soseinsa y cenitsmartfarmingsl: renderizado HTTP 200 con 0 errores de template tags y validación de componentes interactivos.
#09
MEJORA-009 Desplegado en Producción Multi-Tenant / Seguridad / Middleware / Enrutamiento
2026-09-02 15:55

Bloqueo de Fallback Silencioso y Control Estricto de Aislamiento de Organización

Problema o Necesidad Detectada:

Al entrar directamente a cualquier URL interna (ej: /rrhh/empleados/, /facturacion/, etc.) sin tener una empresa seleccionada ni cookie activa, el servidor ejecutaba un fallback silencioso que asignaba automáticamente la empresa matriz (soseinsa). Esto provocaba que cualquier alta o acción realizada por error se registrara en SOSEIN aunque el usuario creyera estar en otro entorno.

Solución Técnica y Funcional Aplicada:
  • Eliminación Total del Fallback Silencioso:
  • Control de Aislamiento e Intercepción de Acceso:
    • Si una petición intenta acceder a una ruta protegida/interna mientras el esquema activo es public, el middleware intercepta la llamada de forma segura:
    • Navegación Web (HTML): Redirige limpiamente al portal central con aviso de selección y preservación de destino: /?seleccionar_empresa=1&next=<path>.
    • Llamadas AJAX / API: Responde con código 403 Forbidden y payload JSON estructurado requiriendo selección previa.
  • Banner de Selección de Organización en Portal Central (landing.html):
    • Al llegar redirigido, se muestra un banner de advertencia destacado solicitando buscar o seleccionar la organización.
    • Se enfoca automáticamente el campo de búsqueda Spotlight.
    • Al seleccionar la empresa, el sistema asienta la cookie active_tenant y redirige inmediatamente al usuario a su URL de destino (next) dentro del tenant correcto.
Pruebas de Verificación y Validación:
  • Test en manage.py shell simulando: acceso anónimo a /rrhh/empleados/ (obtiene redirección 302 a /?seleccionar_empresa=1), búsqueda de CIF de CENIT con next (redirige a la URL interna deseada bajo cenitsmartfarmingsl con cookie de sesión fijada) y acceso a landing pública (mantiene schema public). Todos los tests superados con 0 fugas de tenant.
#08
MEJORA-008 Desplegado en Producción RRHH / Gestión de Empleados / Control de Acceso
2026-09-02 15:50

Visualización de Roles y Permisos de Áreas en Listado de Empleados

Problema o Necesidad Detectada:

En el listado principal de empleados (/rrhh/empleados/) no se mostraba con claridad el rol del usuario en el sistema (Operaciones, Gestor o Dirección), ni las áreas/departamentos específicos a los que tiene permiso de acceso según los departamentos configurados por cada empresa (Fabricación, Instalaciones, Ingeniería, Ganadería, etc.).

Solución Técnica y Funcional Aplicada:
  • Identificación Visual de Roles del Sistema:
    • 🛡️ Dirección: Badge púrpura (#7c3aed) con icono de seguridad para superusuarios, socios y grupo Direccion.
    • 📋 Gestor: Badge azul con icono de gestión para supervisores del grupo Gestores.
    • 🔧 Operaciones: Badge secundario/ámbar para personal de planta, taller y campo.
  • Visualización Granular de Áreas Permitidas:
    • Carga dinámica de los departamentos configurados en la empresa (Departamento.objects.filter(activo=True)).
    • Badges para cada área permitida (Fabricación, Instalaciones, etc.) según los permisos asignados (departamentos_permitidos).
    • Para perfiles de Dirección sin limitación expresa, muestra badge verde distintivo Acceso Global (Todas).
  • Filtros Avanzados y KPIs en Cabecera:
    • Nuevos KPIs de resumen por rol (Dirección, Gestores, Operaciones).
    • Nuevos selectores de filtro en tiempo real por Rol en el Sistema y por Área / Departamento Permitido.
  • Gestión en Ficha de Creación y Edición (EmpleadoForm):
    • Sincronización automática del selector de Rol con los grupos de seguridad de Django (auth_group).
Pruebas de Verificación y Validación:
  • Test en manage.py shell en ambos schemas (cenitsmartfarmingsl y soseinsa): renderizado HTTP 200 con visualización de roles, áreas permitidas y filtros operativos sin errores de plantilla.
#07
MEJORA-007 Desplegado en Producción Multi-Tenant / Navegación / RRHH & Nóminas
2026-09-02 15:45

Selector Instantáneo de Empresa y Diagnóstico de Aislamiento de Empleados

Problema o Necesidad Detectada:

Al acceder al dominio central https://cenit365.com/, el middleware por defecto hacía fallback al tenant soseinsa si no existía cookie previa. Como resultado, al procesar la nómina de un nuevo empleado (Operario de Planta ***46791*) en el extractor de nóminas IA, el sistema lo creó en el esquema de SOSEIN S.A. (cuenta contable 465.20), mientras que el usuario creía estar en el entorno de CENIT.

Solución Técnica y Funcional Aplicada:
  • Selector Desplegable de Organización en Tiempo Real:
    • Integrado en la cabecera del Sidebar (timeclock/templates/timeclock/base.html) y en la Barra Superior (Topbar).
    • Muestra la lista de empresas disponibles (SOSEIN S.A., CENIT 2030 S.L, CENIT SMART FARMING S.L) con la empresa activa destacada mediante un check verde y badge de color.
    • Permite cambiar de empresa en 1 solo clic (?switch_tenant=...) persistiendo la cookie active_tenant.
  • Context Processor Global:
    • Exportada la variable empresas_disponibles en empresas/context_processors.py para tener acceso global sin duplicar consultas en las vistas.
  • Diagnóstico en Base de Datos:
    • Verificado que el empleado existía en cenitsmartfarmingsl (cuenta 465.03) y en soseinsa (cuenta 465.20), explicando exactamente la cronología de subida de nóminas.
Evidencia Gráfica y Captura:
  • 🧪 Verificación:
  • Test en manage.py shell: lista de empresas cargada correctamente, cambio de tenant instantáneo y visibilidad garantizada en la interfaz.

Pruebas de Verificación y Validación:
  • Test en manage.py shell: lista de empresas cargada correctamente, cambio de tenant instantáneo y visibilidad garantizada en la interfaz.
#06
MEJORA-006 Desplegado en Producción Facturación / Albaranes / Procesamiento de Documentos
2026-09-02 15:40

Orientación Automática Inteligente y Herramientas de Rotación de Albaranes (PDF e Imagen)

Problema o Necesidad Detectada:

Al subir albaranes escaneados (ej. Albarán #474 albaran_escaneado.pdf) o fotos tomadas desde smartphones, los documentos aparecían volcados de lado (apaisados u horizontales con rotación física del escáner), dificultando su lectura tanto en el visor de edición como en el modal de consulta.

Solución Técnica y Funcional Aplicada:
  • Servicio de Reorientación (facturacion/services/document_rotator.py):
    • Para PDFs: Analiza las dimensiones (mediabox) y rotación del escáner con pypdf. Si el documento es horizontal, lo rota automáticamente a formato vertical portrait (A4).
    • Para Fotos: Aplica ImageOps.exif_transpose para respetar la orientación del acelerómetro/sensor móvil.
  • Barra de Herramientas de Orientación en Tiempo Real:
    • Botón Auto-Orientar (Varita Mágica inteligente).
    • Botones de giro rápido: 90° ↻ (horario), 90° ↺ (antihorario) y 180° (invertir).
    • Integrado en el Visor de Edición de Albarán (albaran_form.html) y en el Modal de Vista Rápida (albaran_lista.html).
  • Persistencia en Servidor y Azure Blob Storage:
    • Guarda la nueva versión rotada con timestamp para invalidar la caché y actualiza el iframe/imagen en el navegador al instante vía AJAX (/facturacion/compras/albaranes/<id>/rotar/).
Pruebas de Verificación y Validación:
  • Comprobación sobre el Albarán #474 (albaran_escaneado.pdf): rotación exitosa a vertical, persistido en Azure Blob Storage y visible upright en visor.
#05
MEJORA-005 Desplegado en Producción Seguridad / Privacidad / Cumplimiento LOPD & RGPD
2026-09-02 12:20

Garantía de Privacidad LOPD / RGPD y Filtro Central Anti-DNI

Problema o Necesidad Detectada:

En el sistema, el nombre de usuario (User.username) almacena el DNI del empleado. Cuando first_name o last_name estaban vacíos en la base de datos, el sistema hacía fallback al username, imprimiendo el DNI del trabajador en firmas de correos electrónicos dirigidos a proveedores (/facturacion/enviar-email/pedido/...), en los PDFs generados y en tablas públicas. Esto suponía un riesgo de infracción de la legislación de protección de datos (LOPD/RGPD).

Solución Técnica y Funcional Aplicada:
  • Creación del módulo central de privacidad timeclock/utils_privacy.py con:
    • get_nombre_persona_seguro(user): Consulta de forma prioritaria la ficha de Empleado vinculada (nombre y apellidos).
    • Expresión regular de descarte es_identificador_confidencial: Si el texto coincide con un patrón de DNI, NIE o secuencia numérica, es bloqueado de inmediato.
    • Fallback profesional seguro: Si no hay nombre configurado, devuelve "Departamento de Compras", "Administración" o "Equipo Técnico", nunca un DNI.
  • Reemplazo y blindaje en:
    • Redacción predeterminada de emails en enviar_documento_email.
    • Generador de PDF de Pedidos de Compra (generar_pdf_pedido) y Ofertas (generar_pdf_oferta).
    • Filtros de plantilla Django |user_display y |nombre_seguro en people.py, custom_filters.py y presupuestos_extras.py.
Evidencia Gráfica y Captura:

DNI detectado y solucionado en firma

Pruebas de Verificación y Validación:
  • Test unitario simulando el Pedido #344 (P26-0262): la firma del email y el PDF muestran Firmante Autorizado (0 DNIs expuestos).
#04
MEJORA-004 Desplegado en Producción Facturación / Compras / Albaranes / Excel
2026-09-02 10:30

Exportación a Excel Avanzada del Listado Filtrado de Albaranes

Problema o Necesidad Detectada:

En el listado de albaranes (/facturacion/compras/albaranes/), los usuarios necesitaban descargar en formato Excel (.xlsx) el conjunto exacto de albaranes que tenían filtrados en pantalla (por texto de búsqueda q, origen COMPRA/CLIENTE, proveedor o fechas), pero no existía esta opción y la URL daba error de resolución.

Solución Técnica y Funcional Aplicada:
  • Creación de la vista albaran_lista_excel en facturacion/views.py y registro en facturacion/urls.py (compras/albaranes/excel/).
  • Generación de archivo .xlsx estilizado con openpyxl:
    • Cabecera corporativa CENIT 365 / SOSEIN con resumen de filtros activos y fecha/hora.
    • Columnas detalladas: Nº Albarán, Origen, Fecha Recepción, Pedido / Ref., Proveedor / Cliente, Proyecto / Destino, Factura Compra, Estado Factura, Registrado Por, Fecha Registro, Notas y Resumen de Artículos Recibidos.
    • Auto-ajuste de ancho de columnas y estilos visuales optimizados (filas alternas y fuentes tipográficas legibles).
  • Incorporación de botón destacado Exportar Excel en cabecera y enlace rápido Descargar este filtro (.xlsx) en la barra de filtros.
Evidencia Gráfica y Captura:

Filtro de Albaranes Excel Generado

Pruebas de Verificación y Validación:
  • Comprobación con URLs complejas como /facturacion/compras/albaranes/excel/?q=250463&proveedor_id=&origen=CLIENTE: Status HTTP 200, descarga limpia del .xlsx con todas las filas correspondientes.
#03
MEJORA-003 Desplegado en Producción Landing Page / Asistencia / Soporte
2026-09-01 16:00

Canales Oficiales de Soporte Técnico y Contacto CENIT

Problema o Necesidad Detectada:

Los usuarios que accedían a la página principal de CENIT 365 o a la pantalla de creación de empresas no disponían de accesos directos al canal oficial de soporte técnico de https://cenitsf.com/contact/.

Solución Técnica y Funcional Aplicada:
  • Integración de banner de asistencia oficial y pie de página en landing.html y crear.html.
  • Botón directo de WhatsApp Oficial de Asistencia (+34 690 14 38 86) con mensaje predefinido para agilizar consultas.
  • Enlace al portal de contacto e ingeniería industrial de CENIT.
Evidencia Gráfica y Captura:

Soporte Técnico CENIT

Pruebas de Verificación y Validación:
  • Comprobación de enlaces interactivos y apertura directa en WhatsApp Web y móvil.
#02
MEJORA-002 Desplegado en Producción Empresas / Notificaciones / SMTP
2026-09-01 15:15

Notificación Automática por Email de Nuevas Empresas Registradas

Problema o Necesidad Detectada:

Cuando un nuevo cliente o empresa se daba de alta en la plataforma, la dirección técnica y comercial (notificaciones@cenit365.com y administracion@cenit365.com) no recibía ningún aviso inmediato para auditar la nueva cuenta y verificar la activación.

Solución Técnica y Funcional Aplicada:
  • Envío automático de correo electrónico asíncrono/transaccional tras el commit exitoso de creación del tenant.
  • Notificación enviada a los buzones notificaciones@cenit365.com y administracion@cenit365.com.
  • Plantilla HTML y texto plano con todos los detalles de la empresa: Razón Social, CIF, Dominio/Schema asignado, Nombre del Administrador, Email de contacto, Teléfono y Fecha/Hora exacta de alta.
Evidencia Gráfica y Captura:

Notificación por Email

Pruebas de Verificación y Validación:
  • Prueba en entorno de desarrollo y staging: email recibido con formato corporativo correcto y cabeceras SPF/DKIM válidas.
#01
MEJORA-001 Desplegado en Producción Multi-Tenant / Empresas / Registro
2026-09-01 14:30

Validación Previa y Alta Segura de Nuevas Empresas (Multi-Tenant)

Problema o Necesidad Detectada:

Al registrar una nueva empresa desde el formulario público (/crear-empresa/), no se verificaba si el CIF, nombre comercial, subdominio (schema_name) o email del administrador ya existían en la base de datos pública o en otros esquemas de inquilinos, provocando colisiones de esquemas (schema_name already exists) o errores 500 no controlados en PostgreSQL.

Solución Técnica y Funcional Aplicada:
  • Validación previa y exhaustiva en EmpresaCrearForm antes de crear el esquema.
  • Comprobación de unicidad de CIF/NIF normalizado (sin espacios ni guiones), nombre de empresa y subdominio.
  • Validación de que el usuario administrador inicial no colisione con cuentas preexistentes.
  • Mensajes de error claros y localizados en la interfaz para guiar al usuario.
Evidencia Gráfica y Captura:

Formulario de Alta de Empresas

Pruebas de Verificación y Validación:
  • Validación con CIFs duplicados: devuelve alerta en el campo sin tumbar el servidor.
  • Creación de esquema limpio sin afectar al tenant soseinsa ni public.

No se encontraron hitos con ese criterio

Prueba a utilizar términos más genéricos o limpiar los filtros.

MÓDULO 01 · ARQUITECTURA CORE

1. Arquitectura Multi-Tenant y Aislamiento por Esquemas

CENIT 365 opera sobre un modelo de aislamiento estricto por esquemas de base de datos (PostgreSQL Schema Isolation) mediante django-tenants. Cada organización cuenta con su propio espacio de tablas separado físicamente del resto de clientes.

Garantía de Aislamiento y Privacidad:

La base de datos central nunca ejecuta consultas que crucen información entre empresas. Al recibir cada petición, el middleware inspecciona la cookie segura active_tenant o el parámetro ?switch_tenant=... y ejecuta connection.set_tenant(tenant), aislando tablas de facturación, nóminas, fichajes y albaranes.

Estructura de Esquemas

Esquema Propósito Modelos Alojados Acceso Público
public Gestión global de inquilinos, landing corporativa, búsqueda de CIF y registro de empresas. Empresa, Dominio Abierto
[schema_name]
(ej: soseinsa, cenit...)
Datos operativos privados de cada empresa cliente. Factura, Albaran, Empleado, Fichaje, Nomina Aislado / Cifrado

Flujo de Navegación y Cambio de Organización

  • Entrada Inicial: El usuario accede a la landing pública https://cenit365.com/.
  • Búsqueda por CIF: Mediante el endpoint /buscar-empresa/, el sistema localiza el tenant y asienta la cookie active_tenant=<schema>.
  • Escape al Esquema Público: En cualquier momento, el botón de cambiar empresa invoca /?switch_tenant=public, que purga la cookie en el cliente y servidor para devolver al usuario al selector.
MÓDULO 02 · VENTAS & COMPRAS

2. Facturación, Albaranes & Cumplimiento Veri*Factu

Módulo de gestión comercial integral adaptado a las exigencias normativas de la Ley Antifraude y los reglamentos Veri*Factu de la Agencia Tributaria (AEAT).

Ciclo Completo de Gestión Comercial

1. Ofertas & Presupuestos Cálculo de márgenes, desgloses por partidas y exportación de presupuestos a PDF corporativo.
2. Albaranes de Compra y Cliente Recepción con cámara móvil, visor interactivo modal, rotación inteligente de PDFs y exportación a Excel.
3. Factura Electrónica Generación de huella hash encadenada, código QR oficial Veri*Factu y firma digital mediante certificados X.509.

Especificaciones de Integración Veri*Factu

Cada registro de facturación genera un encadenamiento criptográfico con el registro anterior mediante algoritmo SHA-256, garantizando la inalterabilidad de los datos fiscales según el estándar publicado por el Ministerio de Hacienda:

  • Generación de registro de facturación de alta (encabezado XML, datos de emisor y destinatario).
  • Cálculo de huella hash SHA-256 encadenada con la factura previa.
  • Generación de Código Seguro de Verificación (CSV) e inserción de código QR en la plantilla PDF de la factura.
MÓDULO 03 · PRESENCIA LABORAL

3. Control Horario, Geolocalización & Terminal Kiosko

Sistema de registro de jornada laboral adaptado al Real Decreto-ley 8/2019, diseñado tanto para terminales táctiles fijos en taller/planta (Modo Kiosko) como para trabajadores en movilidad y teletrabajo.

Características Operativas del Terminal Kiosko

  • Identificación Rápida: El empleado introduce su DNI y su PIN numérico de seguridad de 4 cifras.
  • Prevención de Fuerza Bruta: El sistema bloquea temporalmente los intentos tras 5 códigos erróneos sucesivos (cuenta atrás de 2 minutos).
  • Cierre Automático de Sesión: Tras registrar la entrada, salida o pausa de desayuno, la sesión se limpia automáticamente para dejar el terminal listo para el siguiente operario.
  • Gestión Rápida de Incidencias: Posibilidad de notificar incidencias técnicas de planta directamente desde la pantalla táctil antes de salir.

Captura GPS y Auditoría de Desplazamiento

En accesos vía navegador web o app móvil, el sistema precaptura de forma asíncrona las coordenadas GPS (latitud y longitud) con alta precisión (timeout 2s) para certificar la presencia física en sedes o centros de trabajo autorizados sin interrumpir la experiencia de usuario.

MÓDULO 04 · INTELIGENCIA ARTIFICIAL

4. Ingeniería IDP con IA (Extracción de Planos Técnicos)

Módulo de Procesamiento Inteligente de Documentos (IDP) diseñado para empresas industriales y de fabricación mecánica, capaz de interpretar planos técnicos en formato PDF y convertirlos en listas de materiales (BOM).

Arquitectura del Motor de Visión

Análisis Vectorial y Bounding Boxes Segmentación de cotas, despieces, cajetines y tablas de materiales mediante algoritmos de geometría computacional.
OCR Multicapa con IA Extracción de referencias, tipos de acero/material, espesores, pesos y tolerancias con soporte de modelos de visión.

Visor Interactivo en JavaScript (PDF.js)

Permite a los ingenieros de oficina técnica inspeccionar el plano original con recuadros interactivos superpuestos sobre cada pieza extraída, editar referencias en caliente y exportar directamente al escandallo de costes de fabricación del ERP.

MÓDULO 05 · RECURSOS HUMANOS

5. RRHH & Extractor Masivo de Nóminas con IA

Gestión centralizada del departamento de personal, contratos, vacaciones anuales y digitalización automática de recibos de nóminas mediante Inteligencia Artificial.

Procesamiento Automatizado de Nóminas

  • Subida en Lote: Los gestores pueden subir archivos PDF individuales o consolidados de las nóminas mensuales de la gestoría.
  • Extracción Semántica: El modelo de visión analiza el recibo y extrae automáticamente: Nombre del Empleado, DNI, Período de Liquidación, Devengos, Total Líquido a Percibir y deducciones de IRPF y Seguridad Social.
  • Asiento Contable Automático: El sistema enlaza la nómina con la ficha del empleado y asigna la cuenta contable 465.XX correspondiente según el esquema de la empresa.
MÓDULO 06 · DIRECCIÓN EJECUTIVA & C-SUITE INTELLIGENCE

6. Dirección Estratégica C-Suite, Inteligencia Financiera & Seguridad Perimetral

Módulo de gobierno corporativo reservado exclusivamente para Directores Generales (CEO), Directores Financieros (CFO), Socios y Gerencia de Operaciones. Proporciona visibilidad en tiempo real de la liquidez proyectada, rentabilidad analítica por proyecto y una consola perimetral con geocercado GPS contra intrusiones.

Aislamiento C-Suite y Restricción por Roles:

El acceso a /direccion/ y /direccion/seguridad/ está blindado por decoradores de autorización que exigen rol de dirección o superusuario en el esquema tenant activo. Las consultas agregan datos exclusivamente del esquema PostgreSQL de la empresa autenticada.

1. Inteligencia Financiera & Tesorería Proyectada

Facturación Neta Desagregada Algoritmo que elimina el efecto distorsionador del IVA (21%, 10%, 4%) y retenciones de IRPF, reflejando el devengo limpio de ingresos, cobrado efectivo y cartera viva.
Previsión Cash Flow (30/60/90d) Cruce automático de vencimientos de facturas de clientes, calendario de pagos a proveedores (albaranes/facturas compra) y costes salariales recurrentes.
Rentabilidad por Proyecto Cálculo en vivo de mano de obra real (horas fichadas × coste/hora de operario) + partidas de materiales imputadas en albaranes = Margen Bruto.

2. Consola de Seguridad Perimetral & Geocercado (/direccion/seguridad/)

Herramienta de auditoría continua diseñada para garantizar la integridad operativa de plantas de fabricación, talleres y oficinas técnicas:

  • Cartografía Interactiva Leaflet Maps: Representación en mapa con agrupación (clustering) de las ubicaciones registradas en accesos y fichajes laborales. Marcadores codificados por color (Verde: En Sede, Ámbar: En Desplazamiento Autorizado, Rojo: Fuera de Zona).
  • Geocercado por Sedes Corporativas: Definición de polígonos de centros de trabajo con coordenadas GPS y radio de tolerancia perimetral en metros (ej. 200 m).
  • Auditoría de Desplazamiento Permisiva: Durante el login, el navegador solicita la posición GPS en segundo plano con un temporizador estricto (2 segundos) para no frenar al usuario. Solo se genera un nuevo evento si se detecta un movimiento físico superior a 1 km y tras al menos 30 minutos desde el último registro.
  • Garantía LOPD / RGPD para Puestos en Teletrabajo: Conmutador individual en la ficha de empleado para eximir de geolocalización a perfiles de teletrabajo o comerciales itinerantes, protegiendo su derecho a la desconexión digital.
  • Listas Blancas de Direcciones IP: Restricción perimetral opcional para impedir conexiones administrativas fuera de las oficinas o redes VPN auditadas.
Métrica / Función Endpoint Frecuencia Nivel de Acceso
Cuadro de Mando Financiero /direccion/ Tiempo Real (Cached 5 min) Dirección / CEO
Mapa Perimetral de Seguridad /direccion/seguridad/ Tiempo Real Seguridad C-Suite
Auditoría GPS en Desplazamiento /api/seguridad/ubicacion/ Asíncrono (Delta > 1 km / 30m) Sesión Activa
¿Deseas activar el módulo C-Suite en tu organización? Crea tu empresa en CENIT 365 con esquema PostgreSQL dedicado y pruébalo gratis.
Darme de Alta Gratis
MÓDULO 07 · DEVOPS & INFRAESTRUCTURA

7. API REST, Infraestructura Azure & Despliegue Continuo

La plataforma CENIT 365 está alojada sobre la infraestructura cloud de Microsoft Azure en el centro de datos de West Europe (Europa Occidental), con arquitectura de alta disponibilidad y copias de seguridad continuas.

Endpoints Públicos de Integración

Método Ruta Descripción Formato
POST /buscar-empresa/ Localización de empresa cliente por CIF o nombre y asignación de cookie de tenant. JSON
GET /api/sugerir-empresas/ Autocompletado predictivo tipo Spotlight para búsqueda instantánea de organizaciones. JSON
GET /api/check-subdominio/ Validación previa de disponibilidad de subdominio durante el alta de empresa. JSON
GET /sitemap.xml Mapa del sitio XML oficial para rastreadores de GoogleBot y Bing con prioridad de alta. XML
Aprovisionamiento Cloud Inmediato

Comienza a Gestionar tu Empresa con CENIT 365 ERP

Da de alta tu organización en 2 minutos. Obtendrás un entorno aislado en PostgreSQL, cumplimiento Veri*Factu garantizado, módulo de control horario táctil y cuadro de mando financiero C-Suite.

Darme de Alta Online Sin permanencia · Esquema privado
SEGURIDAD & CUMPLIMIENTO

Aislamiento Físico y Cumplimiento Normativo RGPD

En el diseño de CENIT 365, la privacidad de los datos de cada cliente no depende de filtros lógicos en consultas SQL (WHERE empresa_id = ...), sino de la separación física por esquemas en PostgreSQL. Esto elimina el riesgo de fuga accidental de información sensible entre organizaciones competidoras.

Cifrado SSL / TLS 1.3 Todas las comunicaciones web y API circulan con cifrado simétrico robusto.
Backups Azure Continuos Copias de seguridad transaccionales periódicas en Azure Blob Storage.
Auditoría C-Suite Registro inalterable de cada inicio de sesión, dirección IP y coordenadas GPS.

Pila Tecnológica Oficial

  • Backend & Framework Python 3.12 · Django 5.x · Gunicorn
  • Base de Datos Multi-Tenant PostgreSQL 16 (django-tenants)
  • Infraestructura Cloud Microsoft Azure App Service · Azure Blob Storage
  • Inteligencia Artificial Gemini Vision API · PDFPlumber · OpenCV