-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.js
More file actions
542 lines (450 loc) · 19.2 KB
/
app.js
File metadata and controls
542 lines (450 loc) · 19.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
// Importar la libreria:::::::::::::::::::::::::::::
const express = require("express");
const mysql = require("mysql2");
const session = require('express-session');
//objetos para llamar los métodos de express:::::::::::::::::::::::::::::
const app = express();
app.use(session({
secret: 'tu_secreto', // Cambia esto a un valor seguro en un entorno de producción
resave: false,
saveUninitialized: true
}));
let conexion = mysql.createConnection({
host: "localhost",
database: "solicitudesestudiantiles",
user: "root",
password: "Juanito2021"
});
//configuraciones
app.set("view engine", "ejs");
app.set("views", __dirname + "/views"); // Especifica el directorio de las vistas
app.use(express.json());
app.use(express.urlencoded({extended:false}));
app.get("/", function(req, res){
res.render("index");
});
// Ruta para manejar el formulario de inicio de sesión
app.post('/iniciar-sesion', function(req, res){
const datos = req.body;
let correo = datos.correo;
let pass = datos.contrasena;
// Llamar al procedimiento almacenado
conexion.query('CALL sp_usuariosLogin(?, ?)', [correo, pass], (error, results) => {
if (error) {
console.error('Error al llamar al procedimiento almacenado:', error);
return res.status(500).send('Error al llamar al procedimiento almacenado');
}
const mensajeResultado = results[0][0].Result;
// Verificar el resultado del procedimiento almacenado
if (mensajeResultado === 'Acceso exitoso!') {
// Redirigir a la página de bienvenida si el inicio de sesión es exitoso
// Almacena el usuario en la sesión
req.session.usuario = correo; // Asume que `correo` es el nombre de usuario
res.redirect('/dashboard');
} else {
// Redirigir a la página de inicio de sesión con un mensaje de error
res.render('index', { error: 'Credenciales incorrectas' });
}
});
});
// Ruta para manejar la página de dashboard
app.get('/dashboard', function (req, res) {
// Recupera el usuario desde la sesión
const usuario = req.session.usuario;
// Verifica si hay mensajes de éxito o error en la URL
const exito = req.query.exito === 'true';
const error = req.query.error === 'true';
const mensaje = req.query.mensaje || null;
// Consulta SQL para obtener el número de documento
const sqlNumeroDocumento = 'SELECT usuNumeroDocumento FROM usuario WHERE UsuCorreoInstitucional = ?';
conexion.query(sqlNumeroDocumento, [usuario], (errNumeroDocumento, numeroDocumentoResults) => {
if (errNumeroDocumento) {
console.error("Error al obtener el número de documento: " + errNumeroDocumento.message);
// Manejar el error adecuadamente
return;
}
const numeroDocumento = numeroDocumentoResults[0].usuNumeroDocumento;
// Consulta SQL para obtener los comentarios recientes
const sqlConsultaComentarios = `SELECT com.CAdmIdComentarioAdministrativo,
com.CAdmSolicitudId,
tra.TraNombre,
est.EtaNombreEtapa,
com.CAdmContenido,
com.CAdmFechaHora
FROM comentarioadministrativo AS com
JOIN EtapaSolicitud AS est
ON com.CAdmEtapaSolicitudId = est.Eta_idEtapa
JOIN Solicitud AS sol
ON sol.solId = com.CAdmSolicitudId
JOIN Tramite AS tra
ON tra.TraId = sol.SolTramiteId
WHERE sol.SolEstNumeroDocumento = ?
ORDER BY com.CAdmFechaHora DESC LIMIT 5`;
// Ejecutar la consulta SQL
conexion.query(sqlConsultaComentarios, [numeroDocumento], (errorConsulta, resultadosConsulta) => {
if (errorConsulta) {
console.error('Error al consultar comentarios recientes:', errorConsulta);
return res.status(500).send('Error interno del servidor');
}
// Resultados de la consulta
const comentariosRecientes = resultadosConsulta;
console.log(comentariosRecientes);
// Haz lo que necesites con la información del usuario, los mensajes y los comentarios recientes
res.render('dashboard', { usuario, exito, error, mensaje, comentariosRecientes });
});
});
});
// Ruta para cerrar sesión
app.get('/logout', function(req, res) {
// Destruye la sesión y proporciona un callback
req.session.destroy(function(err) {
if (err) {
console.error('Error al cerrar sesión:', err);
return res.status(500).send('Error al cerrar sesión');
}
// Si el callback se ejecuta, la sesión se ha destruido con éxito
console.log('Sesión destruida con éxito');
// Redirige al usuario a la página de inicio de sesión (o a donde prefieras)
res.redirect('/index');
});
});
// Ruta para la página de inicio de sesión
app.get('/index', function(req, res) {
// Puedes renderizar la vista de inicio de sesión aquí
res.render('index');
});
// Ruta para la página de nueva solicitud
app.get('/nueva_solicitud', async function(req, res) {
try {
// Consulta de tipos de trámite
const tiposTramite = await queryAsync('SELECT TraId, TraNombre FROM tramite');
// Obtener el número de documento del usuario
const usuario = req.session.usuario;
const numeroDocumentoResults = await queryAsync('SELECT usuNumeroDocumento FROM usuario WHERE UsuCorreoInstitucional = ?', [usuario]);
const numeroDocumento = numeroDocumentoResults[0].usuNumeroDocumento;
// Obtener la carrera del usuario
const carreraResults = await queryAsync('SELECT carNombreCarrera FROM carrera JOIN historiaacademica ON HAcaIdCarrera = CarIdCarrera WHERE HAcaNumeroDocumento = ?', [numeroDocumento]);
const carrera = carreraResults[0].carNombreCarrera;
const mensaje = null;
// Renderizar la vista y pasar los resultados
res.render('nueva_solicitud', { opciones: tiposTramite, numeroDocumento, carrera, usuario });
} catch (error) {
console.error('Error en la ruta /nueva_solicitud:', error);
return res.status(500).send('Error en la ruta /nueva_solicitud');
}
});
// Función para realizar una consulta a la base de datos de manera asíncrona
function queryAsync(sql, values) {
return new Promise((resolve, reject) => {
conexion.query(sql, values, function(error, results, fields) {
if (error) {
reject(error);
} else {
resolve(results);
}
});
});
}
//tabla de mapeo entre opciones y procedimientos almacenados
const opcionesProcedimientos = {
'Autorizacion cursar Menos de la carga minima': 'sp_revisarTra_AutorizacionCargaMinima',
'Cancelacion de Asignaturas posterior mitad periodo academico': 'sp_revisarTra_CancelacionAsignaturasMitadPAcademico',
'Cancelación de periodo academico': 'sp_revisarTra_CancelacionPeriodoAcademico',
'Doble titulacion': 'sp_revisarTra_DobleTitulacion',
'Homologacion y convalidacion de asignaturas': 'sp_revisarTra_HomologacionConvalidacionAsignaturas',
'Registro trabajo de grado': 'sp_revisarTra_RegistoTrabajoGrado',
'Reingreso': 'sp_revisarTra_Reingreso',
'Reserva cupo adicional': 'sp_revisarTra_ReservaCupoAdicional',
'Traslado programa Curricular': 'sp_revisarTra_TrasladoProgramaCurricular'
};
app.get('/obtener-resultados-tramite', function (req, res) {
// Obtén el nombre del trámite seleccionado de la consulta
const tramiteSeleccionado = req.query.tramite;
console.log(tramiteSeleccionado);
// Accede a las variables adicionales pasadas desde la vista
const numeroDocumento = req.query.numeroDocumento;
const carrera = req.query.carrera;
// Verifica si la opción existe en el mapeo
if (opcionesProcedimientos.hasOwnProperty(tramiteSeleccionado)) {
// Obten el nombre del procedimiento almacenado asociado a la opción
const nombreProcedimiento = opcionesProcedimientos[tramiteSeleccionado];
console.log(nombreProcedimiento);
// Ajusta los parámetros del procedimiento según tus necesidades
conexion.query(`CALL ${nombreProcedimiento}(?, ?, ?)`, [numeroDocumento, carrera, 4], (error, results) => {
if (error) {
console.error('Error al llamar al procedimiento almacenado:', error);
return res.status(500).json({ error: 'Error al llamar al procedimiento almacenado' });
}
// Manejar los resultados como desees
const datosResultados = results[0];
console.log(datosResultados);
// Enviar los resultados al cliente en formato JSON
res.json(datosResultados);
});
} else {
// La opción no está en el mapeo, puedes manejar esto como desees
res.status(400).send('Opción de trámite no válida');
}
});
// Ruta para manejar la presentación del formulario
app.post('/crear_solicitud', (req, res) => {
// Recuperar los valores del formulario
const numeroDocumento = req.body.numeroDocumento;
const numeroTramite = req.body.opcion;
console.log(numeroTramite);
// Llamar al procedimiento almacenado
const sql = 'CALL sp_estudianteRadicarSolicitud(?, ?, 6)';
conexion.query(sql, [numeroDocumento, numeroTramite], (err, result) => {
if (err) {
console.error(`Error al ejecutar el procedimiento almacenado: ${err.message}`);
res.status(500).send('Error interno del servidor');
} else {
console.log('Procedimiento almacenado ejecutado correctamente');
const mensaje = result[0][0].Mensaje;
if (mensaje === 'Solicitud creada exitosamente!') {
// Redirige a la vista de éxito con el mensaje de éxito
res.redirect('/dashboard?exito=true&mensaje=' + encodeURIComponent(mensaje));
} else {
console.error(`Error al radicar la solicitud: ${mensaje}`);
// Redirige a la vista de error con el mensaje de error
res.redirect('/dashboard?error=true&mensaje=' + encodeURIComponent(mensaje));
}
}
});
});
// Ruta mis solicitudes
app.get('/mis_solicitudes', async function(req, res) {
try {
const usuario = req.session.usuario;
// Consulta SQL para obtener el número de documento
const sqlNumeroDocumento = 'SELECT usuNumeroDocumento FROM usuario WHERE UsuCorreoInstitucional = ?';
const numeroDocumentoResults = await queryAsync(sqlNumeroDocumento, [usuario]);
if (!numeroDocumentoResults || !numeroDocumentoResults[0]) {
console.error("No se encontró el número de documento para el usuario:", usuario);
// Manejar el caso sin resultados adecuadamente
return res.status(500).send('Error en la ruta /mis_solicitudes');
}
const numeroDocumento = numeroDocumentoResults[0].usuNumeroDocumento;
console.log(numeroDocumento);
// Solicitudes activas
const solicitudesResults = await queryAsync(`
WITH UltimoEstadoSolicitud AS (
SELECT
sol.SolId,
est.EstNombreEstado,
tra.traNombre,
sol.SolFechaEstimadaRespuesta,
ROW_NUMBER() OVER (PARTITION BY sol.SolId ORDER BY she.SEstFechaHora DESC) AS RowNum
FROM
solicitud AS sol
JOIN Solicitud_has_Estado AS she ON she.SEstSolicitudId = sol.solId
JOIN Estado AS est ON she.SEstdEstadoId = est.EstId
JOIN tramite AS tra ON sol.SolTramiteId = tra.TraId
WHERE
sol.SolEstNumeroDocumento = ?
)
SELECT
SolId,
EstNombreEstado,
traNombre,
SolFechaEstimadaRespuesta
FROM
UltimoEstadoSolicitud
WHERE
RowNum = 1;`, [numeroDocumento]);
const solicitudes = solicitudesResults;
console.log(solicitudes);
// Renderizar la vista y pasar los resultados
res.render('mis_solicitudes', { solicitudes, usuario });
} catch (error) {
console.error('Error en la ruta /mis_solicitudes:', error);
return res.status(500).send('Error en la ruta /mis_solicitudes');
}
});
// Función para realizar una consulta a la base de datos de manera asíncrona
function queryAsync(sql, values) {
return new Promise((resolve, reject) => {
conexion.query(sql, values, function(error, results, fields) {
if (error) {
reject(error);
} else {
resolve(results);
}
});
});
}
// Ruta info_solicitud
app.get('/info_solicitud/:id', async function(req, res) {
try {
const solicitudId = req.params.id;
const usuario = req.session.usuario;
// Realizar la consulta para obtener la información de la solicitud por ID
const solicitudResults = await queryAsync(`
SELECT
sol.SolId,
sol.SolEstNumeroDocumento,
sol.SolFechaHoraRadicacion,
sol.SolFechaEstimadaRespuesta,
est.EstNombreEstado,
tra.traNombre,
sol.SolFechaEstimadaRespuesta
FROM
solicitud AS sol
JOIN Solicitud_has_Estado AS she ON she.SEstSolicitudId = sol.solId
JOIN Estado AS est ON she.SEstdEstadoId = est.EstId
JOIN tramite AS tra ON sol.SolTramiteId = tra.TraId
WHERE
sol.SolId = ?
`, [solicitudId]);
if (!solicitudResults || solicitudResults.length === 0) {
// Manejar el caso si la solicitud no se encuentra
return res.status(404).send('Solicitud no encontrada');
}
const solicitud = solicitudResults[0];
// Realizar la consulta para obtener todos los comentarios del estudiante de la solicitud
const comentariosEstudianteResults = await queryAsync(`
SELECT
CEstContenido,
CEstFechaHora
FROM
ComentarioEstudiante
WHERE
CEstSolicitudId = ?
`, [solicitudId]);
const comentariosEstudiante = comentariosEstudianteResults;
// Realizar la consulta para obtener todos los comentarios del administrativo de la solicitud
const comentariosAdministrativoResults = await queryAsync(`
SELECT
CAdmContenido,
CAdmFechaHora
FROM
ComentarioAdministrativo
WHERE
CAdmSolicitudId = ?
`, [solicitudId]);
const comentariosAdministrativo = comentariosAdministrativoResults;
// Renderizar la vista para mostrar la información de la solicitud
res.render('vista_solicitud', { solicitud, comentariosEstudiante, comentariosAdministrativo, usuario});
} catch (error) {
console.error('Error en la ruta /info_solicitud:', error);
return res.status(500).send('Error en la ruta /info_solicitud');
}
});
//Realizar comentario
app.get('/comentarioEstudiante/:id', async function(req, res) {
try {
const solicitudId = req.params.id;
const usuario = req.session.usuario;
// Consulta SQL para obtener el número de documento
const sqlNumeroDocumento = 'SELECT usuNumeroDocumento FROM usuario WHERE UsuCorreoInstitucional = ?';
const numeroDocumentoResults = await queryAsync(sqlNumeroDocumento, [usuario]);
if (!numeroDocumentoResults || !numeroDocumentoResults[0]) {
console.error("No se encontró el número de documento para el usuario:", usuario);
// Manejar el caso sin resultados adecuadamente
return res.status(500).send('Error en la ruta /mis_solicitudes');
}
const numeroDocumento = numeroDocumentoResults[0].usuNumeroDocumento;
// Renderizar la vista para mostrar la información de la solicitud
res.render('nuevo_comentario', { solicitudId, numeroDocumento, usuario});
} catch (error) {
console.error('Error en la ruta /info_solicitud:', error);
return res.status(500).send('Error en la ruta /info_solicitud');
}
});
// Ruta para manejar la creación del comentario
app.post('/crearComentario', async function (req, res) {
try {
const datos = req.body;
let comentario = datos.comentario;
let numeroDocumento = datos.numeroDocumento;
let solicitudId = datos.idSolicitud;
// Llama al procedimiento almacenado
const resultadoSP = await queryAsync(
'CALL sp_estudianteCrearComentarioSolicitud(?, ?, ?)',
[comentario, numeroDocumento, solicitudId]
);
// Analiza el resultado del procedimiento almacenado
const mensaje = resultadoSP[0][0].Mensaje;
// Puedes realizar cualquier otra lógica necesaria después de crear el comentario
// Redirige a la página de información de la solicitud
res.redirect(`/info_solicitud/${solicitudId}`);
} catch (error) {
console.error('Error en la ruta /crearComentario', error);
return res.status(500).send('Error en la ruta /crearComentario');
}
});
//Ruta para registro usuario
app.post('/registro', async function (req, res) {
try {
const {
tipoDocumento,
numeroDocumento,
nombres,
apellidos,
telefono,
edad,
email,
password,
areaCurricular,
organismoColegiado,
} = req.body;
// Llama al procedimiento almacenado
const resultadoSP = await queryAsync(
'CALL sp_registroEstudiantes(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
[
tipoDocumento,
numeroDocumento,
nombres,
apellidos,
telefono,
edad, // Suponiendo que tienes una función para calcular la edad
email,
password,
areaCurricular,
organismoColegiado,
]
);
// Analiza el resultado del procedimiento almacenado
const mensaje = resultadoSP[0][0].Mensaje;
// Puedes realizar cualquier otra lógica necesaria después de registrar al usuario
// Redirige a la página de inicio de sesión u otra página según tus necesidades
res.redirect('/index');
} catch (error) {
console.error('Error en la ruta /registro', error);
return res.status(500).send('Error en la ruta /registro');
}
});
app.get("/registrarse", async function(req, res){
const tiposDocumento= await queryAsync('SELECT TDocIdTipoDocumento, TDocDescripcion FROM TipoDocumento');
res.render("registro", {opciones: tiposDocumento});
});
//Ruta cambiar contraseña
app.get("/recuperarPass", function(req, res){
res.render("recuperarPass");
});
app.post('/recuperarPassword', async function (req, res) {
try {
const { email, nuevaContrasena, confirmarContrasena } = req.body;
// Verificar que las contraseñas coincidan
if (nuevaContrasena !== confirmarContrasena) {
return res.status(400).send('Las contraseñas no coinciden');
}
// Llamar al procedimiento almacenado para cambiar la contraseña
const resultadoSP = await queryAsync('CALL sp_cambiarContrasena(?, ?)', [
email,
nuevaContrasena,
]);
// Analizar el resultado del procedimiento almacenado
const mensaje = resultadoSP[0][0].Mensaje;
// Redirige a la página de inicio de sesión u otra página según tus necesidades
res.redirect('/index?mensajeCambioPass=CambioExitoso');
} catch (error) {
console.error('Error en la ruta /recuperarPassword', error);
}
});
//middleware :::::::::::::::::::::::::::::
app.use(express.static("public"));
//configurar el puerto usado para el servidor local:::::::::::::::::::::::::::::
app.listen(3000, function(){
console.log("El servidor es http://localhost:3000")
});