Cambios de unificacion en ingresos de visitas.
This commit is contained in:
@@ -1,69 +1,70 @@
|
|||||||
// src/controladores/controlador_Clientes_MiembrosVisitas.js
|
// 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 = {
|
const controlador_Clientes_MiembrosVisitas = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function registrarVisita
|
* @function crearVisita
|
||||||
* @description Registra una nueva visita de miembro en la tabla clientes_miembros_visitas.
|
* @description Registra una nueva visita en la tabla `clientes_miembros_visitas`.
|
||||||
* @param {Object} req - Objeto de solicitud de Express.
|
* Maneja tanto visitas de miembros como de clientes ocasionales.
|
||||||
|
* @param {Object} req - Objeto de solicitud de Express (req.body).
|
||||||
* @param {Object} res - Objeto de respuesta de Express.
|
* @param {Object} res - Objeto de respuesta de Express.
|
||||||
*/
|
*/
|
||||||
registrarVisita: (req, res) => {
|
crearVisita: (req, res) => {
|
||||||
req.getConnection((err, connection) => {
|
req.getConnection((err, connection) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('Error al obtener conexión para registrar visita:', err);
|
console.error('Error al obtener conexión para crear visita:', err);
|
||||||
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener conexión', error: err.message });
|
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener conexión', error: err.message });
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
id_miembro,
|
client_id, // Obligatorio, siempre debe estar
|
||||||
matricula_registrada,
|
es_miembro, // Booleano: true (1) o false (0)
|
||||||
|
id_miembro, // Opcional, solo si es_miembro es true
|
||||||
nombre_area_acceso,
|
nombre_area_acceso,
|
||||||
estado_acceso, // 'CONCEDIDO' o 'DENEGADO'
|
estado_acceso,
|
||||||
motivo_denegacion,
|
motivo_denegacion,
|
||||||
registrado_por,
|
registrado_por,
|
||||||
observaciones
|
observaciones
|
||||||
} = req.body;
|
} = req.body;
|
||||||
|
|
||||||
// Validación básica de los campos requeridos
|
// Validaciones básicas de campos obligatorios
|
||||||
if (!id_miembro || !matricula_registrada || !nombre_area_acceso || !estado_acceso) {
|
if (client_id === undefined || client_id === null || !nombre_area_acceso || !estado_acceso || es_miembro === undefined || es_miembro === null) {
|
||||||
return res.status(400).json({ mensaje: 'Faltan campos obligatorios para registrar la visita (id_miembro, matricula_registrada, nombre_area_acceso, estado_acceso).' });
|
return res.status(400).json({ mensaje: 'Faltan campos obligatorios (client_id, nombre_area_acceso, estado_acceso, es_miembro).' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Asegúrate de que estado_acceso sea uno de los valores ENUM permitidos
|
|
||||||
if (!['CONCEDIDO', 'DENEGADO'].includes(estado_acceso.toUpperCase())) {
|
if (!['CONCEDIDO', 'DENEGADO'].includes(estado_acceso.toUpperCase())) {
|
||||||
return res.status(400).json({ mensaje: 'El estado de acceso debe ser "CONCEDIDO" o "DENEGADO".' });
|
return res.status(400).json({ mensaje: 'El estado de acceso debe ser "CONCEDIDO" o "DENEGADO".' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- SIMPLIFICACIÓN: Usar la fecha nativa de JavaScript ---
|
// Validación de coherencia entre `es_miembro` y `id_miembro` (gestionada por código)
|
||||||
const now = new Date(); // Esto obtendrá la fecha y hora local del servidor (Quito)
|
if (es_miembro && (id_miembro === undefined || id_miembro === null)) {
|
||||||
|
return res.status(400).json({ mensaje: 'Si es_miembro es TRUE, id_miembro es obligatorio.' });
|
||||||
|
}
|
||||||
|
if (!es_miembro && (id_miembro !== undefined && id_miembro !== null)) {
|
||||||
|
return res.status(400).json({ mensaje: 'Si es_miembro es FALSE, id_miembro no debe ser proporcionado.' });
|
||||||
|
}
|
||||||
|
|
||||||
// Formatear la fecha y hora a 'YYYY-MM-DD HH:mm:ss' para MySQL
|
// Usar la fecha nativa de JavaScript, asumiendo que el servidor está en UTC-5 (Quito)
|
||||||
|
const now = new Date();
|
||||||
const year = now.getFullYear();
|
const year = now.getFullYear();
|
||||||
const month = String(now.getMonth() + 1).padStart(2, '0'); // getMonth() es 0-indexado
|
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||||
const day = String(now.getDate()).padStart(2, '0');
|
const day = String(now.getDate()).padStart(2, '0');
|
||||||
const hours = String(now.getHours()).padStart(2, '0');
|
const hours = String(now.getHours()).padStart(2, '0');
|
||||||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||||||
|
|
||||||
const fecha_hora_visita = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
const fecha_hora_visita = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||||
// ---------------------------------------------------
|
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
INSERT INTO clientes_miembros_visitas
|
INSERT INTO clientes_miembros_visitas
|
||||||
(id_miembro, matricula_registrada, fecha_hora_visita, nombre_area_acceso, estado_acceso, motivo_denegacion, registrado_por, observaciones)
|
(client_id, es_miembro, id_miembro, fecha_hora_visita, nombre_area_acceso, estado_acceso, motivo_denegacion, registrado_por, observaciones)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
`;
|
`;
|
||||||
const values = [
|
const values = [
|
||||||
id_miembro,
|
client_id,
|
||||||
matricula_registrada,
|
es_miembro, // Se insertará como 1 (TRUE) o 0 (FALSE) en MySQL
|
||||||
fecha_hora_visita, // Usa la fecha formateada
|
es_miembro ? id_miembro : null, // Inserta id_miembro si es miembro, de lo contrario NULL
|
||||||
|
fecha_hora_visita,
|
||||||
nombre_area_acceso,
|
nombre_area_acceso,
|
||||||
estado_acceso.toUpperCase(), // Asegura que se guarde en mayúsculas
|
estado_acceso.toUpperCase(),
|
||||||
motivo_denegacion || null,
|
motivo_denegacion || null,
|
||||||
registrado_por || null,
|
registrado_por || null,
|
||||||
observaciones || null
|
observaciones || null
|
||||||
@@ -71,11 +72,14 @@ const controlador_Clientes_MiembrosVisitas = {
|
|||||||
|
|
||||||
connection.query(query, values, (err, result) => {
|
connection.query(query, values, (err, result) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('Error al registrar visita:', err);
|
console.error('Error al crear visita:', err);
|
||||||
if (err.code === 'ER_NO_REFERENCED_ROW_2' || err.code === 'ER_NO_REFERENCED_ROW') {
|
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 });
|
let msg = 'El ID de cliente o ID de miembro especificado no existe.';
|
||||||
|
if (es_miembro) msg += ' Asegúrese de que el miembro y su cliente asociado existan.';
|
||||||
|
else msg += ' Asegúrese de que el cliente exista.';
|
||||||
|
return res.status(400).json({ mensaje: msg, error: err.message });
|
||||||
}
|
}
|
||||||
return res.status(500).json({ mensaje: 'Error interno del servidor al registrar la visita', error: err.message });
|
return res.status(500).json({ mensaje: 'Error interno del servidor al crear la visita', error: err.message });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.affectedRows === 1) {
|
if (result.affectedRows === 1) {
|
||||||
@@ -83,15 +87,16 @@ const controlador_Clientes_MiembrosVisitas = {
|
|||||||
mensaje: 'Visita registrada exitosamente.',
|
mensaje: 'Visita registrada exitosamente.',
|
||||||
id_visita: result.insertId,
|
id_visita: result.insertId,
|
||||||
datos_visita: {
|
datos_visita: {
|
||||||
id_miembro,
|
client_id,
|
||||||
matricula_registrada,
|
es_miembro,
|
||||||
|
id_miembro: es_miembro ? id_miembro : null,
|
||||||
nombre_area_acceso,
|
nombre_area_acceso,
|
||||||
estado_acceso,
|
estado_acceso,
|
||||||
fecha_hora_visita // Devuelve la fecha formateada
|
fecha_hora_visita
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
res.status(500).json({ mensaje: 'Error al registrar la visita: no se afectó ninguna fila.' });
|
res.status(500).json({ mensaje: 'Error al crear la visita: no se afectó ninguna fila.' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -99,8 +104,9 @@ const controlador_Clientes_MiembrosVisitas = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @function listarVisitas
|
* @function listarVisitas
|
||||||
* @description Lista todos los registros de visitas.
|
* @description Lista todas las visitas, con información detallada de cliente y miembro si aplica.
|
||||||
* @param {Object} req - Objeto de solicitud de Express.
|
* Soporta filtros opcionales por client_id, id_miembro, estado_acceso, nombre_area_acceso, y rango de fechas.
|
||||||
|
* @param {Object} req - Objeto de solicitud de Express (req.query para filtros).
|
||||||
* @param {Object} res - Objeto de respuesta de Express.
|
* @param {Object} res - Objeto de respuesta de Express.
|
||||||
*/
|
*/
|
||||||
listarVisitas: (req, res) => {
|
listarVisitas: (req, res) => {
|
||||||
@@ -110,30 +116,81 @@ const controlador_Clientes_MiembrosVisitas = {
|
|||||||
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener conexión', error: err.message });
|
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener conexión', error: err.message });
|
||||||
}
|
}
|
||||||
|
|
||||||
const query = `
|
let query = `
|
||||||
SELECT
|
SELECT
|
||||||
cv.id_visita,
|
cmv.id_visita,
|
||||||
cv.id_miembro,
|
cmv.fecha_hora_visita,
|
||||||
|
cmv.nombre_area_acceso,
|
||||||
|
cmv.estado_acceso,
|
||||||
|
cmv.motivo_denegacion,
|
||||||
|
cmv.registrado_por,
|
||||||
|
cmv.observaciones,
|
||||||
|
cmv.client_id,
|
||||||
|
cli.client_nombre,
|
||||||
|
cli.client_rucCed,
|
||||||
|
cmv.es_miembro,
|
||||||
|
cmv.id_miembro,
|
||||||
cm.matricula AS matricula_miembro,
|
cm.matricula AS matricula_miembro,
|
||||||
cli.client_nombre AS nombre_cliente,
|
ctm.nombre_tipo AS nombre_tipo_membresia,
|
||||||
cv.matricula_registrada,
|
cmv.fecha_creacion,
|
||||||
cv.fecha_hora_visita,
|
cmv.fecha_actualizacion
|
||||||
cv.nombre_area_acceso,
|
|
||||||
cv.estado_acceso,
|
|
||||||
cv.motivo_denegacion,
|
|
||||||
cv.registrado_por,
|
|
||||||
cv.observaciones,
|
|
||||||
cv.fecha_creacion
|
|
||||||
FROM
|
FROM
|
||||||
clientes_miembros_visitas cv
|
clientes_miembros_visitas cmv
|
||||||
JOIN
|
JOIN
|
||||||
clientes_miembros cm ON cv.id_miembro = cm.id_miembro
|
clientes cli ON cmv.client_id = cli.client_id
|
||||||
JOIN
|
LEFT JOIN
|
||||||
clientes cli ON cm.client_id = cli.client_id
|
clientes_miembros cm ON cmv.id_miembro = cm.id_miembro
|
||||||
ORDER BY cv.fecha_hora_visita DESC
|
LEFT JOIN
|
||||||
|
clientes_membresias ctm ON cm.id_tipo_membresia = ctm.id_tipo_membresia
|
||||||
|
WHERE 1=1
|
||||||
`;
|
`;
|
||||||
|
const queryParams = [];
|
||||||
|
|
||||||
connection.query(query, (err, rows) => {
|
// Aplicar filtros desde req.query
|
||||||
|
if (req.query.client_id) {
|
||||||
|
query += ` AND cmv.client_id = ?`;
|
||||||
|
queryParams.push(req.query.client_id);
|
||||||
|
}
|
||||||
|
if (req.query.id_miembro) {
|
||||||
|
query += ` AND cmv.id_miembro = ?`;
|
||||||
|
queryParams.push(req.query.id_miembro);
|
||||||
|
}
|
||||||
|
if (req.query.estado_acceso) {
|
||||||
|
const estado = req.query.estado_acceso.toUpperCase();
|
||||||
|
if (['CONCEDIDO', 'DENEGADO'].includes(estado)) {
|
||||||
|
query += ` AND cmv.estado_acceso = ?`;
|
||||||
|
queryParams.push(estado);
|
||||||
|
} else {
|
||||||
|
return res.status(400).json({ mensaje: 'Estado de acceso inválido para el filtro.' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (req.query.nombre_area) {
|
||||||
|
query += ` AND cmv.nombre_area_acceso LIKE ?`;
|
||||||
|
queryParams.push(`%${req.query.nombre_area}%`);
|
||||||
|
}
|
||||||
|
if (req.query.fecha_desde) {
|
||||||
|
query += ` AND cmv.fecha_hora_visita >= ?`;
|
||||||
|
queryParams.push(req.query.fecha_desde + ' 00:00:00'); // Desde el inicio del día
|
||||||
|
}
|
||||||
|
if (req.query.fecha_hasta) {
|
||||||
|
query += ` AND cmv.fecha_hora_visita <= ?`;
|
||||||
|
queryParams.push(req.query.fecha_hasta + ' 23:59:59'); // Hasta el final del día
|
||||||
|
}
|
||||||
|
// Filtro para `es_miembro` (true/false)
|
||||||
|
if (req.query.es_miembro !== undefined && req.query.es_miembro !== null) {
|
||||||
|
const esMiembroBool = req.query.es_miembro === 'true' || req.query.es_miembro === '1';
|
||||||
|
query += ` AND cmv.es_miembro = ?`;
|
||||||
|
queryParams.push(esMiembroBool);
|
||||||
|
}
|
||||||
|
|
||||||
|
query += ` ORDER BY cmv.fecha_hora_visita DESC`;
|
||||||
|
// Implementar paginación si se necesita
|
||||||
|
// if (req.query.limit && req.query.offset) {
|
||||||
|
// query += ` LIMIT ? OFFSET ?`;
|
||||||
|
// queryParams.push(parseInt(req.query.limit), parseInt(req.query.offset));
|
||||||
|
// }
|
||||||
|
|
||||||
|
connection.query(query, queryParams, (err, rows) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('Error al listar visitas:', err);
|
console.error('Error al listar visitas:', err);
|
||||||
return res.status(500).json({ mensaje: 'Error interno del servidor al listar visitas', error: err.message });
|
return res.status(500).json({ mensaje: 'Error interno del servidor al listar visitas', error: err.message });
|
||||||
@@ -159,25 +216,31 @@ const controlador_Clientes_MiembrosVisitas = {
|
|||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
SELECT
|
SELECT
|
||||||
cv.id_visita,
|
cmv.id_visita,
|
||||||
cv.id_miembro,
|
cmv.fecha_hora_visita,
|
||||||
|
cmv.nombre_area_acceso,
|
||||||
|
cmv.estado_acceso,
|
||||||
|
cmv.motivo_denegacion,
|
||||||
|
cmv.registrado_por,
|
||||||
|
cmv.observaciones,
|
||||||
|
cmv.client_id,
|
||||||
|
cli.client_nombre,
|
||||||
|
cli.client_rucCed,
|
||||||
|
cmv.es_miembro,
|
||||||
|
cmv.id_miembro,
|
||||||
cm.matricula AS matricula_miembro,
|
cm.matricula AS matricula_miembro,
|
||||||
cli.client_nombre AS nombre_cliente,
|
ctm.nombre_tipo AS nombre_tipo_membresia,
|
||||||
cv.matricula_registrada,
|
cmv.fecha_creacion,
|
||||||
cv.fecha_hora_visita,
|
cmv.fecha_actualizacion
|
||||||
cv.nombre_area_acceso,
|
|
||||||
cv.estado_acceso,
|
|
||||||
cv.motivo_denegacion,
|
|
||||||
cv.registrado_por,
|
|
||||||
cv.observaciones,
|
|
||||||
cv.fecha_creacion
|
|
||||||
FROM
|
FROM
|
||||||
clientes_miembros_visitas cv
|
clientes_miembros_visitas cmv
|
||||||
JOIN
|
JOIN
|
||||||
clientes_miembros cm ON cv.id_miembro = cm.id_miembro
|
clientes cli ON cmv.client_id = cli.client_id
|
||||||
JOIN
|
LEFT JOIN
|
||||||
clientes cli ON cm.client_id = cli.client_id
|
clientes_miembros cm ON cmv.id_miembro = cm.id_miembro
|
||||||
WHERE cv.id_visita = ?
|
LEFT JOIN
|
||||||
|
clientes_membresias ctm ON cm.id_tipo_membresia = ctm.id_tipo_membresia
|
||||||
|
WHERE cmv.id_visita = ?
|
||||||
`;
|
`;
|
||||||
|
|
||||||
connection.query(query, [id_visita], (err, rows) => {
|
connection.query(query, [id_visita], (err, rows) => {
|
||||||
@@ -193,9 +256,164 @@ const controlador_Clientes_MiembrosVisitas = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function actualizarVisita
|
||||||
|
* @description Actualiza un registro de visita existente por su ID en `clientes_miembros_visitas`.
|
||||||
|
* Solo permite actualizar campos como área, estado, motivo, registrado_por, observaciones.
|
||||||
|
* NO se permite actualizar `client_id`, `es_miembro`, `id_miembro` o `fecha_hora_visita`.
|
||||||
|
* @param {Object} req - Objeto de solicitud de Express (req.params.id_visita, req.body).
|
||||||
|
* @param {Object} res - Objeto de respuesta de Express.
|
||||||
|
*/
|
||||||
|
actualizarVisita: (req, res) => {
|
||||||
|
const { id_visita } = req.params;
|
||||||
|
const {
|
||||||
|
nombre_area_acceso,
|
||||||
|
estado_acceso,
|
||||||
|
motivo_denegacion,
|
||||||
|
registrado_por,
|
||||||
|
observaciones
|
||||||
|
} = req.body;
|
||||||
|
|
||||||
|
if (!nombre_area_acceso || !estado_acceso) {
|
||||||
|
return res.status(400).json({ mensaje: 'Faltan campos obligatorios para actualizar la visita (nombre_area_acceso, estado_acceso).' });
|
||||||
|
}
|
||||||
|
if (!['CONCEDIDO', 'DENEGADO'].includes(estado_acceso.toUpperCase())) {
|
||||||
|
return res.status(400).json({ mensaje: 'El estado de acceso debe ser "CONCEDIDO" o "DENEGADO".' });
|
||||||
|
}
|
||||||
|
|
||||||
|
req.getConnection((err, connection) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al obtener conexión para actualizar visita:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener conexión', error: err.message });
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = `
|
||||||
|
UPDATE clientes_miembros_visitas SET
|
||||||
|
nombre_area_acceso = ?,
|
||||||
|
estado_acceso = ?,
|
||||||
|
motivo_denegacion = ?,
|
||||||
|
registrado_por = ?,
|
||||||
|
observaciones = ?,
|
||||||
|
fecha_actualizacion = CURRENT_TIMESTAMP()
|
||||||
|
WHERE id_visita = ?
|
||||||
|
`;
|
||||||
|
const values = [
|
||||||
|
nombre_area_acceso,
|
||||||
|
estado_acceso.toUpperCase(),
|
||||||
|
motivo_denegacion || null,
|
||||||
|
registrado_por || null,
|
||||||
|
observaciones || null,
|
||||||
|
id_visita
|
||||||
|
];
|
||||||
|
|
||||||
|
connection.query(query, values, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al actualizar visita:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al actualizar visita', error: err.message });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.affectedRows === 0) {
|
||||||
|
return res.status(404).json({ mensaje: 'Visita no encontrada para actualizar' });
|
||||||
|
}
|
||||||
|
res.json({ mensaje: 'Visita actualizada exitosamente' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function eliminarVisita
|
||||||
|
* @description Elimina físicamente una visita de la tabla `clientes_miembros_visitas`.
|
||||||
|
* NOTA: Para propósitos de auditoría, a menudo se prefiere una "eliminación lógica"
|
||||||
|
* (por ejemplo, actualizando un campo `estado_visita` a 'ANULADA').
|
||||||
|
* @param {Object} req - Objeto de solicitud de Express (req.params.id_visita).
|
||||||
|
* @param {Object} res - Objeto de respuesta de Express.
|
||||||
|
*/
|
||||||
|
eliminarVisita: (req, res) => {
|
||||||
|
const { id_visita } = req.params;
|
||||||
|
req.getConnection((err, connection) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al obtener conexión para eliminar visita:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener conexión', error: err.message });
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = `DELETE FROM clientes_miembros_visitas WHERE id_visita = ?`;
|
||||||
|
|
||||||
|
connection.query(query, [id_visita], (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al eliminar visita:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al eliminar visita', error: err.message });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.affectedRows === 0) {
|
||||||
|
return res.status(404).json({ mensaje: 'Visita no encontrada para eliminar' });
|
||||||
|
}
|
||||||
|
res.json({ mensaje: 'Visita eliminada exitosamente.' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function listarVisitasPorCliente
|
||||||
|
* @description Lista visitas filtradas por un `client_id` específico.
|
||||||
|
* Incluye tanto visitas de miembros como de clientes ocasionales asociados a ese cliente.
|
||||||
|
* @param {Object} req - Objeto de solicitud de Express (req.params.client_id).
|
||||||
|
* @param {Object} res - Objeto de respuesta de Express.
|
||||||
|
*/
|
||||||
|
listarVisitasPorCliente: (req, res) => {
|
||||||
|
const { client_id } = req.params;
|
||||||
|
req.getConnection((err, connection) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al obtener conexión para listar visitas por cliente:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener conexión', error: err.message });
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = `
|
||||||
|
SELECT
|
||||||
|
cmv.id_visita,
|
||||||
|
cmv.fecha_hora_visita,
|
||||||
|
cmv.nombre_area_acceso,
|
||||||
|
cmv.estado_acceso,
|
||||||
|
cmv.motivo_denegacion,
|
||||||
|
cmv.registrado_por,
|
||||||
|
cmv.observaciones,
|
||||||
|
cmv.client_id,
|
||||||
|
cli.client_nombre,
|
||||||
|
cli.client_rucCed,
|
||||||
|
cmv.es_miembro,
|
||||||
|
cmv.id_miembro,
|
||||||
|
cm.matricula AS matricula_miembro,
|
||||||
|
ctm.nombre_tipo AS nombre_tipo_membresia,
|
||||||
|
cmv.fecha_creacion,
|
||||||
|
cmv.fecha_actualizacion
|
||||||
|
FROM
|
||||||
|
clientes_miembros_visitas cmv
|
||||||
|
JOIN
|
||||||
|
clientes cli ON cmv.client_id = cli.client_id
|
||||||
|
LEFT JOIN
|
||||||
|
clientes_miembros cm ON cmv.id_miembro = cm.id_miembro
|
||||||
|
LEFT JOIN
|
||||||
|
clientes_membresias ctm ON cm.id_tipo_membresia = ctm.id_tipo_membresia
|
||||||
|
WHERE cmv.client_id = ?
|
||||||
|
ORDER BY cmv.fecha_hora_visita DESC
|
||||||
|
`;
|
||||||
|
|
||||||
|
connection.query(query, [client_id], (err, rows) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error al listar visitas por cliente:', err);
|
||||||
|
return res.status(500).json({ mensaje: 'Error interno del servidor al listar visitas por cliente', error: err.message });
|
||||||
|
}
|
||||||
|
if (rows.length === 0) {
|
||||||
|
return res.status(404).json({ mensaje: 'No se encontraron visitas para el cliente proporcionado.' });
|
||||||
|
}
|
||||||
|
res.json(rows);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function listarVisitasPorMiembro
|
* @function listarVisitasPorMiembro
|
||||||
* @description Lista el historial de visitas para un miembro específico por su id_miembro.
|
* @description Lista visitas filtradas por un `id_miembro` específico.
|
||||||
|
* Solo devolverá visitas donde `es_miembro` sea TRUE.
|
||||||
* @param {Object} req - Objeto de solicitud de Express (req.params.id_miembro).
|
* @param {Object} req - Objeto de solicitud de Express (req.params.id_miembro).
|
||||||
* @param {Object} res - Objeto de respuesta de Express.
|
* @param {Object} res - Objeto de respuesta de Express.
|
||||||
*/
|
*/
|
||||||
@@ -209,18 +427,32 @@ const controlador_Clientes_MiembrosVisitas = {
|
|||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
SELECT
|
SELECT
|
||||||
cv.id_visita,
|
cmv.id_visita,
|
||||||
cv.matricula_registrada,
|
cmv.fecha_hora_visita,
|
||||||
cv.fecha_hora_visita,
|
cmv.nombre_area_acceso,
|
||||||
cv.nombre_area_acceso,
|
cmv.estado_acceso,
|
||||||
cv.estado_acceso,
|
cmv.motivo_denegacion,
|
||||||
cv.motivo_denegacion,
|
cmv.registrado_por,
|
||||||
cv.registrado_por,
|
cmv.observaciones,
|
||||||
cv.observaciones
|
cmv.client_id,
|
||||||
|
cli.client_nombre,
|
||||||
|
cli.client_rucCed,
|
||||||
|
cmv.es_miembro,
|
||||||
|
cmv.id_miembro,
|
||||||
|
cm.matricula AS matricula_miembro,
|
||||||
|
ctm.nombre_tipo AS nombre_tipo_membresia,
|
||||||
|
cmv.fecha_creacion,
|
||||||
|
cmv.fecha_actualizacion
|
||||||
FROM
|
FROM
|
||||||
clientes_miembros_visitas cv
|
clientes_miembros_visitas cmv
|
||||||
WHERE cv.id_miembro = ?
|
JOIN
|
||||||
ORDER BY cv.fecha_hora_visita DESC
|
clientes cli ON cmv.client_id = cli.client_id
|
||||||
|
JOIN
|
||||||
|
clientes_miembros cm ON cmv.id_miembro = cm.id_miembro AND cmv.es_miembro = TRUE
|
||||||
|
LEFT JOIN
|
||||||
|
clientes_membresias ctm ON cm.id_tipo_membresia = ctm.id_tipo_membresia
|
||||||
|
WHERE cmv.id_miembro = ?
|
||||||
|
ORDER BY cmv.fecha_hora_visita DESC
|
||||||
`;
|
`;
|
||||||
|
|
||||||
connection.query(query, [id_miembro], (err, rows) => {
|
connection.query(query, [id_miembro], (err, rows) => {
|
||||||
@@ -229,7 +461,7 @@ const controlador_Clientes_MiembrosVisitas = {
|
|||||||
return res.status(500).json({ mensaje: 'Error interno del servidor al listar visitas por miembro', error: err.message });
|
return res.status(500).json({ mensaje: 'Error interno del servidor al listar visitas por miembro', error: err.message });
|
||||||
}
|
}
|
||||||
if (rows.length === 0) {
|
if (rows.length === 0) {
|
||||||
return res.status(404).json({ mensaje: 'No se encontraron visitas para el miembro con el ID proporcionado.' });
|
return res.status(404).json({ mensaje: 'No se encontraron visitas para el miembro proporcionado.' });
|
||||||
}
|
}
|
||||||
res.json(rows);
|
res.json(rows);
|
||||||
});
|
});
|
||||||
@@ -238,13 +470,12 @@ const controlador_Clientes_MiembrosVisitas = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @function listarVisitasPorEstadoAcceso
|
* @function listarVisitasPorEstadoAcceso
|
||||||
* @description Lista las visitas filtradas por un estado de acceso específico (CONCEDIDO/DENEGADO).
|
* @description Lista 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} req - Objeto de solicitud de Express (req.params.estado_acceso).
|
||||||
* @param {Object} res - Objeto de respuesta de Express.
|
* @param {Object} res - Objeto de respuesta de Express.
|
||||||
*/
|
*/
|
||||||
listarVisitasPorEstadoAcceso: (req, res) => {
|
listarVisitasPorEstadoAcceso: (req, res) => {
|
||||||
const { estado_acceso } = req.params;
|
const { estado_acceso } = req.params;
|
||||||
// Validar que el estado sea uno de los permitidos por el ENUM
|
|
||||||
const estadosPermitidos = ['CONCEDIDO', 'DENEGADO'];
|
const estadosPermitidos = ['CONCEDIDO', 'DENEGADO'];
|
||||||
if (!estadosPermitidos.includes(estado_acceso.toUpperCase())) {
|
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(', ')}.` });
|
return res.status(400).json({ mensaje: `El estado de acceso proporcionado '${estado_acceso}' no es válido. Los estados permitidos son: ${estadosPermitidos.join(', ')}.` });
|
||||||
@@ -258,23 +489,30 @@ const controlador_Clientes_MiembrosVisitas = {
|
|||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
SELECT
|
SELECT
|
||||||
cv.id_visita,
|
cmv.id_visita,
|
||||||
cv.id_miembro,
|
cmv.fecha_hora_visita,
|
||||||
|
cmv.nombre_area_acceso,
|
||||||
|
cmv.estado_acceso,
|
||||||
|
cmv.motivo_denegacion,
|
||||||
|
cmv.registrado_por,
|
||||||
|
cmv.observaciones,
|
||||||
|
cmv.client_id,
|
||||||
|
cli.client_nombre,
|
||||||
|
cli.client_rucCed,
|
||||||
|
cmv.es_miembro,
|
||||||
|
cmv.id_miembro,
|
||||||
cm.matricula AS matricula_miembro,
|
cm.matricula AS matricula_miembro,
|
||||||
cli.client_nombre AS nombre_cliente,
|
ctm.nombre_tipo AS nombre_tipo_membresia
|
||||||
cv.matricula_registrada,
|
|
||||||
cv.fecha_hora_visita,
|
|
||||||
cv.nombre_area_acceso,
|
|
||||||
cv.estado_acceso,
|
|
||||||
cv.motivo_denegacion
|
|
||||||
FROM
|
FROM
|
||||||
clientes_miembros_visitas cv
|
clientes_miembros_visitas cmv
|
||||||
JOIN
|
JOIN
|
||||||
clientes_miembros cm ON cv.id_miembro = cm.id_miembro
|
clientes cli ON cmv.client_id = cli.client_id
|
||||||
JOIN
|
LEFT JOIN
|
||||||
clientes cli ON cm.client_id = cli.client_id
|
clientes_miembros cm ON cmv.id_miembro = cm.id_miembro
|
||||||
WHERE cv.estado_acceso = ?
|
LEFT JOIN
|
||||||
ORDER BY cv.fecha_hora_visita DESC
|
clientes_membresias ctm ON cm.id_tipo_membresia = ctm.id_tipo_membresia
|
||||||
|
WHERE cmv.estado_acceso = ?
|
||||||
|
ORDER BY cmv.fecha_hora_visita DESC
|
||||||
`;
|
`;
|
||||||
|
|
||||||
connection.query(query, [estado_acceso.toUpperCase()], (err, rows) => {
|
connection.query(query, [estado_acceso.toUpperCase()], (err, rows) => {
|
||||||
@@ -289,13 +527,12 @@ const controlador_Clientes_MiembrosVisitas = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @function listarVisitasPorArea
|
* @function listarVisitasPorArea
|
||||||
* @description Lista las visitas filtradas por el nombre del área de acceso.
|
* @description Lista visitas filtradas por el nombre del área de acceso.
|
||||||
* @param {Object} req - Objeto de solicitud de Express (req.params.nombre_area).
|
* @param {Object} req - Objeto de solicitud de Express (req.params.nombre_area).
|
||||||
* @param {Object} res - Objeto de respuesta de Express.
|
* @param {Object} res - Objeto de respuesta de Express.
|
||||||
*/
|
*/
|
||||||
listarVisitasPorArea: (req, res) => {
|
listarVisitasPorArea: (req, res) => {
|
||||||
const { nombre_area } = req.params;
|
const { nombre_area } = req.params;
|
||||||
|
|
||||||
if (!nombre_area) {
|
if (!nombre_area) {
|
||||||
return res.status(400).json({ mensaje: 'El nombre del área es obligatorio.' });
|
return res.status(400).json({ mensaje: 'El nombre del área es obligatorio.' });
|
||||||
}
|
}
|
||||||
@@ -308,26 +545,33 @@ const controlador_Clientes_MiembrosVisitas = {
|
|||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
SELECT
|
SELECT
|
||||||
cv.id_visita,
|
cmv.id_visita,
|
||||||
cv.id_miembro,
|
cmv.fecha_hora_visita,
|
||||||
|
cmv.nombre_area_acceso,
|
||||||
|
cmv.estado_acceso,
|
||||||
|
cmv.motivo_denegacion,
|
||||||
|
cmv.registrado_por,
|
||||||
|
cmv.observaciones,
|
||||||
|
cmv.client_id,
|
||||||
|
cli.client_nombre,
|
||||||
|
cli.client_rucCed,
|
||||||
|
cmv.es_miembro,
|
||||||
|
cmv.id_miembro,
|
||||||
cm.matricula AS matricula_miembro,
|
cm.matricula AS matricula_miembro,
|
||||||
cli.client_nombre AS nombre_cliente,
|
ctm.nombre_tipo AS nombre_tipo_membresia
|
||||||
cv.matricula_registrada,
|
|
||||||
cv.fecha_hora_visita,
|
|
||||||
cv.nombre_area_acceso,
|
|
||||||
cv.estado_acceso,
|
|
||||||
cv.motivo_denegacion
|
|
||||||
FROM
|
FROM
|
||||||
clientes_miembros_visitas cv
|
clientes_miembros_visitas cmv
|
||||||
JOIN
|
JOIN
|
||||||
clientes_miembros cm ON cv.id_miembro = cm.id_miembro
|
clientes cli ON cmv.client_id = cli.client_id
|
||||||
JOIN
|
LEFT JOIN
|
||||||
clientes cli ON cm.client_id = cli.client_id
|
clientes_miembros cm ON cmv.id_miembro = cm.id_miembro
|
||||||
WHERE cv.nombre_area_acceso LIKE ?
|
LEFT JOIN
|
||||||
ORDER BY cv.fecha_hora_visita DESC
|
clientes_membresias ctm ON cm.id_tipo_membresia = ctm.id_tipo_membresia
|
||||||
|
WHERE cmv.nombre_area_acceso LIKE ?
|
||||||
|
ORDER BY cmv.fecha_hora_visita DESC
|
||||||
`;
|
`;
|
||||||
|
|
||||||
connection.query(query, [`%${nombre_area}%`], (err, rows) => { // Uso de LIKE para búsqueda parcial
|
connection.query(query, [`%${nombre_area}%`], (err, rows) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('Error al listar visitas por área:', 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 });
|
return res.status(500).json({ mensaje: 'Error interno del servidor al listar visitas por área', error: err.message });
|
||||||
@@ -336,7 +580,6 @@ const controlador_Clientes_MiembrosVisitas = {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = controlador_Clientes_MiembrosVisitas;
|
module.exports = controlador_Clientes_MiembrosVisitas;
|
||||||
@@ -5,7 +5,7 @@ const controladorClientes = require('../controladores/controlador_Clientes');
|
|||||||
const controladorMembresias = require('../controladores/controlador_Clientes_Membresias');
|
const controladorMembresias = require('../controladores/controlador_Clientes_Membresias');
|
||||||
const controladorMiembros = require('../controladores/controlador_Clientes_Miembros');
|
const controladorMiembros = require('../controladores/controlador_Clientes_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
|
const controladorVisitas = 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
|
||||||
@@ -44,57 +44,45 @@ rutas.delete('/api/tipos-membresia/:id', controladorMembresias.eliminarTipoMembr
|
|||||||
// --- Rutas RESTful para MIEMBROS (tabla 'clientes_miembros') ---
|
// --- Rutas RESTful para MIEMBROS (tabla 'clientes_miembros') ---
|
||||||
// Estas rutas apuntarán al nuevo controlador_Miembros
|
// Estas rutas apuntarán al nuevo controlador_Miembros
|
||||||
// Obtener todos los miembros
|
// Obtener todos los miembros
|
||||||
// GET /api/miembros
|
|
||||||
rutas.get('/api/miembros', controladorMiembros.listarMiembros);
|
rutas.get('/api/miembros', controladorMiembros.listarMiembros);
|
||||||
// Obtener un miembro por su ID
|
// Obtener un miembro por su ID
|
||||||
// GET /api/miembros/:id_miembro
|
|
||||||
rutas.get('/api/miembros/:id_miembro', controladorMiembros.obtenerMiembroPorId);
|
rutas.get('/api/miembros/:id_miembro', controladorMiembros.obtenerMiembroPorId);
|
||||||
// Crear un nuevo miembro
|
// Crear un nuevo miembro
|
||||||
// POST /api/miembros
|
|
||||||
// Datos esperados en el cuerpo de la solicitud: matricula, client_id, id_tipo_membresia, fecha_inicio, fecha_fin, etc.
|
// Datos esperados en el cuerpo de la solicitud: matricula, client_id, id_tipo_membresia, fecha_inicio, fecha_fin, etc.
|
||||||
rutas.post('/api/miembros', controladorMiembros.crearMiembro);
|
rutas.post('/api/miembros', controladorMiembros.crearMiembro);
|
||||||
// Actualizar un miembro existente por su ID
|
// Actualizar un miembro existente por su ID
|
||||||
// PUT /api/miembros/:id_miembro
|
|
||||||
// Datos esperados en el cuerpo de la solicitud para actualizar: estado, fechas, etc.
|
// Datos esperados en el cuerpo de la solicitud para actualizar: estado, fechas, etc.
|
||||||
rutas.put('/api/miembros/:id_miembro', controladorMiembros.actualizarMiembro);
|
rutas.put('/api/miembros/:id_miembro', controladorMiembros.actualizarMiembro);
|
||||||
// Eliminar (lógicamente/cambiar estado a CANCELADO/SUSPENDIDO) un miembro por su ID
|
// Eliminar (lógicamente/cambiar estado a CANCELADO/SUSPENDIDO) un miembro por su ID
|
||||||
// DELETE /api/miembros/:id_miembro
|
|
||||||
// NOTA: Dada la importancia del historial, es más común cambiar el estado a 'CANCELADO' o 'SUSPENDIDO'
|
// NOTA: Dada la importancia del historial, es más común cambiar el estado a 'CANCELADO' o 'SUSPENDIDO'
|
||||||
// en lugar de una eliminación física. El controlador debería manejar esto.
|
// en lugar de una eliminación física. El controlador debería manejar esto.
|
||||||
rutas.delete('/api/miembros/:id_miembro', controladorMiembros.eliminarMiembro);
|
rutas.delete('/api/miembros/:id_miembro', controladorMiembros.eliminarMiembro);
|
||||||
|
|
||||||
// --- Rutas Adicionales Comunes para Miembros (Opcional) ---
|
// --- Rutas Adicionales Comunes para Miembros (Opcional) ---
|
||||||
// Obtener miembros por client_id (útil para ver todas las membresías de un cliente)
|
// Obtener miembros por client_id (útil para ver todas las membresías de un cliente)
|
||||||
// GET /api/clientes/:client_id/miembros
|
|
||||||
rutas.get('/api/clientes/:client_id/miembros', controladorMiembros.listarMiembrosPorCliente);
|
rutas.get('/api/clientes/:client_id/miembros', controladorMiembros.listarMiembrosPorCliente);
|
||||||
// Obtener miembros por estado (ej. 'ACTIVO', 'VENCIDO')
|
// Obtener miembros por estado (ej. 'ACTIVO', 'VENCIDO')
|
||||||
// GET /api/miembros/estado/:estado
|
|
||||||
rutas.get('/api/miembros/estado/:estado', controladorMiembros.listarMiembrosPorEstado);
|
rutas.get('/api/miembros/estado/:estado', controladorMiembros.listarMiembrosPorEstado);
|
||||||
// Obtener miembros por tipo de membresía
|
// Obtener miembros por tipo de membresía
|
||||||
// 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') ---
|
/// --- Rutas RESTful para VISITAS UNIFICADAS (tabla 'clientes_visitas') ---
|
||||||
// Estas rutas apuntarán al nuevo controlador_VisitasMiembros
|
// Estas rutas apuntarán al nuevo controlador_ClientesVisitas
|
||||||
// Registrar una nueva visita de miembro
|
// Registrar una nueva visita (para miembro o ocasional)
|
||||||
// POST /api/visitas-miembros
|
rutas.post('/api/visitas', controladorVisitas.crearVisita); // Renombrado a 'crearVisita'
|
||||||
// Datos esperados en el cuerpo: id_miembro, matricula_registrada, nombre_area_acceso, estado_acceso, motivo_denegacion (opcional), registrado_por (opcional), observaciones (opcional)
|
// Obtener todas las visitas (con posibilidad de filtros, cuidado con volumen)
|
||||||
rutas.post('/api/visitas-miembros', controladorVisitasMiembros.registrarVisita);
|
rutas.get('/api/visitas', controladorVisitas.listarVisitas);
|
||||||
// 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
|
// Obtener una visita específica por su ID
|
||||||
// GET /api/visitas-miembros/:id_visita
|
rutas.get('/api/visitas/:id_visita', controladorVisitas.obtenerVisitaPorId);
|
||||||
rutas.get('/api/visitas-miembros/:id_visita', controladorVisitasMiembros.obtenerVisitaPorId);
|
// Actualizar una visita existente (ej. corregir observaciones, cambiar estado si se permite)
|
||||||
// (Opcional) Obtener visitas por estado de acceso (CONCEDIDO/DENEGADO)
|
rutas.put('/api/visitas/:id_visita', controladorVisitas.actualizarVisita);
|
||||||
// GET /api/visitas-miembros/estado/:estado_acceso
|
// Eliminar lógicamente una visita (ej. marcar como 'ANULADA' si tuvieras ese estado)
|
||||||
rutas.get('/api/visitas-miembros/estado/:estado_acceso', controladorVisitasMiembros.listarVisitasPorEstadoAcceso);
|
rutas.delete('/api/visitas/:id_visita', controladorVisitas.eliminarVisita); // Implementación para una eliminación lógica
|
||||||
// (Opcional) Obtener visitas por área de acceso
|
// Rutas de consulta específicas para visitas
|
||||||
// GET /api/visitas-miembros/area/:nombre_area
|
rutas.get('/api/visitas/por-cliente/:client_id', controladorVisitas.listarVisitasPorCliente);
|
||||||
rutas.get('/api/visitas-miembros/area/:nombre_area', controladorVisitasMiembros.listarVisitasPorArea);
|
rutas.get('/api/visitas/por-miembro/:id_miembro', controladorVisitas.listarVisitasPorMiembro);
|
||||||
|
rutas.get('/api/visitas/estado/:estado_acceso', controladorVisitas.listarVisitasPorEstadoAcceso);
|
||||||
|
rutas.get('/api/visitas/area/:nombre_area', controladorVisitas.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);
|
||||||
|
|||||||
Reference in New Issue
Block a user