Hora Inicio: 2 p.m
Hora Fin: 8 p.m
Horas Trabajadas: 6 horas
Modalidad: Virtual
Se realizó el SP de LogOut, el cual se encarga de insertar en la tabla Bitácora de Eventos de la Bases de Datos, este recibe el nombre del usuario que estaba loggeado así como su ip.
ALTER PROCEDURE [dbo].[LogOut]
@inUser VARCHAR(64)
, @inIP VARCHAR(64)
, @OutResulTCode INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
-- se hacen declaraciones
DECLARE @IdUser INT;
-- se hacen inicializacion
SET @OutResulTCode = 0;
SELECT
@IdUser = U.id
FROM dbo.Usuario AS U
WHERE U.Username = @inUser
INSERT INTO dbo.BitacoraEvento(
[IdTipoEvento]
, [Descripcion]
, [IdPostByUser]
, [PostInIP]
, [PostTime]
)
VALUES (
4
, ''
, @IdUser
, @inIP
, GETDATE()
);
END TRY
BEGIN CATCH
INSERT INTO dbo.DBError VALUES (
USER_NAME()
, ERROR_NUMBER()
, ERROR_STATE()
, ERROR_SEVERITY()
, ERROR_LINE()
, ERROR_PROCEDURE()
, ERROR_MESSAGE()
,GETDATE()
);
-- Retorna un mensaje de error para el usuario
SET @OutResulTCode=50008; -- Codigo de error standar del profe para informar de un error capturado en el catch
END CATCH
SET NOCOUNT OFF;
END
Por ello, se debió de modificar una vez más la ventana que lista los empleados, para que esta reciba como parámetros una nueva función desde el controlador, la cual se encarga de capturar el usuario y ejecutar por medio de una solicitud a base de datos el stored procedure correspondiente.
async function logOutStoredProcedure(usuario, ip) { //Función asincrónica para llamar a un procedimiento almacenado de inserción
try {
await sql.connect(config); //Conecta con la base de datos SQL Server
const request = new sql.Request(); //Crea una nueva solicitud SQL
request.input('inIP', sql.VarChar(64), ip);
request.input('inUser', sql.VarChar(64), usuario);
request.output('OutResulTCode', sql.Int); //Define un parámetro de salida para el código de resultado
const result = await request.execute('dbo.LogOut'); //Ejecuta el procedimiento almacenado de inserción
const outputResultCode = result.output.OutResulTCode; //Obtiene el código de resultado de la salida
if (outputResultCode === 0) { //Si el código de resultado es 0 (éxito)
return result.recordset; //Devuelve el conjunto de registros resultante
} else { //Si hay un error en la operación
console.error(`Error in operation. Result Code: ${outputResultCode}`);
throw new Error(`Error in operation. Result Code: ${outputResultCode}`);
}
} catch (error) {
console.error('Error executing stored procedure:', error.message);
throw error; //Captura y lanza cualquier error que ocurra
} finally {
await sql.close(); //Cierra la conexión a la base de datos
}
}
app.post('/api/logout', async (req, res) => {
const { usuario } = req.body;
const ip = '25.3.206.243';
try {
console.log('Received data:', req.body);
const result = await logOutStoredProcedure(usuario, ip);
res.json(result); //Devuelve los resultados como una respuesta JSON
} catch (error) {
console.error('Error calling mov insertion stored procedure:', error);
res.status(500).json({ error: 'Internal Server Error' }); //Devuelve un error 500 si hay un problema
}
});
Por otro lado, se realizo dentro del API los métodos correspondientes al control de errores, los cuales obtienen la descripción (que se indican el documento xml) correspondiente según el código de error devuelto por el SP, para esto se creó swhitch que contiene un caso según cada código de error. Dichas descripciones son enviadas para ser visualizadas por el usuario.
async function verificarUsuarioStoredProcedure(username, password, ip) {
try {
await sql.connect(config);
const request = new sql.Request();
request.input('inUserName', sql.VarChar(64), username);
request.input('inPassword', sql.VarChar(64), password);
request.input('inIP', sql.VarChar(64), ip);
request.output('OutResulTCode', sql.Int);
const result = await request.execute('dbo.VerificarUsuario');
const outputResultCode = result.output.OutResulTCode;
if (outputResultCode === 0) {
return result.recordset;
} else {
let errorMessage = ''; // Initialize an empty error message
switch (outputResultCode) {
case 50001:
errorMessage = 'Username no existe';
break;
case 50002:
errorMessage = 'Password no existe';
break;
default:
errorMessage = `Error in operation. Result Code: ${outputResultCode}`;
break;
}
throw new Error(errorMessage);
}
} catch (error) {
console.error('Error executing stored procedure:', error.message);
throw error;
} finally {
await sql.close();
}
}
Se nos presentaron múltiples errores dentro de los sp de verificarUsuario, borrar, insertar y modificar, causados por un mal manejo de la tabla de bitácora, ya que la capa lógica enviaba valores que se convertían a nulos en el transcurso API-BD, para ello se realizaron ciertas modificaciones dentro de la API para solucionarlos. Un ejemplo de estos fue
Received data: { username: 'UsuarioScripts', password: 'UsuarioScripts' }
ip ::1
Error in operation. Result Code: 50008
Error executing stored procedure: Error in operation. Result Code: 50008
Error calling user verification stored procedure: Error: Error in operation. Result Code: 50008
at verificarUsuarioStoredProcedure
Por otra parte, debido a estos errores tambien decidimos realizar cambio en los SP, a continuacion vamos a mosrtrar un ejemplo del cambio que se realizo en el SP modificar.
ALTER PROCEDURE [dbo].[EditarEmpleado]
@inEmpleado VARCHAR(64)
, @inNuevoValorDocumentoIdentidad INT
, @inNuevoNombre VARCHAR(64)
, @inNuevoPuesto VARCHAR(64)
, @inUser VARCHAR(64)
, @inIP VARCHAR(64)
, @OutResulTCode INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
-- se hacen declaraciones
DECLARE @ValorDocumentoIdentidad INT
, @IdUser INT
, @SaldoVacaciones SMALLINT
, @IdPuesto INT
, @Puesto VARCHAR(64)
, @DescripcionError VARCHAR(2000);
-- se hacen inicializacion
SET @OutResulTCode = 0;
SELECT
@IdUser = U.id
FROM dbo.Usuario AS U
WHERE U.Username = @inUser
SELECT
@ValorDocumentoIdentidad = E.ValorDocumentoIdentidad
, @Puesto = P.Nombre
, @SaldoVacaciones = E.SaldoVacaciones
FROM dbo.Empleado AS E
INNER JOIN dbo.Puesto AS P ON E.idPuesto = P.id
WHERE E.Nombre = @inEmpleado
-- se hacen validaciones
IF EXISTS (SELECT 1 FROM dbo.Empleado AS E
WHERE E.ValorDocumentoIdentidad = @inNuevoValorDocumentoIdentidad)
BEGIN
SET @OutResulTCode = 50004;
SELECT @DescripcionError = Err.Descripcion
FROM dbo.Error AS Err
WHERE Err.Codigo = @OutResulTCode;
INSERT dbo.BitacoraEvento(
[IdTipoEvento]
, [Descripcion]
, [IdPostByUser]
, [PostInIP]
, [PostTime]
)
VALUES (
7
, ' Descripcion del error: '+ @DescripcionError
+ ' Valor documento identidad antes de editarse:' + CAST(@ValorDocumentoIdentidad AS VARCHAR)
+' Nombre antes de editarse:' + @inEmpleado
+ ' Nombre del Puesto antes de editarse:'+ @Puesto
+ ' Valor documento identidad despues de editarse:' + CAST(@inNuevoValorDocumentoIdentidad AS VARCHAR)
+' Nombre despues de editarse:' + @inNuevoNombre
+ ' Nombre del Puesto despues de editarse:'+ @inNuevoPuesto
, @IdUser
, @inIP
, GETDATE()
);
END;
ELSE IF EXISTS (SELECT 1 FROM dbo.Empleado AS E
WHERE E.Nombre = @inNuevoNombre)
BEGIN
SET @OutResulTCode = 50005;
SELECT @DescripcionError = Err.Descripcion
FROM dbo.Error AS Err
WHERE Err.Codigo = @OutResulTCode;
INSERT dbo.BitacoraEvento(
[IdTipoEvento]
, [Descripcion]
, [IdPostByUser]
, [PostInIP]
, [PostTime]
)
VALUES (
7
, ' Descripcion del error:'+ @DescripcionError
+ ' Valor documento identidad antes de editarse:' + CAST(@ValorDocumentoIdentidad AS VARCHAR)
+' Nombre antes de editarse:' + @inEmpleado
+ ' Nombre del Puesto antes de editarse:'+ @Puesto
+ ' Valor documento identidad despues de editarse:' + CAST(@inNuevoValorDocumentoIdentidad AS VARCHAR)
+' Nombre despues de editarse:' + @inNuevoNombre
+ ' Nombre del Puesto despues de editarse:'+ @inNuevoPuesto
, @IdUser
, @inIP
, GETDATE()
);
END;
ELSE
BEGIN
-- Obtener el Id del puesto utilizando el nombre del puesto
SELECT @IdPuesto = P.id
FROM dbo.Puesto AS P
WHERE P.Nombre = @inNuevoPuesto;
-- Realizar la edición del empleado
UPDATE E
SET
E.ValorDocumentoIdentidad = @inNuevoValorDocumentoIdentidad
, E.Nombre = @inNuevoNombre
, E.IdPuesto = @IdPuesto
FROM dbo.Empleado AS E
WHERE e.Nombre = @inEmpleado;
INSERT dbo.BitacoraEvento(
[IdTipoEvento]
, [Descripcion]
, [IdPostByUser]
, [PostInIP]
, [PostTime]
)
VALUES (
8
, ' Valor documento identidad antes de editarse:' + CAST(@ValorDocumentoIdentidad AS VARCHAR)
+' Nombre antes de editarse:' + @inEmpleado
+ ' Nombre del Puesto antes de editarse:'+ @Puesto
+ ' Valor documento identidad despues de editarse:' + CAST(@inNuevoValorDocumentoIdentidad AS VARCHAR)
+' Nombre despues de editarse:' + @inNuevoNombre
+ ' Nombre del Puesto despues de editarse:'+ @inNuevoPuesto
+ 'Saldo Vacaciones:' + CAST(@SaldoVacaciones AS VARCHAR)
, @IdUser
, @inIP
, GETDATE()
);
END
END TRY
BEGIN CATCH
-- Registro de error en la tabla de errores
INSERT INTO dbo.DBError VALUES (
SUSER_SNAME(),
ERROR_NUMBER(),
ERROR_STATE(),
ERROR_SEVERITY(),
ERROR_LINE(),
ERROR_PROCEDURE(),
ERROR_MESSAGE(),
GETDATE()
);
SET @OutResulTCode = 50008; -- Código de error para error capturado en el bloque TRY-CATCH
END CATCH;
SET NOCOUNT OFF;
END;