Creacion de rutas de registro de visitas de miembros
This commit is contained in:
342
src/controladores/controlador_Clientes_MiembrosVisitas.js
Normal file
342
src/controladores/controlador_Clientes_MiembrosVisitas.js
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
// src/controladores/controlador_Clientes_MiembrosVisitas.js
|
||||||
|
|
||||||
|
// NO NECESITARÁS 'moment-timezone' NI CÁLCULOS MANUALES COMPLEJOS
|
||||||
|
// const moment = require('moment-timezone');
|
||||||
|
|
||||||
|
// ¡IMPORTANTE: Cambia el nombre de esta constante para que coincida con la importación en rt_clientes.js!
|
||||||
|
const controlador_Clientes_MiembrosVisitas = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function registrarVisita
|
||||||
|
* @description Registra una nueva visita de miembro en la tabla clientes_miembros_visitas.
|
||||||
|
* @param {Object} req - Objeto de solicitud de Express.
|
||||||
|
* @param {Object} res - Objeto de respuesta de Express.
|
||||||
|
*/
|
||||||
|
registrarVisita: (req, res) => {
|
||||||
|
req.getConnection((err, connection) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al obtener conexión para registrar visita:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener conexión', error: err.message });
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
id_miembro,
|
||||||
|
matricula_registrada,
|
||||||
|
nombre_area_acceso,
|
||||||
|
estado_acceso, // 'CONCEDIDO' o 'DENEGADO'
|
||||||
|
motivo_denegacion,
|
||||||
|
registrado_por,
|
||||||
|
observaciones
|
||||||
|
} = req.body;
|
||||||
|
|
||||||
|
// Validación básica de los campos requeridos
|
||||||
|
if (!id_miembro || !matricula_registrada || !nombre_area_acceso || !estado_acceso) {
|
||||||
|
return res.status(400).json({ mensaje: 'Faltan campos obligatorios para registrar la visita (id_miembro, matricula_registrada, nombre_area_acceso, estado_acceso).' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Asegúrate de que estado_acceso sea uno de los valores ENUM permitidos
|
||||||
|
if (!['CONCEDIDO', 'DENEGADO'].includes(estado_acceso.toUpperCase())) {
|
||||||
|
return res.status(400).json({ mensaje: 'El estado de acceso debe ser "CONCEDIDO" o "DENEGADO".' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- SIMPLIFICACIÓN: Usar la fecha nativa de JavaScript ---
|
||||||
|
const now = new Date(); // Esto obtendrá la fecha y hora local del servidor (Quito)
|
||||||
|
|
||||||
|
// Formatear la fecha y hora a 'YYYY-MM-DD HH:mm:ss' para MySQL
|
||||||
|
const year = now.getFullYear();
|
||||||
|
const month = String(now.getMonth() + 1).padStart(2, '0'); // getMonth() es 0-indexado
|
||||||
|
const day = String(now.getDate()).padStart(2, '0');
|
||||||
|
const hours = String(now.getHours()).padStart(2, '0');
|
||||||
|
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||||
|
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||||||
|
|
||||||
|
const fecha_hora_visita = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||||
|
// ---------------------------------------------------
|
||||||
|
|
||||||
|
const query = `
|
||||||
|
INSERT INTO clientes_miembros_visitas
|
||||||
|
(id_miembro, matricula_registrada, fecha_hora_visita, nombre_area_acceso, estado_acceso, motivo_denegacion, registrado_por, observaciones)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
`;
|
||||||
|
const values = [
|
||||||
|
id_miembro,
|
||||||
|
matricula_registrada,
|
||||||
|
fecha_hora_visita, // Usa la fecha formateada
|
||||||
|
nombre_area_acceso,
|
||||||
|
estado_acceso.toUpperCase(), // Asegura que se guarde en mayúsculas
|
||||||
|
motivo_denegacion || null,
|
||||||
|
registrado_por || null,
|
||||||
|
observaciones || null
|
||||||
|
];
|
||||||
|
|
||||||
|
connection.query(query, values, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al registrar visita:', err);
|
||||||
|
if (err.code === 'ER_NO_REFERENCED_ROW_2' || err.code === 'ER_NO_REFERENCED_ROW') {
|
||||||
|
return res.status(400).json({ mensaje: 'El ID de miembro especificado no existe. Asegúrate de que el miembro esté registrado en el sistema.', error: err.message });
|
||||||
|
}
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al registrar la visita', error: err.message });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.affectedRows === 1) {
|
||||||
|
res.status(201).json({
|
||||||
|
mensaje: 'Visita registrada exitosamente.',
|
||||||
|
id_visita: result.insertId,
|
||||||
|
datos_visita: {
|
||||||
|
id_miembro,
|
||||||
|
matricula_registrada,
|
||||||
|
nombre_area_acceso,
|
||||||
|
estado_acceso,
|
||||||
|
fecha_hora_visita // Devuelve la fecha formateada
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.status(500).json({ mensaje: 'Error al registrar la visita: no se afectó ninguna fila.' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function listarVisitas
|
||||||
|
* @description Lista todos los registros de visitas.
|
||||||
|
* @param {Object} req - Objeto de solicitud de Express.
|
||||||
|
* @param {Object} res - Objeto de respuesta de Express.
|
||||||
|
*/
|
||||||
|
listarVisitas: (req, res) => {
|
||||||
|
req.getConnection((err, connection) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al obtener conexión para listar visitas:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener conexión', error: err.message });
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = `
|
||||||
|
SELECT
|
||||||
|
cv.id_visita,
|
||||||
|
cv.id_miembro,
|
||||||
|
cm.matricula AS matricula_miembro,
|
||||||
|
cli.client_nombre AS nombre_cliente,
|
||||||
|
cv.matricula_registrada,
|
||||||
|
cv.fecha_hora_visita,
|
||||||
|
cv.nombre_area_acceso,
|
||||||
|
cv.estado_acceso,
|
||||||
|
cv.motivo_denegacion,
|
||||||
|
cv.registrado_por,
|
||||||
|
cv.observaciones,
|
||||||
|
cv.fecha_creacion
|
||||||
|
FROM
|
||||||
|
clientes_miembros_visitas cv
|
||||||
|
JOIN
|
||||||
|
clientes_miembros cm ON cv.id_miembro = cm.id_miembro
|
||||||
|
JOIN
|
||||||
|
clientes cli ON cm.client_id = cli.client_id
|
||||||
|
ORDER BY cv.fecha_hora_visita DESC
|
||||||
|
`;
|
||||||
|
|
||||||
|
connection.query(query, (err, rows) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al listar visitas:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al listar visitas', error: err.message });
|
||||||
|
}
|
||||||
|
res.json(rows);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function obtenerVisitaPorId
|
||||||
|
* @description Obtiene una visita específica por su ID.
|
||||||
|
* @param {Object} req - Objeto de solicitud de Express (req.params.id_visita).
|
||||||
|
* @param {Object} res - Objeto de respuesta de Express.
|
||||||
|
*/
|
||||||
|
obtenerVisitaPorId: (req, res) => {
|
||||||
|
const { id_visita } = req.params;
|
||||||
|
req.getConnection((err, connection) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al obtener conexión para visita por ID:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener conexión', error: err.message });
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = `
|
||||||
|
SELECT
|
||||||
|
cv.id_visita,
|
||||||
|
cv.id_miembro,
|
||||||
|
cm.matricula AS matricula_miembro,
|
||||||
|
cli.client_nombre AS nombre_cliente,
|
||||||
|
cv.matricula_registrada,
|
||||||
|
cv.fecha_hora_visita,
|
||||||
|
cv.nombre_area_acceso,
|
||||||
|
cv.estado_acceso,
|
||||||
|
cv.motivo_denegacion,
|
||||||
|
cv.registrado_por,
|
||||||
|
cv.observaciones,
|
||||||
|
cv.fecha_creacion
|
||||||
|
FROM
|
||||||
|
clientes_miembros_visitas cv
|
||||||
|
JOIN
|
||||||
|
clientes_miembros cm ON cv.id_miembro = cm.id_miembro
|
||||||
|
JOIN
|
||||||
|
clientes cli ON cm.client_id = cli.client_id
|
||||||
|
WHERE cv.id_visita = ?
|
||||||
|
`;
|
||||||
|
|
||||||
|
connection.query(query, [id_visita], (err, rows) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al obtener visita por ID:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener visita', error: err.message });
|
||||||
|
}
|
||||||
|
if (rows.length === 0) {
|
||||||
|
return res.status(404).json({ mensaje: 'Visita no encontrada' });
|
||||||
|
}
|
||||||
|
res.json(rows[0]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function listarVisitasPorMiembro
|
||||||
|
* @description Lista el historial de visitas para un miembro específico por su id_miembro.
|
||||||
|
* @param {Object} req - Objeto de solicitud de Express (req.params.id_miembro).
|
||||||
|
* @param {Object} res - Objeto de respuesta de Express.
|
||||||
|
*/
|
||||||
|
listarVisitasPorMiembro: (req, res) => {
|
||||||
|
const { id_miembro } = req.params;
|
||||||
|
req.getConnection((err, connection) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al obtener conexión para listar visitas por miembro:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener conexión', error: err.message });
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = `
|
||||||
|
SELECT
|
||||||
|
cv.id_visita,
|
||||||
|
cv.matricula_registrada,
|
||||||
|
cv.fecha_hora_visita,
|
||||||
|
cv.nombre_area_acceso,
|
||||||
|
cv.estado_acceso,
|
||||||
|
cv.motivo_denegacion,
|
||||||
|
cv.registrado_por,
|
||||||
|
cv.observaciones
|
||||||
|
FROM
|
||||||
|
clientes_miembros_visitas cv
|
||||||
|
WHERE cv.id_miembro = ?
|
||||||
|
ORDER BY cv.fecha_hora_visita DESC
|
||||||
|
`;
|
||||||
|
|
||||||
|
connection.query(query, [id_miembro], (err, rows) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al listar visitas por miembro:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al listar visitas por miembro', error: err.message });
|
||||||
|
}
|
||||||
|
if (rows.length === 0) {
|
||||||
|
return res.status(404).json({ mensaje: 'No se encontraron visitas para el miembro con el ID proporcionado.' });
|
||||||
|
}
|
||||||
|
res.json(rows);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function listarVisitasPorEstadoAcceso
|
||||||
|
* @description Lista las visitas filtradas por un estado de acceso específico (CONCEDIDO/DENEGADO).
|
||||||
|
* @param {Object} req - Objeto de solicitud de Express (req.params.estado_acceso).
|
||||||
|
* @param {Object} res - Objeto de respuesta de Express.
|
||||||
|
*/
|
||||||
|
listarVisitasPorEstadoAcceso: (req, res) => {
|
||||||
|
const { estado_acceso } = req.params;
|
||||||
|
// Validar que el estado sea uno de los permitidos por el ENUM
|
||||||
|
const estadosPermitidos = ['CONCEDIDO', 'DENEGADO'];
|
||||||
|
if (!estadosPermitidos.includes(estado_acceso.toUpperCase())) {
|
||||||
|
return res.status(400).json({ mensaje: `El estado de acceso proporcionado '${estado_acceso}' no es válido. Los estados permitidos son: ${estadosPermitidos.join(', ')}.` });
|
||||||
|
}
|
||||||
|
|
||||||
|
req.getConnection((err, connection) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al obtener conexión para listar visitas por estado de acceso:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener conexión', error: err.message });
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = `
|
||||||
|
SELECT
|
||||||
|
cv.id_visita,
|
||||||
|
cv.id_miembro,
|
||||||
|
cm.matricula AS matricula_miembro,
|
||||||
|
cli.client_nombre AS nombre_cliente,
|
||||||
|
cv.matricula_registrada,
|
||||||
|
cv.fecha_hora_visita,
|
||||||
|
cv.nombre_area_acceso,
|
||||||
|
cv.estado_acceso,
|
||||||
|
cv.motivo_denegacion
|
||||||
|
FROM
|
||||||
|
clientes_miembros_visitas cv
|
||||||
|
JOIN
|
||||||
|
clientes_miembros cm ON cv.id_miembro = cm.id_miembro
|
||||||
|
JOIN
|
||||||
|
clientes cli ON cm.client_id = cli.client_id
|
||||||
|
WHERE cv.estado_acceso = ?
|
||||||
|
ORDER BY cv.fecha_hora_visita DESC
|
||||||
|
`;
|
||||||
|
|
||||||
|
connection.query(query, [estado_acceso.toUpperCase()], (err, rows) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al listar visitas por estado de acceso:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al listar visitas por estado de acceso', error: err.message });
|
||||||
|
}
|
||||||
|
res.json(rows);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function listarVisitasPorArea
|
||||||
|
* @description Lista las visitas filtradas por el nombre del área de acceso.
|
||||||
|
* @param {Object} req - Objeto de solicitud de Express (req.params.nombre_area).
|
||||||
|
* @param {Object} res - Objeto de respuesta de Express.
|
||||||
|
*/
|
||||||
|
listarVisitasPorArea: (req, res) => {
|
||||||
|
const { nombre_area } = req.params;
|
||||||
|
|
||||||
|
if (!nombre_area) {
|
||||||
|
return res.status(400).json({ mensaje: 'El nombre del área es obligatorio.' });
|
||||||
|
}
|
||||||
|
|
||||||
|
req.getConnection((err, connection) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al obtener conexión para listar visitas por área:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener conexión', error: err.message });
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = `
|
||||||
|
SELECT
|
||||||
|
cv.id_visita,
|
||||||
|
cv.id_miembro,
|
||||||
|
cm.matricula AS matricula_miembro,
|
||||||
|
cli.client_nombre AS nombre_cliente,
|
||||||
|
cv.matricula_registrada,
|
||||||
|
cv.fecha_hora_visita,
|
||||||
|
cv.nombre_area_acceso,
|
||||||
|
cv.estado_acceso,
|
||||||
|
cv.motivo_denegacion
|
||||||
|
FROM
|
||||||
|
clientes_miembros_visitas cv
|
||||||
|
JOIN
|
||||||
|
clientes_miembros cm ON cv.id_miembro = cm.id_miembro
|
||||||
|
JOIN
|
||||||
|
clientes cli ON cm.client_id = cli.client_id
|
||||||
|
WHERE cv.nombre_area_acceso LIKE ?
|
||||||
|
ORDER BY cv.fecha_hora_visita DESC
|
||||||
|
`;
|
||||||
|
|
||||||
|
connection.query(query, [`%${nombre_area}%`], (err, rows) => { // Uso de LIKE para búsqueda parcial
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al listar visitas por área:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al listar visitas por área', error: err.message });
|
||||||
|
}
|
||||||
|
res.json(rows);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = controlador_Clientes_MiembrosVisitas;
|
||||||
@@ -2,10 +2,10 @@ const express = require('express');
|
|||||||
const rutas = express.Router();
|
const rutas = express.Router();
|
||||||
|
|
||||||
const controladorClientes = require('../controladores/controlador_Clientes');
|
const controladorClientes = require('../controladores/controlador_Clientes');
|
||||||
// Importa el NUEVO controlador de Membresías
|
const controladorMembresias = require('../controladores/controlador_Clientes_Membresias');
|
||||||
const controladorMembresias = require('../controladores/controlador_Membresias');
|
const controladorMiembros = require('../controladores/controlador_Clientes_Miembros');
|
||||||
const controladorMiembros = require('../controladores/controlador_Miembros');
|
|
||||||
const controladorAreas = require('../controladores/controlador_Areas'); // Controlador para áreas de configuración
|
const controladorAreas = require('../controladores/controlador_Areas'); // Controlador para áreas de configuración
|
||||||
|
const controladorVisitasMiembros = require('../controladores/controlador_Clientes_MiembrosVisitas'); // Controlador para visitas de miembros
|
||||||
|
|
||||||
//indice inical
|
//indice inical
|
||||||
rutas.get('/clientes', controladorClientes.ver);//ver lista de clientes
|
rutas.get('/clientes', controladorClientes.ver);//ver lista de clientes
|
||||||
@@ -74,6 +74,28 @@ rutas.get('/api/miembros/estado/:estado', controladorMiembros.listarMiembrosPorE
|
|||||||
// GET /api/tipos-membresia/:id_tipo_membresia/miembros
|
// GET /api/tipos-membresia/:id_tipo_membresia/miembros
|
||||||
rutas.get('/api/tipos-membresia/:id_tipo_membresia/miembros', controladorMiembros.listarMiembrosPorTipoMembresia);
|
rutas.get('/api/tipos-membresia/:id_tipo_membresia/miembros', controladorMiembros.listarMiembrosPorTipoMembresia);
|
||||||
|
|
||||||
|
// --- Rutas RESTful para VISITAS de Miembros (tabla 'clientes_miembros_visitas') ---
|
||||||
|
// Estas rutas apuntarán al nuevo controlador_VisitasMiembros
|
||||||
|
// Registrar una nueva visita de miembro
|
||||||
|
// POST /api/visitas-miembros
|
||||||
|
// Datos esperados en el cuerpo: id_miembro, matricula_registrada, nombre_area_acceso, estado_acceso, motivo_denegacion (opcional), registrado_por (opcional), observaciones (opcional)
|
||||||
|
rutas.post('/api/visitas-miembros', controladorVisitasMiembros.registrarVisita);
|
||||||
|
// Obtener todas las visitas (puede ser útil para reportes o auditorías, pero cuidado con el volumen)
|
||||||
|
// GET /api/visitas-miembros
|
||||||
|
rutas.get('/api/visitas-miembros', controladorVisitasMiembros.listarVisitas);
|
||||||
|
// Obtener visitas por ID de miembro (para ver el historial de un miembro específico)
|
||||||
|
// GET /api/miembros/:id_miembro/visitas
|
||||||
|
rutas.get('/api/miembros/:id_miembro/visitas', controladorVisitasMiembros.listarVisitasPorMiembro);
|
||||||
|
// Obtener una visita específica por su ID
|
||||||
|
// GET /api/visitas-miembros/:id_visita
|
||||||
|
rutas.get('/api/visitas-miembros/:id_visita', controladorVisitasMiembros.obtenerVisitaPorId);
|
||||||
|
// (Opcional) Obtener visitas por estado de acceso (CONCEDIDO/DENEGADO)
|
||||||
|
// GET /api/visitas-miembros/estado/:estado_acceso
|
||||||
|
rutas.get('/api/visitas-miembros/estado/:estado_acceso', controladorVisitasMiembros.listarVisitasPorEstadoAcceso);
|
||||||
|
// (Opcional) Obtener visitas por área de acceso
|
||||||
|
// GET /api/visitas-miembros/area/:nombre_area
|
||||||
|
rutas.get('/api/visitas-miembros/area/:nombre_area', controladorVisitasMiembros.listarVisitasPorArea);
|
||||||
|
|
||||||
// Rutas para la administración de Áreas de Acceso
|
// Rutas para la administración de Áreas de Acceso
|
||||||
rutas.get('/api/areas', controladorAreas.listarAreas);
|
rutas.get('/api/areas', controladorAreas.listarAreas);
|
||||||
rutas.get('/api/areas/:id', controladorAreas.obtenerAreaPorId);
|
rutas.get('/api/areas/:id', controladorAreas.obtenerAreaPorId);
|
||||||
|
|||||||
Reference in New Issue
Block a user