Creacion de una nueva ruta para consulta de clientes.

This commit is contained in:
Pablinux
2025-06-06 08:48:56 -05:00
parent 053c55ca96
commit 0fa29e719b
3 changed files with 150 additions and 44 deletions

View File

@@ -173,6 +173,53 @@ controlador.app_pedidos_clientes = (req, res) => {
});
};
/**
* @function consulta_clientesApps
* @description Consulta clientes por nombre, RUC o cédula para el autocomplete en aplicaciones.
* Espera un parámetro de consulta en la URL: /consultaClientesJson?consulta=dato
* Donde 'dato' puede ser parte del nombre, RUC o cédula.
* @param {Object} req - Objeto de solicitud de Express (req.query.consulta).
* @param {Object} res - Objeto de respuesta de Express.
*/
controlador.consulta_clientesApps = (req, res) => { // Nombre de la función cambiado aquí
const { consulta } = req.query; // Obtener el parámetro 'consulta' de la URL
if (!consulta) {
return res.status(400).json({ mensaje: 'El parámetro "consulta" es obligatorio para la búsqueda.' });
}
req.getConnection((err, connection) => {
if (err) {
console.error('Error al obtener conexión para consulta de clientes:', err);
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener conexión', error: err.message });
}
const searchTerm = `%${consulta}%`; // Preparar el término de búsqueda para operaciones LIKE
// Consulta SQL para buscar clientes por 'client_nombre' o 'client_rucCed'
// Limita los resultados a 10 para evitar cargar demasiados datos en el frontend
const query = `
SELECT
client_id,
client_nombre,
client_rucCed
FROM
clientes
WHERE
client_nombre LIKE ? OR client_rucCed LIKE ?
LIMIT 10;
`;
// Ejecutar la consulta con el término de búsqueda para ambos campos
connection.query(query, [searchTerm, searchTerm], (err, rows) => {
if (err) {
console.error('Error al consultar clientes en consulta_clientesApps:', err); // Log actualizado
return res.status(500).json({ mensaje: 'Error interno del servidor al consultar clientes', error: err.message });
}
res.json(rows); // Devolver los resultados en formato JSON
});
});
}
//CONSULTA CLIENTE CLOUD C.I-RUC => ruta:/busquedaSRI
var data_url0 = 'http://www.ecuadorlegalonline.com/modulo/sri/consulta-ruc/ruc.api.php';
var data_url1 = "https://siax-system.net/app/clientes_cloud.php";

View File

