Backend:
Diseño de un AuditoriaController con un patrón para añadir endpoints de historial para diferentes entidades. Implementación de la lógica de servicio y repositorio para obtener datos de las tablas _H para: Usuarios (gral_Usuarios_H) Pagos de Distribuidores (cue_PagosDistribuidor_H) Notas de Crédito/Débito (cue_CreditosDebitos_H) Entradas/Salidas de Distribuidores (dist_EntradasSalidas_H) Entradas/Salidas de Canillitas (dist_EntradasSalidasCanillas_H) Novedades de Canillitas (dist_dtNovedadesCanillas_H) Ajustes Manuales de Saldo (cue_SaldoAjustesHistorial) Tipos de Pago (cue_dtTipopago_H) Canillitas (Maestro) (dist_dtCanillas_H) Distribuidores (Maestro) (dist_dtDistribuidores_H) Empresas (Maestro) (dist_dtEmpresas_H) DTOs específicos para cada tipo de historial, incluyendo NombreUsuarioModifico. Frontend: Servicio auditoriaService.ts con métodos para llamar a cada endpoint de historial. Página AuditoriaGeneralPage.tsx con: Selector de "Tipo de Entidad a Auditar". Filtros comunes (Fechas, Usuario Modificador, Tipo de Modificación, ID Entidad). Un DataGrid que muestra las columnas dinámicamente según el tipo de entidad seleccionada. Lógica para cargar los datos correspondientes. DTOs de historial en TypeScript. Actualizaciones en AppRoutes.tsx y MainLayout.tsx para la nueva sección de Auditoría (restringida a SuperAdmin).
This commit is contained in:
@@ -7,7 +7,8 @@ using System.Data;
|
||||
using GestionIntegral.Api.Data;
|
||||
using GestionIntegral.Api.Models.Distribucion;
|
||||
using GestionIntegral.Api.Data.Repositories.Distribucion;
|
||||
using GestionIntegral.Api.Data.Repositories.Contables; // Para IDbTransaction, ConnectionState
|
||||
using GestionIntegral.Api.Data.Repositories.Contables;
|
||||
using GestionIntegral.Api.Dtos.Auditoria; // Para IDbTransaction, ConnectionState
|
||||
|
||||
namespace GestionIntegral.Api.Services.Distribucion
|
||||
{
|
||||
@@ -42,7 +43,7 @@ namespace GestionIntegral.Api.Services.Distribucion
|
||||
Detalle = e.Detalle
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public async Task<IEnumerable<EmpresaDropdownDto>> ObtenerParaDropdown()
|
||||
{
|
||||
// El repositorio ya devuelve solo las activas si es necesario
|
||||
@@ -131,7 +132,7 @@ namespace GestionIntegral.Api.Services.Distribucion
|
||||
{
|
||||
throw new InvalidOperationException($"Falló al crear saldo inicial para distribuidor {idDistribuidor} y nueva empresa {empresaCreada.IdEmpresa}.");
|
||||
}
|
||||
_logger.LogInformation("Saldo inicial creado para Distribuidor ID {IdDistribuidor}, Empresa ID {IdEmpresa}", idDistribuidor, empresaCreada.IdEmpresa);
|
||||
_logger.LogInformation("Saldo inicial creado para Distribuidor ID {IdDistribuidor}, Empresa ID {IdEmpresa}", idDistribuidor, empresaCreada.IdEmpresa);
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
@@ -158,41 +159,41 @@ namespace GestionIntegral.Api.Services.Distribucion
|
||||
|
||||
public async Task<(bool Exito, string? Error)> ActualizarAsync(int id, UpdateEmpresaDto updateDto, int idUsuario)
|
||||
{
|
||||
var empresaExistente = await _empresaRepository.GetByIdAsync(id);
|
||||
if (empresaExistente == null)
|
||||
{
|
||||
return (false, "Empresa no encontrada.");
|
||||
}
|
||||
var empresaExistente = await _empresaRepository.GetByIdAsync(id);
|
||||
if (empresaExistente == null)
|
||||
{
|
||||
return (false, "Empresa no encontrada.");
|
||||
}
|
||||
|
||||
if (await _empresaRepository.ExistsByNameAsync(updateDto.Nombre, id))
|
||||
{
|
||||
return (false, "El nombre de la empresa ya existe para otro registro.");
|
||||
}
|
||||
if (await _empresaRepository.ExistsByNameAsync(updateDto.Nombre, id))
|
||||
{
|
||||
return (false, "El nombre de la empresa ya existe para otro registro.");
|
||||
}
|
||||
|
||||
empresaExistente.Nombre = updateDto.Nombre;
|
||||
empresaExistente.Detalle = updateDto.Detalle;
|
||||
empresaExistente.Nombre = updateDto.Nombre;
|
||||
empresaExistente.Detalle = updateDto.Detalle;
|
||||
|
||||
// --- Transacción ---
|
||||
using (var connection = _connectionFactory.CreateConnection())
|
||||
{
|
||||
if (connection is System.Data.Common.DbConnection dbConnection) { await dbConnection.OpenAsync(); } else { connection.Open(); }
|
||||
using (var transaction = connection.BeginTransaction())
|
||||
if (connection is System.Data.Common.DbConnection dbConnection) { await dbConnection.OpenAsync(); } else { connection.Open(); }
|
||||
using (var transaction = connection.BeginTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
var actualizado = await _empresaRepository.UpdateAsync(empresaExistente, idUsuario, transaction);
|
||||
if (!actualizado)
|
||||
{
|
||||
throw new InvalidOperationException("La actualización en el repositorio de empresas devolvió false.");
|
||||
}
|
||||
transaction.Commit();
|
||||
_logger.LogInformation("Empresa ID {IdEmpresa} actualizada exitosamente por Usuario ID {IdUsuario}.", id, idUsuario);
|
||||
return (true, null); // Éxito
|
||||
var actualizado = await _empresaRepository.UpdateAsync(empresaExistente, idUsuario, transaction);
|
||||
if (!actualizado)
|
||||
{
|
||||
throw new InvalidOperationException("La actualización en el repositorio de empresas devolvió false.");
|
||||
}
|
||||
transaction.Commit();
|
||||
_logger.LogInformation("Empresa ID {IdEmpresa} actualizada exitosamente por Usuario ID {IdUsuario}.", id, idUsuario);
|
||||
return (true, null); // Éxito
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { transaction.Rollback(); } catch (Exception rbEx) { _logger.LogError(rbEx, "Error al intentar hacer rollback en ActualizarAsync Empresa."); }
|
||||
_logger.LogError(ex, "Error en transacción ActualizarAsync para Empresa ID: {Id}", id);
|
||||
_logger.LogError(ex, "Error en transacción ActualizarAsync para Empresa ID: {Id}", id);
|
||||
return (false, "Error interno al actualizar la empresa.");
|
||||
}
|
||||
}
|
||||
@@ -215,35 +216,39 @@ namespace GestionIntegral.Api.Services.Distribucion
|
||||
return (false, "No se puede eliminar. Existen publicaciones relacionadas a la empresa.");
|
||||
}
|
||||
|
||||
// --- Transacción ---
|
||||
// --- Transacción ---
|
||||
using (var connection = _connectionFactory.CreateConnection())
|
||||
{
|
||||
if (connection is System.Data.Common.DbConnection dbConnection) { await dbConnection.OpenAsync(); } else { connection.Open(); }
|
||||
using (var transaction = connection.BeginTransaction())
|
||||
if (connection is System.Data.Common.DbConnection dbConnection) { await dbConnection.OpenAsync(); } else { connection.Open(); }
|
||||
using (var transaction = connection.BeginTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
// 1. Eliminar Saldos asociados
|
||||
bool saldosEliminados = await _saldoRepository.DeleteSaldosByEmpresaAsync(id, transaction);
|
||||
// No lanzamos error si saldosEliminados es false, podría no haber tenido saldos. Loggeamos si es necesario.
|
||||
if (!saldosEliminados && await _saldoRepository.CheckIfSaldosExistForEmpresaAsync(id)) // Necesitarías este método en ISaldoRepository
|
||||
{
|
||||
_logger.LogWarning("Se intentó eliminar Empresa ID {IdEmpresa} pero falló la eliminación de saldos asociados.", id);
|
||||
// Decidir si continuar o fallar. Por ahora, continuamos pero loggeamos.
|
||||
// throw new InvalidOperationException("Error al intentar eliminar los saldos asociados a la empresa.");
|
||||
} else if (!saldosEliminados) {
|
||||
_logger.LogInformation("No se encontraron saldos para eliminar de la Empresa ID {IdEmpresa}.", id);
|
||||
} else {
|
||||
_logger.LogInformation("Saldos eliminados para Empresa ID {IdEmpresa}.", id);
|
||||
}
|
||||
if (!saldosEliminados && await _saldoRepository.CheckIfSaldosExistForEmpresaAsync(id)) // Necesitarías este método en ISaldoRepository
|
||||
{
|
||||
_logger.LogWarning("Se intentó eliminar Empresa ID {IdEmpresa} pero falló la eliminación de saldos asociados.", id);
|
||||
// Decidir si continuar o fallar. Por ahora, continuamos pero loggeamos.
|
||||
// throw new InvalidOperationException("Error al intentar eliminar los saldos asociados a la empresa.");
|
||||
}
|
||||
else if (!saldosEliminados)
|
||||
{
|
||||
_logger.LogInformation("No se encontraron saldos para eliminar de la Empresa ID {IdEmpresa}.", id);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogInformation("Saldos eliminados para Empresa ID {IdEmpresa}.", id);
|
||||
}
|
||||
|
||||
|
||||
// 2. Eliminar Empresa (Repo maneja historial)
|
||||
var eliminado = await _empresaRepository.DeleteAsync(id, idUsuario, transaction);
|
||||
if (!eliminado)
|
||||
{
|
||||
throw new InvalidOperationException("La eliminación en el repositorio de empresas devolvió false.");
|
||||
}
|
||||
var eliminado = await _empresaRepository.DeleteAsync(id, idUsuario, transaction);
|
||||
if (!eliminado)
|
||||
{
|
||||
throw new InvalidOperationException("La eliminación en el repositorio de empresas devolvió false.");
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
_logger.LogInformation("Empresa ID {IdEmpresa} eliminada exitosamente por Usuario ID {IdUsuario}.", id, idUsuario);
|
||||
@@ -252,12 +257,30 @@ namespace GestionIntegral.Api.Services.Distribucion
|
||||
catch (Exception ex)
|
||||
{
|
||||
try { transaction.Rollback(); } catch (Exception rbEx) { _logger.LogError(rbEx, "Error al intentar hacer rollback en EliminarAsync Empresa."); }
|
||||
_logger.LogError(ex, "Error en transacción EliminarAsync para Empresa ID: {Id}", id);
|
||||
_logger.LogError(ex, "Error en transacción EliminarAsync para Empresa ID: {Id}", id);
|
||||
return (false, "Error interno al eliminar la empresa.");
|
||||
}
|
||||
}
|
||||
}
|
||||
// --- Fin Transacción ---
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<EmpresaHistorialDto>> ObtenerHistorialAsync(
|
||||
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||
int? idUsuarioModifico, string? tipoModificacion,
|
||||
int? idEmpresaAfectada)
|
||||
{
|
||||
var historialData = await _empresaRepository.GetHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idEmpresaAfectada);
|
||||
|
||||
return historialData.Select(h => new EmpresaHistorialDto
|
||||
{
|
||||
Id_Empresa = h.Historial.Id_Empresa,
|
||||
Nombre = h.Historial.Nombre,
|
||||
Detalle = h.Historial.Detalle,
|
||||
Id_Usuario = h.Historial.Id_Usuario,
|
||||
NombreUsuarioModifico = h.NombreUsuarioModifico,
|
||||
FechaMod = h.Historial.FechaMod,
|
||||
TipoMod = h.Historial.TipoMod
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user