diff --git a/src/controladores/controlador_Clientes.js b/src/controladores/controlador_Clientes.js index a6c4579..7b45303 100644 --- a/src/controladores/controlador_Clientes.js +++ b/src/controladores/controlador_Clientes.js @@ -135,105 +135,7 @@ controlador.eliminarCliente = (req, res) => { }); } -/**** Listar miembros *****/ -controlador.listarMembresias = (req, res) => { - req.getConnection((err, conn) => { - if (err) { - return res.status(500).json({ error: 'Error de conexión' }); - } - conn.query('SELECT * FROM clientes_membresias ORDER BY nombre ASC', (err, membresias) => { - if (err) { - return res.status(500).json({ error: 'Error al consultar membresías' }); - } - res.json(membresias); - }); - }); -}; - -/**** Obtener membresía para edición (ahora vía /api/membresias/:id) *****/ -controlador.editarMembresia = (req, res) => { - const { id } = req.params; // *** MODIFICADO: id ahora viene de req.params *** - req.getConnection((err, conn) => { - if (err) { - return res.status(500).json({ error: 'Error de conexión' }); - } - - conn.query('SELECT * FROM clientes_membresias WHERE id = ?', [id], (err, membresia) => { - if (err) { - return res.status(500).json({ error: 'Error al consultar membresía' }); - } - if (membresia.length === 0) { - return res.status(404).json({ error: 'Membresía no encontrada' }); - } - res.json(membresia[0]); - }); - }); -}; - -/**** Guardar/Crear nueva membresía (vía POST /api/membresias) *****/ -controlador.guardarMembresia = (req, res) => { - const membresia = req.body; // Obtener los datos de la membresía desde el cuerpo de la solicitud - req.getConnection((err, conn) => { - if (err) { - return res.status(500).json({ error: 'Error de conexión' }); - } - - conn.query('INSERT INTO clientes_membresias SET ?', membresia, (err, result) => { - if (err) { - return res.status(500).json({ error: 'Error al guardar membresía' }); - } - res.status(201).json({ id: result.insertId, ...membresia, message: 'Membresía creada exitosamente' }); // 201 Created - }); - }); -}; - -/**** Actualizar membresía existente (vía PUT /api/membresias/:id) *****/ -controlador.actualizarMembresia = (req, res) => { - const { id } = req.params; // *** MODIFICADO: id ahora viene de req.params *** - const membresiaActualizada = req.body; // Obtener los datos actualizados de la membresía desde el cuerpo de la solicitud - req.getConnection((err, conn) => { - if (err) { - return res.status(500).json({ error: 'Error de conexión' }); - } - - conn.query('UPDATE clientes_membresias SET ? WHERE id = ?', [membresiaActualizada, id], (err, result) => { - if (err) { - return res.status(500).json({ error: 'Error al actualizar membresía' }); - } - if (result.affectedRows === 0) { - return res.status(404).json({ error: 'Membresía no encontrada' }); - } - res.json({ message: 'Membresía actualizada exitosamente' }); - }); - }); -}; - -/**** Eliminar membresía (vía DELETE /api/membresias/:id) *****/ -controlador.eliminarMembresia = (req, res) => { - const { id } = req.params; // *** MODIFICADO: id ahora viene de req.params *** - req.getConnection((err, conn) => { - if (err) { - return res.status(500).json({ error: 'Error de conexión' }); - } - - conn.query('DELETE FROM clientes_membresias WHERE id = ?', [id], (err, result) => { - if (err) { - return res.status(500).json({ error: 'Error al eliminar membresía' }); - } - if (result.affectedRows === 0) { - return res.status(404).json({ error: 'Membresía no encontrada' }); - } - res.json({ message: 'Membresía eliminada exitosamente' }); - }); - }); -}; - -/** - * controlador para obtener las ciudades de la base de datos - * @param {*} req - * @param {*} res - */ controlador.obtenerCiudades = (req, res) => { req.getConnection((err, conn) => { if (err) { diff --git a/src/controladores/controlador_Membresias.js b/src/controladores/controlador_Membresias.js new file mode 100644 index 0000000..ee21b20 --- /dev/null +++ b/src/controladores/controlador_Membresias.js @@ -0,0 +1,226 @@ +// src/controladores/controlador_Membresias.js + +// La conexión/pool se obtendrá a través de req.getConnection() inyectado por express-myconnection. + +const controladorMembresias = { + + // --- Funciones para Tipos de Membresía (clientes_membresias) --- + + /** + * @function listarTiposMembresia + * @description Lista todos los tipos de membresía disponibles, incluyendo información del combo ensamblado si aplica. + * @param {Object} req - Objeto de solicitud de Express. + * @param {Object} res - Objeto de respuesta de Express. + */ + listarTiposMembresia: async (req, res) => { + let connection; + try { + connection = await req.getConnection(); + const [rows] = await connection.query(` + SELECT + cm.id_tipo_membresia, + cm.nombre_tipo, + cm.categoria_membresia, + cm.es_grupal, + cm.capacidad_maxima_miembros, + cm.valor, + cm.descripcion, + cm.duracion_dias, + cm.visitas_maximas_diarias, + cm.areas_de_acceso, + cm.id_combo_ensamblado_incluido, + cm.cantidad_combo_incluido, + pe.PdctEnsb_codigoEnsamble AS codigo_combo_ensamblado, + cm.estado_tipo, + cm.fecha_creacion, + cm.fecha_modificacion + FROM + clientes_membresias cm + LEFT JOIN + productos_Ensamblados pe ON cm.id_combo_ensamblado_incluido = pe.PdctEnsb_ID + `); + res.json(rows); + } catch (error) { + console.error('Error al listar tipos de membresía:', error); + res.status(500).json({ mensaje: 'Error interno del servidor al listar tipos de membresía', error: error.message }); + } finally { + if (connection && typeof connection.release === 'function') connection.release(); + } + }, + + /** + * @function obtenerTipoMembresiaPorId + * @description Obtiene un tipo de membresía específico por su ID. + * @param {Object} req - Objeto de solicitud de Express (req.params.id contiene el ID del tipo de membresía). + * @param {Object} res - Objeto de respuesta de Express. + */ + obtenerTipoMembresiaPorId: async (req, res) => { + const { id } = req.params; // ID de la tabla clientes_membresias + let connection; + try { + connection = await req.getConnection(); + const [rows] = await connection.query(` + SELECT + cm.id_tipo_membresia, + cm.nombre_tipo, + cm.categoria_membresia, + cm.es_grupal, + cm.capacidad_maxima_miembros, + cm.valor, + cm.descripcion, + cm.duracion_dias, + cm.visitas_maximas_diarias, + cm.areas_de_acceso, + cm.id_combo_ensamblado_incluido, + cm.cantidad_combo_incluido, + pe.PdctEnsb_codigoEnsamble AS codigo_combo_ensamblado, + cm.estado_tipo, + cm.fecha_creacion, + cm.fecha_modificacion + FROM + clientes_membresias cm + LEFT JOIN + productos_Ensamblados pe ON cm.id_combo_ensamblado_incluido = pe.PdctEnsb_ID + WHERE cm.id_tipo_membresia = ?`, [id]); + + if (rows.length === 0) { + return res.status(404).json({ mensaje: 'Tipo de membresía no encontrado' }); + } + res.json(rows[0]); + } catch (error) { + console.error('Error al obtener tipo de membresía:', error); + res.status(500).json({ mensaje: 'Error interno del servidor al obtener tipo de membresía', error: error.message }); + } finally { + if (connection && typeof connection.release === 'function') connection.release(); + } + }, + + /** + * @function crearTipoMembresia + * @description Crea un nuevo tipo de membresía. + * @param {Object} req - Objeto de solicitud de Express (req.body contiene los datos del tipo de membresía). + * @param {Object} res - Objeto de respuesta de Express. + */ + crearTipoMembresia: async (req, res) => { + const { + nombre_tipo, categoria_membresia, es_grupal, capacidad_maxima_miembros, + valor, descripcion, duracion_dias, visitas_maximas_diarias, + areas_de_acceso, id_combo_ensamblado_incluido, cantidad_combo_incluido + } = req.body; + + // Validaciones básicas de campos obligatorios + if (!nombre_tipo || es_grupal === undefined || valor === undefined) { + return res.status(400).json({ mensaje: 'Faltan campos obligatorios para el tipo de membresía (nombre_tipo, es_grupal, valor).' }); + } + + let connection; + try { + connection = await req.getConnection(); + const [result] = await connection.query( + `INSERT INTO clientes_membresias ( + nombre_tipo, categoria_membresia, es_grupal, capacidad_maxima_miembros, + valor, descripcion, duracion_dias, visitas_maximas_diarias, + areas_de_acceso, id_combo_ensamblado_incluido, cantidad_combo_incluido, + estado_tipo, fecha_creacion + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'ACTIVO', NOW())`, + [ + nombre_tipo, categoria_membresia, es_grupal, capacidad_maxima_miembros, + valor, descripcion, duracion_dias, visitas_maximas_diarias, + areas_de_acceso, id_combo_ensamblado_incluido, cantidad_combo_incluido + ] + ); + res.status(201).json({ mensaje: 'Tipo de membresía creado exitosamente', id: result.insertId }); + } catch (error) { + console.error('Error al crear tipo de membresía:', error); + // Manejo de error específico por entrada duplicada (ej. nombre_tipo único) + if (error.code === 'ER_DUP_ENTRY') { + return res.status(409).json({ mensaje: 'Ya existe un tipo de membresía con ese nombre.', error: error.message }); + } + res.status(500).json({ mensaje: 'Error interno del servidor al crear tipo de membresía', error: error.message }); + } finally { + if (connection && typeof connection.release === 'function') connection.release(); + } + }, + + /** + * @function actualizarTipoMembresia + * @description Actualiza un tipo de membresía existente por su ID. + * @param {Object} req - Objeto de solicitud de Express (req.params.id para el ID, req.body para los datos). + * @param {Object} res - Objeto de respuesta de Express. + */ + actualizarTipoMembresia: async (req, res) => { + const { id } = req.params; // ID del tipo de membresía a actualizar + const { + nombre_tipo, categoria_membresia, es_grupal, capacidad_maxima_miembros, + valor, descripcion, duracion_dias, visitas_maximas_diarias, + areas_de_acceso, id_combo_ensamblado_incluido, cantidad_combo_incluido, estado_tipo + } = req.body; + + // Validaciones básicas de campos obligatorios + if (!nombre_tipo || es_grupal === undefined || valor === undefined || !estado_tipo) { + return res.status(400).json({ mensaje: 'Faltan campos obligatorios para actualizar el tipo de membresía (nombre_tipo, es_grupal, valor, estado_tipo).' }); + } + + let connection; + try { + connection = await req.getConnection(); + const [result] = await connection.query( + `UPDATE clientes_membresias SET + nombre_tipo = ?, categoria_membresia = ?, es_grupal = ?, + capacidad_maxima_miembros = ?, valor = ?, descripcion = ?, + duracion_dias = ?, visitas_maximas_diarias = ?, areas_de_acceso = ?, + id_combo_ensamblado_incluido = ?, cantidad_combo_incluido = ?, + estado_tipo = ?, fecha_modificacion = NOW() + WHERE id_tipo_membresia = ?`, + [ + nombre_tipo, categoria_membresia, es_grupal, capacidad_maxima_miembros, + valor, descripcion, duracion_dias, visitas_maximas_diarias, + areas_de_acceso, id_combo_ensamblado_incluido, cantidad_combo_incluido, estado_tipo, id + ] + ); + + if (result.affectedRows === 0) { + return res.status(404).json({ mensaje: 'Tipo de membresía no encontrado para actualizar' }); + } + res.json({ mensaje: 'Tipo de membresía actualizado exitosamente' }); + } catch (error) { + console.error('Error al actualizar tipo de membresía:', error); + // Manejo de error específico por entrada duplicada + if (error.code === 'ER_DUP_ENTRY') { + return res.status(409).json({ mensaje: 'Ya existe otro tipo de membresía con ese nombre.', error: error.message }); + } + res.status(500).json({ mensaje: 'Error interno del servidor al actualizar tipo de membresía', error: error.message }); + } finally { + if (connection && typeof connection.release === 'function') connection.release(); + } + }, + + /** + * @function eliminarTipoMembresia + * @description Elimina lógicamente un tipo de membresía por su ID (cambia su estado a 'ELIMINADO'). + * @param {Object} req - Objeto de solicitud de Express (req.params.id para el ID). + * @param {Object} res - Objeto de respuesta de Express. + */ + eliminarTipoMembresia: async (req, res) => { + const { id } = req.params; + let connection; + try { + connection = await req.getConnection(); + // Se recomienda una eliminación lógica para mantener la integridad referencial + // si hay adquisiciones de membresía o historial asociados. + const [result] = await connection.query('UPDATE clientes_membresias SET estado_tipo = "ELIMINADO" WHERE id_tipo_membresia = ?', [id]); + + if (result.affectedRows === 0) { + return res.status(404).json({ mensaje: 'Tipo de membresía no encontrado para eliminar' }); + } + res.json({ mensaje: 'Tipo de membresía eliminado (lógicamente) exitosamente' }); + } catch (error) { + console.error('Error al eliminar tipo de membresía:', error); + res.status(500).json({ mensaje: 'Error interno del servidor al eliminar tipo de membresía', error: error.message }); + } finally { + if (connection && typeof connection.release === 'function') connection.release(); + } + } +}; + +module.exports = controladorMembresias; \ No newline at end of file diff --git a/src/rutas/rt_clientes.js b/src/rutas/rt_clientes.js index e19ba34..55dab54 100644 --- a/src/rutas/rt_clientes.js +++ b/src/rutas/rt_clientes.js @@ -2,6 +2,8 @@ const express = require('express'); const rutas = express.Router(); const controladorClientes = require('../controladores/controlador_Clientes'); +// Importa el NUEVO controlador de Membresías +const controladorMembresias = require('../controladores/controlador_Membresias'); //indice inical rutas.get('/clientes', controladorClientes.ver);//ver lista de clientes @@ -21,18 +23,13 @@ rutas.get('/eliminarCliente/:client_id', controladorClientes.eliminarCliente); rutas.post('/addCliente', controladorClientes.guardaCliente);//almacena en bd el nuevo cliente: https://app.factura-e.net/addCliente rutas.get('/addClienteForm', controladorClientes.verFormNclientes);//muesta form para crear cliente -// --- Rutas RESTful para Membresías --- https://app.factura-e.net/api/membresias -// Listar todas las membresías (GET /api/membresias) -rutas.get('/api/membresias', controladorClientes.listarMembresias); -// Obtener una membresía específica por ID (GET /api/membresias/:id) -// Usado para "editar" (obtener datos para un formulario de edición) -rutas.get('/api/membresias/:id', controladorClientes.editarMembresia); -// Crear una nueva membresía (POST /api/membresias) -rutas.post('/api/membresias', controladorClientes.guardarMembresia); -// Actualizar una membresía existente por ID (PUT /api/membresias/:id) -rutas.put('/api/membresias/:id', controladorClientes.actualizarMembresia); -// Eliminar una membresía por ID (DELETE /api/membresias/:id) -rutas.delete('/api/membresias/:id', controladorClientes.eliminarMembresia); +// --- Rutas RESTful para TIPOS de Membresías (tabla 'clientes_membresias') --- +// Estas rutas apuntarán al nuevo controlador_Membresias +rutas.get('/api/tipos-membresia', controladorMembresias.listarTiposMembresia); +rutas.get('/api/tipos-membresia/:id', controladorMembresias.obtenerTipoMembresiaPorId); +rutas.post('/api/tipos-membresia', controladorMembresias.crearTipoMembresia); +rutas.put('/api/tipos-membresia/:id', controladorMembresias.actualizarTipoMembresia); +rutas.delete('/api/tipos-membresia/:id', controladorMembresias.eliminarTipoMembresia); // Ruta para obtener ciudades rutas.get('/api/ciudades', controladorClientes.obtenerCiudades);