using Dapper; using GestionIntegral.Api.Models.Suscripciones; using System.Data; namespace GestionIntegral.Api.Data.Repositories.Suscripciones { public class SuscripcionRepository : ISuscripcionRepository { private readonly DbConnectionFactory _connectionFactory; private readonly ILogger _logger; public SuscripcionRepository(DbConnectionFactory connectionFactory, ILogger logger) { _connectionFactory = connectionFactory; _logger = logger; } public async Task GetByIdAsync(int idSuscripcion) { const string sql = "SELECT * FROM dbo.susc_Suscripciones WHERE IdSuscripcion = @IdSuscripcion;"; try { using var connection = _connectionFactory.CreateConnection(); return await connection.QuerySingleOrDefaultAsync(sql, new { IdSuscripcion = idSuscripcion }); } catch (Exception ex) { _logger.LogError(ex, "Error al obtener Suscripción por ID: {IdSuscripcion}", idSuscripcion); return null; } } public async Task> GetBySuscriptorIdAsync(int idSuscriptor) { const string sql = "SELECT * FROM dbo.susc_Suscripciones WHERE IdSuscriptor = @IdSuscriptor ORDER BY FechaInicio DESC;"; try { using var connection = _connectionFactory.CreateConnection(); return await connection.QueryAsync(sql, new { IdSuscriptor = idSuscriptor }); } catch (Exception ex) { _logger.LogError(ex, "Error al obtener suscripciones para el suscriptor ID: {IdSuscriptor}", idSuscriptor); return Enumerable.Empty(); } } public async Task> GetAllActivasParaFacturacion(string periodo, IDbTransaction transaction) { // Lógica para determinar el rango del período (ej. '2023-11') var year = int.Parse(periodo.Split('-')[0]); var month = int.Parse(periodo.Split('-')[1]); var primerDiaMes = new DateTime(year, month, 1); var ultimoDiaMes = primerDiaMes.AddMonths(1).AddDays(-1); const string sql = @" SELECT s.* FROM dbo.susc_Suscripciones s JOIN dbo.susc_Suscriptores su ON s.IdSuscriptor = su.IdSuscriptor WHERE s.Estado = 'Activa' AND su.Activo = 1 AND s.FechaInicio <= @UltimoDiaMes AND (s.FechaFin IS NULL OR s.FechaFin >= @PrimerDiaMes);"; if (transaction == null || transaction.Connection == null) { throw new ArgumentNullException(nameof(transaction), "La transacción o su conexión no pueden ser nulas."); } return await transaction.Connection.QueryAsync(sql, new { PrimerDiaMes = primerDiaMes, UltimoDiaMes = ultimoDiaMes }, transaction); } public async Task CreateAsync(Suscripcion nuevaSuscripcion, IDbTransaction transaction) { if (transaction == null || transaction.Connection == null) { throw new ArgumentNullException(nameof(transaction), "La transacción o su conexión no pueden ser nulas."); } const string sqlInsert = @" INSERT INTO dbo.susc_Suscripciones (IdSuscriptor, IdPublicacion, FechaInicio, FechaFin, Estado, DiasEntrega, Observaciones, IdUsuarioAlta, FechaAlta) OUTPUT INSERTED.* VALUES (@IdSuscriptor, @IdPublicacion, @FechaInicio, @FechaFin, @Estado, @DiasEntrega, @Observaciones, @IdUsuarioAlta, GETDATE());"; return await transaction.Connection.QuerySingleAsync(sqlInsert, nuevaSuscripcion, transaction); } public async Task UpdateAsync(Suscripcion suscripcion, IDbTransaction transaction) { if (transaction == null || transaction.Connection == null) { throw new ArgumentNullException(nameof(transaction), "La transacción o su conexión no pueden ser nulas."); } const string sqlUpdate = @" UPDATE dbo.susc_Suscripciones SET IdPublicacion = @IdPublicacion, FechaInicio = @FechaInicio, FechaFin = @FechaFin, Estado = @Estado, DiasEntrega = @DiasEntrega, Observaciones = @Observaciones, IdUsuarioMod = @IdUsuarioMod, FechaMod = @FechaMod WHERE IdSuscripcion = @IdSuscripcion;"; var rowsAffected = await transaction.Connection.ExecuteAsync(sqlUpdate, suscripcion, transaction); return rowsAffected == 1; } } }