using Dapper; using GestionIntegral.Api.Models.Distribucion; using Microsoft.Extensions.Logging; // Para ILogger using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; // Para StringBuilder using System.Threading.Tasks; namespace GestionIntegral.Api.Data.Repositories.Distribucion { public class CambioParadaRepository : ICambioParadaRepository { private readonly DbConnectionFactory _cf; private readonly ILogger _logger; public CambioParadaRepository(DbConnectionFactory cf, ILogger logger) { _cf = cf; _logger = logger; } private async Task LogHistorialAsync(CambioParadaCanilla paradaOriginal, int idUsuario, string tipoMod, IDbConnection connection, IDbTransaction? transaction) { var historial = new CambioParadaCanillaHistorial { Id_Registro = paradaOriginal.IdRegistro, Id_Canilla = paradaOriginal.IdCanilla, Parada = paradaOriginal.Parada, VigenciaD = paradaOriginal.VigenciaD, VigenciaH = paradaOriginal.VigenciaH, Id_Usuario = idUsuario, FechaMod = DateTime.Now, TipoMod = tipoMod }; const string sqlHistorial = @" INSERT INTO dbo.dist_CambiosParadasCanillas_H (Id_Registro, Id_Canilla, Parada, VigenciaD, VigenciaH, Id_Usuario, FechaMod, TipoMod) VALUES (@Id_Registro, @Id_Canilla, @Parada, @VigenciaD, @VigenciaH, @Id_Usuario, @FechaMod, @TipoMod);"; await connection.ExecuteAsync(sqlHistorial, historial, transaction); } public async Task> GetByCanillaAsync(int idCanilla) { using var connection = _cf.CreateConnection(); const string sql = @" SELECT Id_Registro AS IdRegistro, Id_Canilla AS IdCanilla, Parada, VigenciaD, VigenciaH FROM dbo.dist_CambiosParadasCanillas WHERE Id_Canilla = @IdCanilla ORDER BY VigenciaD DESC, Id_Registro DESC;"; return await connection.QueryAsync(sql, new { IdCanilla = idCanilla }); } public async Task GetByIdAsync(int idRegistro) { using var connection = _cf.CreateConnection(); const string sql = @" SELECT Id_Registro AS IdRegistro, Id_Canilla AS IdCanilla, Parada, VigenciaD, VigenciaH FROM dbo.dist_CambiosParadasCanillas WHERE Id_Registro = @IdRegistro;"; return await connection.QuerySingleOrDefaultAsync(sql, new { IdRegistro = idRegistro }); } public async Task GetCurrentParadaAsync(int idCanilla, IDbTransaction? transaction = null) { const string sql = @" SELECT TOP 1 Id_Registro AS IdRegistro, Id_Canilla AS IdCanilla, Parada, VigenciaD, VigenciaH FROM dbo.dist_CambiosParadasCanillas WHERE Id_Canilla = @IdCanilla AND VigenciaH IS NULL ORDER BY VigenciaD DESC, Id_Registro DESC;"; // Por si hay un error y quedaron varias abiertas var conn = transaction?.Connection ?? _cf.CreateConnection(); bool manageConnection = transaction == null; if (manageConnection && conn.State != ConnectionState.Open) { if (conn is System.Data.Common.DbConnection dbConn) await dbConn.OpenAsync(); else conn.Open(); } try { return await conn.QuerySingleOrDefaultAsync(sql, new { IdCanilla = idCanilla }, transaction); } finally { if (manageConnection && conn.State == ConnectionState.Open) { if (conn is System.Data.Common.DbConnection dbConn) await dbConn.CloseAsync(); else conn.Close(); } } } public async Task CreateAsync(CambioParadaCanilla nuevaParada, int idUsuario, IDbTransaction transaction) { const string sqlInsert = @" INSERT INTO dbo.dist_CambiosParadasCanillas (Id_Canilla, Parada, VigenciaD, VigenciaH) OUTPUT INSERTED.Id_Registro AS IdRegistro, INSERTED.Id_Canilla AS IdCanilla, INSERTED.Parada, INSERTED.VigenciaD, INSERTED.VigenciaH VALUES (@IdCanilla, @Parada, @VigenciaD, @VigenciaH);"; // VigenciaH es null al crear una nueva parada activa var inserted = await transaction.Connection!.QuerySingleAsync(sqlInsert, new { nuevaParada.IdCanilla, nuevaParada.Parada, nuevaParada.VigenciaD, VigenciaH = (DateTime?)null }, transaction); if (inserted == null || inserted.IdRegistro == 0) throw new DataException("Error al crear cambio de parada o ID no generado."); await LogHistorialAsync(inserted, idUsuario, "Creada", transaction.Connection!, transaction); return inserted; } public async Task UpdateVigenciaHAsync(int idRegistro, DateTime vigenciaH, int idUsuario, IDbTransaction transaction) { var paradaOriginal = await GetByIdAsync(idRegistro); // Obtener para el log if (paradaOriginal == null) throw new KeyNotFoundException("Registro de parada no encontrado para actualizar VigenciaH."); // Loggear ANTES de actualizar await LogHistorialAsync(paradaOriginal, idUsuario, "Cerrada", transaction.Connection!, transaction); const string sqlUpdate = @" UPDATE dbo.dist_CambiosParadasCanillas SET VigenciaH = @VigenciaH WHERE Id_Registro = @IdRegistro;"; var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlUpdate, new { VigenciaH = vigenciaH.Date, IdRegistro = idRegistro }, transaction); return rowsAffected == 1; } public async Task DeleteAsync(int idRegistro, int idUsuario, IDbTransaction transaction) { var paradaOriginal = await GetByIdAsync(idRegistro); if (paradaOriginal == null) throw new KeyNotFoundException("Registro de parada no encontrado para eliminar."); // Loggear ANTES de eliminar await LogHistorialAsync(paradaOriginal, idUsuario, "Eliminada", transaction.Connection!, transaction); const string sqlDelete = "DELETE FROM dbo.dist_CambiosParadasCanillas WHERE Id_Registro = @IdRegistro;"; var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlDelete, new { IdRegistro = idRegistro }, transaction); return rowsAffected == 1; } } }