Files
GestionIntegralWeb/Backend/GestionIntegral.Api/Data/Repositories/Distribucion/NovedadCanillaRepository.cs

278 lines
13 KiB
C#
Raw Normal View History

using Dapper;
using GestionIntegral.Api.Models.Distribucion;
using Microsoft.Extensions.Configuration; // Para IConfiguration
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Data;
using Microsoft.Data.SqlClient; // O el proveedor de tu BD
using System.Linq;
using System.Threading.Tasks;
using GestionIntegral.Api.Dtos.Reportes;
using System.Text;
namespace GestionIntegral.Api.Data.Repositories.Distribucion
{
public class NovedadCanillaRepository : INovedadCanillaRepository
{
private readonly DbConnectionFactory _connectionFactory; // Inyecta tu DbConnectionFactory
private readonly ILogger<NovedadCanillaRepository> _logger;
public NovedadCanillaRepository(DbConnectionFactory connectionFactory, ILogger<NovedadCanillaRepository> logger)
{
_connectionFactory = connectionFactory;
_logger = logger;
}
private async Task LogHistorialAsync(NovedadCanilla novedadOriginal, int idUsuario, string tipoMod, IDbConnection connection, IDbTransaction? transaction)
{
var historial = new NovedadCanillaHistorial
{
IdNovedad = novedadOriginal.IdNovedad,
IdCanilla = novedadOriginal.IdCanilla,
Fecha = novedadOriginal.Fecha,
Detalle = novedadOriginal.Detalle,
IdUsuario = idUsuario,
FechaMod = DateTime.Now,
TipoMod = tipoMod
};
var sqlHistorial = @"
INSERT INTO dbo.dist_dtNovedadesCanillas_H
(Id_Novedad, Id_Canilla, Fecha, Detalle, Id_Usuario, FechaMod, TipoMod)
VALUES
(@IdNovedad, @IdCanilla, @Fecha, @Detalle, @IdUsuario, @FechaMod, @TipoMod);";
await connection.ExecuteAsync(sqlHistorial, historial, transaction);
}
public async Task<IEnumerable<(NovedadCanilla Novedad, string NombreCanilla)>> GetByCanillaAsync(int idCanilla, DateTime? fechaDesde, DateTime? fechaHasta)
{
using var connection = _connectionFactory.CreateConnection();
var sqlBuilder = new System.Text.StringBuilder(@"
SELECT
n.Id_Novedad AS IdNovedad,
n.Id_Canilla AS IdCanilla,
n.Fecha,
n.Detalle,
c.NomApe AS NombreCanilla
FROM dbo.dist_dtNovedadesCanillas n
JOIN dbo.dist_dtCanillas c ON n.Id_Canilla = c.Id_Canilla
WHERE n.Id_Canilla = @IdCanilla");
var parameters = new DynamicParameters();
parameters.Add("IdCanilla", idCanilla);
if (fechaDesde.HasValue)
{
sqlBuilder.Append(" AND n.Fecha >= @FechaDesde");
parameters.Add("FechaDesde", fechaDesde.Value.Date); // Solo fecha, sin hora
}
if (fechaHasta.HasValue)
{
sqlBuilder.Append(" AND n.Fecha <= @FechaHasta");
// Para incluir todo el día de fechaHasta
parameters.Add("FechaHasta", fechaHasta.Value.Date.AddDays(1).AddTicks(-1));
}
sqlBuilder.Append(" ORDER BY n.Fecha DESC, n.Id_Novedad DESC;");
var result = await connection.QueryAsync<NovedadCanilla, string, (NovedadCanilla, string)>(
sqlBuilder.ToString(),
(novedad, nombreCanilla) => (novedad, nombreCanilla),
parameters,
splitOn: "NombreCanilla"
);
return result;
}
public async Task<NovedadCanilla?> GetByIdAsync(int idNovedad)
{
using var connection = _connectionFactory.CreateConnection();
var sql = "SELECT Id_Novedad AS IdNovedad, Id_Canilla AS IdCanilla, Fecha, Detalle FROM dbo.dist_dtNovedadesCanillas WHERE Id_Novedad = @IdNovedad;";
return await connection.QuerySingleOrDefaultAsync<NovedadCanilla>(sql, new { IdNovedad = idNovedad });
}
public async Task<bool> ExistsByCanillaAndFechaAsync(int idCanilla, DateTime fecha, int? excludeIdNovedad = null)
{
using var connection = _connectionFactory.CreateConnection();
var sqlBuilder = new System.Text.StringBuilder("SELECT COUNT(1) FROM dbo.dist_dtNovedadesCanillas WHERE Id_Canilla = @IdCanilla AND Fecha = @Fecha");
var parameters = new DynamicParameters();
parameters.Add("IdCanilla", idCanilla);
parameters.Add("Fecha", fecha.Date); // Comparar solo la fecha
if (excludeIdNovedad.HasValue)
{
sqlBuilder.Append(" AND Id_Novedad != @ExcludeIdNovedad");
parameters.Add("ExcludeIdNovedad", excludeIdNovedad.Value);
}
var count = await connection.ExecuteScalarAsync<int>(sqlBuilder.ToString(), parameters);
return count > 0;
}
public async Task<NovedadCanilla?> CreateAsync(NovedadCanilla novedad, int idUsuario, IDbTransaction? transaction = null)
{
var sql = @"
INSERT INTO dbo.dist_dtNovedadesCanillas (Id_Canilla, Fecha, Detalle)
VALUES (@IdCanilla, @Fecha, @Detalle);
SELECT CAST(SCOPE_IDENTITY() as int);";
IDbConnection conn = transaction?.Connection ?? _connectionFactory.CreateConnection();
bool manageConnection = transaction == null; // Solo gestionar si no hay transacción externa
try
{
if (manageConnection && conn.State != ConnectionState.Open) await (conn as SqlConnection)!.OpenAsync();
var newId = await conn.QuerySingleAsync<int>(sql, novedad, transaction);
novedad.IdNovedad = newId;
await LogHistorialAsync(novedad, idUsuario, "Insertada", conn, transaction);
return novedad;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al crear NovedadCanilla para Canilla ID: {IdCanilla}", novedad.IdCanilla);
return null;
}
finally
{
if (manageConnection && conn.State == ConnectionState.Open) conn.Close();
}
}
public async Task<bool> UpdateAsync(NovedadCanilla novedad, int idUsuario, IDbTransaction? transaction = null)
{
var novedadOriginal = await GetByIdAsync(novedad.IdNovedad); // Necesitamos el estado original para el log
if (novedadOriginal == null) return false; // No se encontró
var sql = @"
UPDATE dbo.dist_dtNovedadesCanillas SET
Detalle = @Detalle
-- No se permite cambiar IdCanilla ni Fecha de una novedad existente
WHERE Id_Novedad = @IdNovedad;";
IDbConnection conn = transaction?.Connection ?? _connectionFactory.CreateConnection();
bool manageConnection = transaction == null;
try
{
if (manageConnection && conn.State != ConnectionState.Open) await (conn as SqlConnection)!.OpenAsync();
await LogHistorialAsync(novedadOriginal, idUsuario, "Modificada", conn, transaction); // Log con datos ANTES de actualizar
var affectedRows = await conn.ExecuteAsync(sql, novedad, transaction);
return affectedRows > 0;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al actualizar NovedadCanilla ID: {IdNovedad}", novedad.IdNovedad);
return false;
}
finally
{
if (manageConnection && conn.State == ConnectionState.Open) conn.Close();
}
}
public async Task<bool> DeleteAsync(int idNovedad, int idUsuario, IDbTransaction? transaction = null)
{
var novedadOriginal = await GetByIdAsync(idNovedad);
if (novedadOriginal == null) return false;
var sql = "DELETE FROM dbo.dist_dtNovedadesCanillas WHERE Id_Novedad = @IdNovedad;";
IDbConnection conn = transaction?.Connection ?? _connectionFactory.CreateConnection();
bool manageConnection = transaction == null;
try
{
if (manageConnection && conn.State != ConnectionState.Open) await (conn as SqlConnection)!.OpenAsync();
await LogHistorialAsync(novedadOriginal, idUsuario, "Eliminada", conn, transaction);
var affectedRows = await conn.ExecuteAsync(sql, new { IdNovedad = idNovedad }, transaction);
return affectedRows > 0;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al eliminar NovedadCanilla ID: {IdNovedad}", idNovedad);
return false;
}
finally
{
if (manageConnection && conn.State == ConnectionState.Open) conn.Close();
}
}
public async Task<IEnumerable<NovedadesCanillasReporteDto>> GetReporteNovedadesAsync(int idEmpresa, DateTime fechaDesde, DateTime fechaHasta)
{
using var connection = _connectionFactory.CreateConnection();
var parameters = new
{
idEmpresa,
fechaDesde = fechaDesde.Date, // Enviar solo la fecha
fechaHasta = fechaHasta.Date.AddDays(1).AddTicks(-1) // Para incluir todo el día hasta las 23:59:59.999...
};
// El nombre del SP en el archivo es SP_DistCanillasNovedades
return await connection.QueryAsync<NovedadesCanillasReporteDto>(
"dbo.SP_DistCanillasNovedades", // Asegúrate que el nombre del SP sea exacto
parameters,
commandType: CommandType.StoredProcedure
);
}
public async Task<IEnumerable<CanillaGananciaReporteDto>> GetReporteGananciasAsync(int idEmpresa, DateTime fechaDesde, DateTime fechaHasta)
{
using var connection = _connectionFactory.CreateConnection();
var parameters = new
{
idEmpresa,
fechaDesde = fechaDesde.Date,
fechaHasta = fechaHasta.Date // El SP SP_DistCanillasGanancias maneja el rango inclusivo directamente
};
return await connection.QueryAsync<CanillaGananciaReporteDto>(
"dbo.SP_DistCanillasGanancias", // Nombre del SP
parameters,
commandType: CommandType.StoredProcedure
);
}
public async Task<IEnumerable<(NovedadCanillaHistorico Historial, string NombreUsuarioModifico)>> GetHistorialAsync(
DateTime? fechaDesde, DateTime? fechaHasta,
int? idUsuarioModifico, string? tipoModificacion,
int? idNovedadOriginal)
{
using var connection = _connectionFactory.CreateConnection();
var sqlBuilder = new StringBuilder(@"
SELECT
h.Id_Novedad, h.Id_Canilla, h.Fecha, h.Detalle,
h.Id_Usuario, h.FechaMod, h.TipoMod,
u.Nombre + ' ' + u.Apellido AS NombreUsuarioModifico
FROM dbo.dist_dtNovedadesCanillas_H h
JOIN dbo.gral_Usuarios u ON h.Id_Usuario = u.Id
WHERE 1=1");
var parameters = new DynamicParameters();
if (fechaDesde.HasValue) { sqlBuilder.Append(" AND h.FechaMod >= @FechaDesdeParam"); parameters.Add("FechaDesdeParam", fechaDesde.Value.Date); }
if (fechaHasta.HasValue) { sqlBuilder.Append(" AND h.FechaMod <= @FechaHastaParam"); parameters.Add("FechaHastaParam", fechaHasta.Value.Date.AddDays(1).AddTicks(-1)); }
if (idUsuarioModifico.HasValue) { sqlBuilder.Append(" AND h.Id_Usuario = @IdUsuarioModificoParam"); parameters.Add("IdUsuarioModificoParam", idUsuarioModifico.Value); }
if (!string.IsNullOrWhiteSpace(tipoModificacion)) { sqlBuilder.Append(" AND h.TipoMod = @TipoModParam"); parameters.Add("TipoModParam", tipoModificacion); }
if (idNovedadOriginal.HasValue) { sqlBuilder.Append(" AND h.Id_Novedad = @IdNovedadOriginalParam"); parameters.Add("IdNovedadOriginalParam", idNovedadOriginal.Value); }
sqlBuilder.Append(" ORDER BY h.FechaMod DESC;");
try
{
var result = await connection.QueryAsync<NovedadCanillaHistorico, string, (NovedadCanillaHistorico, string)>(
sqlBuilder.ToString(),
(hist, userName) => (hist, userName),
parameters,
splitOn: "NombreUsuarioModifico"
);
return result;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al obtener historial de Novedades de Canillitas.");
return Enumerable.Empty<(NovedadCanillaHistorico, string)>();
}
}
}
}