@@ -116,49 +116,105 @@ const controladorMiembros = {
* @param {Object} req - Objeto de solicitud de Express (req.body contiene los datos del miembro).
* @param {Object} res - Objeto de respuesta de Express.
*/
/**
* @function crearMiembro
* @description Crea un nuevo registro de miembro, generando la matrícula automáticamente
* basándose en el tipo de membresía, un contador de membresías por cliente y el ID del cliente.
* NO MODIFICA TABLAS NI REQUIERE TABLAS ADICIONALES.
* @param {Object} req - Objeto de solicitud de Express (req.body contiene los datos del miembro).
* @param {Object} res - Objeto de respuesta de Express.
*/
crearMiembro: (req, res) => {
const {
matricula, client_id, id_tipo_membresia, fecha_inicio, fecha_fin,
observaciones, creado_por // Añadir creado_por si lo envías desde el frontend
client_id, id_tipo_membresia, fecha_inicio, fecha_fin,
observaciones, creado_por
} = req.body;
// Validar campos obligatorios
if (!matricula || !client_id || !id_tipo_membresia || !fecha_inicio || !fecha_fin) {
return res.status(400).json({ mensaje: 'Faltan campos obligatorios para crear el miembro (matricula, client_id, id_tipo_membresia, fecha_inicio, fecha_fin).' });
// Validar campos obligatorios que vienen del frontend
if (!client_id || !id_tipo_membresia || !fecha_inicio || !fecha_fin) {
return res.status(400).json({ mensaje: 'Faltan campos obligatorios para crear el miembro (client_id, id_tipo_membresia, fecha_inicio, fecha_fin).' });
}
req.getConnection((err, connection) => {
req.getConnection(async (err, connection) => {
if (err) {
console.error('Error al obtener conexión para crear miembro:', err);
return res.status(500).json({ mensaje: 'Error interno del servidor al obtener conexión', error: err.message });
}
try {
// Iniciar una transacción para asegurar la consistencia si la generación requiere múltiples pasos
await connection.promise().beginTransaction();
// 1. Obtener el nombre del tipo de membresía para el prefijo (ej. 'MP' de 'Membresia Premium')
const [tipoMembresiaRows] = await connection.promise().query(
'SELECT nombre_tipo FROM clientes_membresias WHERE id_tipo_membresia = ?',
[id_tipo_membresia]
);
if (tipoMembresiaRows.length === 0) {
await connection.promise().rollback(); // Revertir la transacción
return res.status(400).json({ mensaje: 'Tipo de membresía no encontrado.' });
}
const nombreTipoMembresia = tipoMembresiaRows[0].nombre_tipo;
// Derivar prefijo: Tomar las iniciales en mayúsculas. Ej: "Membresia Premium" -> "MP"
const prefijoMembresia = nombreTipoMembresia.split(' ')
.map(word => word[0])
.join('')
.toUpperCase();
// 2. Contar el número de membresías previas de este cliente
const [countMembresiasRows] = await connection.promise().query(
'SELECT COUNT(*) AS total_membresias FROM clientes_miembros WHERE client_id = ?',
[client_id]
);
const contadorCliente = countMembresiasRows[0].total_membresias + 1; // Sumar 1 para la nueva membresía
// Formatear contador a 2 dígitos (ej. 1 -> '01', 10 -> '10')
const contadorFormateado = String(contadorCliente).padStart(2, '0');
// Formatear client_id a 6 dígitos (ej. 21 -> '000021')
const clienteIdFormateado = String(client_id).padStart(6, '0');
// 3. Ensamblar la matrícula final: MP-01-000021
const matriculaGenerada = `${prefijoMembresia}-${contadorFormateado}-${clienteIdFormateado}`;
// 4. Insertar el nuevo miembro con la matrícula generada
const query = `
INSERT INTO clientes_miembros (
matricula, client_id, id_tipo_membresia, estado, fecha_registro,
fecha_inicio, fecha_fin, observaciones, creado_por
) VALUES (?, ?, ?, ?, NOW(), ?, ?, ?, ?)
`;
// 'ACTIVO' como estado por defecto en el INSERT
const values = [
matricula, client_id, id_tipo_membresia, 'ACTIVO',
matriculaGenerada, client_id, id_tipo_membresia, 'ACTIVO',
fecha_inicio, fecha_fin, observaciones, creado_por
];
connection.query(query, values, (err, result) => {
if (err) {
console.error('Error al crear miembro:', err);
if (err.code === 'ER_DUP_ENTRY') {
return res.status(409).json({ mensaje: 'Ya existe un miembro con esa matrícula.', error: err.message });
}
// Posibles errores de clave foránea (client_id o id_tipo_membresia no existen)
if (err.code === 'ER_NO_REFERENCED_ROW_2' || err.code === 'ER_NO_REFERENCED_ROW') {
return res.status(400).json({ mensaje: 'El cliente o el tipo de membresía especificado no existe.', error: err.message });
}
return res.status(500).json({ mensaje: 'Error interno del servidor al crear miembro', error: err.message });
}
res.status(201).json({ mensaje: 'Miembro creado exitosamente', id_miembro: result.insertId });
const [result] = await connection.promise().query(query, values);
await connection.promise().commit(); // Confirmar la transacción
res.status(201).json({
mensaje: 'Miembro creado exitosamente',
id_miembro: result.insertId,
matricula: matriculaGenerada // Devolvemos la matrícula generada
});
} catch (error) {
await connection.promise().rollback(); // Revertir la transacción en caso de error
console.error('Error en la lógica de creación de miembro:', error);
if (error.code === 'ER_DUP_ENTRY') {
// Esto es posible si el mismo cliente intenta registrar una membresía
// con la misma matrícula generada, lo cual ocurriría si ya tiene una.
// O si hubo un error en la lógica de conteo o formateo.
return res.status(409).json({ mensaje: `Ya existe un miembro con la matrícula generada (${error.sqlMessage}). Esto puede ocurrir si un cliente ya tiene una membresía con este tipo o si hay un problema con la generación del contador.`, error: error.message });
}
if (error.code === 'ER_NO_REFERENCED_ROW_2' || error.code === 'ER_NO_REFERENCED_ROW') {
return res.status(400).json({ mensaje: 'El cliente o el tipo de membresía especificado no existe. Asegúrate de que los IDs seleccionados sean válidos.', error: error.message });
}
return res.status(500).json({ mensaje: 'Error interno del servidor al crear miembro', error: error.message });
}
});
},

View File

@@ -5,6 +5,7 @@ const controladorClientes = require('../controladores/controlador_Clientes');
// Importa el NUEVO controlador de Membresías
const controladorMembresias = require('../controladores/controlador_Membresias');
const controladorMiembros = require('../controladores/controlador_Miembros');
//indice inical
rutas.get('/clientes', controladorClientes.ver);//ver lista de clientes
@@ -23,6 +24,13 @@ rutas.get('/eliminarCliente/:client_id', controladorClientes.eliminarCliente);
//almacena cliente
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
//*** Consultas de clientes(/consultaClientesJson?consulta=dato) donde dato puede ser nombre, ruc, cedula;
rutas.get('/consultaClientesJson', controladorClientes.app_pedidos_clientes);//consulta clientes: /consultaClientesJson?consulta=dato
rutas.get('/consulta_clientesApps', controladorClientes.consulta_clientesApps);
rutas.get('/busquedaSRI/', controladorClientes.buscarCli_sri);//API consulta clientes
//API CONSULTA CLIENTES: https://NAME_SERVER/api_consultaClientes?id=numero_rucOcedula => https://app.factura-e.net/api_consultaClientes?id=0701637498001
rutas.get('/api_consultaClientes/', controladorClientes.api_consultaCliente);//API consulta clientes
// --- Rutas RESTful para TIPOS de Membresías (tabla 'clientes_membresias') ---
// Estas rutas apuntarán al nuevo controlador_Membresias
@@ -68,10 +76,5 @@ rutas.get('/api/tipos-membresia/:id_tipo_membresia/miembros', controladorMiembro
// Ruta para obtener ciudades
rutas.get('/api/ciudades', controladorClientes.obtenerCiudades);
//APP_SIGMA consultas
rutas.get('/consultaClientesJson', controladorClientes.app_pedidos_clientes);//consulta clientes: /consultaClientesJson?consulta=dato
rutas.get('/busquedaSRI/', controladorClientes.buscarCli_sri);//API consulta clientes
//API CONSULTA CLIENTES: https://NAME_SERVER/api_consultaClientes?id=numero_rucOcedula => https://app.factura-e.net/api_consultaClientes?id=0701637498001
rutas.get('/api_consultaClientes/', controladorClientes.api_consultaCliente);//API consulta clientes
module.exports = rutas;