using Dapper; using GestionIntegral.Api.Models.Suscripciones; using System.Data; using System.Text; namespace GestionIntegral.Api.Data.Repositories.Suscripciones { public class PromocionRepository : IPromocionRepository { private readonly DbConnectionFactory _connectionFactory; private readonly ILogger _logger; public PromocionRepository(DbConnectionFactory factory, ILogger logger) { _connectionFactory = factory; _logger = logger; } public async Task> GetAllAsync(bool soloActivas) { var sql = new StringBuilder("SELECT * FROM dbo.susc_Promociones"); if (soloActivas) { sql.Append(" WHERE Activa = 1"); } sql.Append(" ORDER BY FechaInicio DESC;"); using var connection = _connectionFactory.CreateConnection(); return await connection.QueryAsync(sql.ToString()); } public async Task GetByIdAsync(int id) { const string sql = "SELECT * FROM dbo.susc_Promociones WHERE IdPromocion = @Id;"; using var connection = _connectionFactory.CreateConnection(); return await connection.QuerySingleOrDefaultAsync(sql, new { Id = id }); } public async Task CreateAsync(Promocion nuevaPromocion, IDbTransaction transaction) { const string sql = @" INSERT INTO dbo.susc_Promociones (Descripcion, TipoEfecto, ValorEfecto, TipoCondicion, ValorCondicion, FechaInicio, FechaFin, Activa, IdUsuarioAlta, FechaAlta) OUTPUT INSERTED.* VALUES (@Descripcion, @TipoEfecto, @ValorEfecto, @TipoCondicion, @ValorCondicion, @FechaInicio, @FechaFin, @Activa, @IdUsuarioAlta, GETDATE());"; if (transaction?.Connection == null) { throw new ArgumentNullException(nameof(transaction.Connection), "La conexión de la transacción no puede ser nula."); } return await transaction.Connection.QuerySingleAsync(sql, nuevaPromocion, transaction); } public async Task UpdateAsync(Promocion promocion, IDbTransaction transaction) { const string sql = @" UPDATE dbo.susc_Promociones SET Descripcion = @Descripcion, TipoPromocion = @TipoPromocion, Valor = @Valor, FechaInicio = @FechaInicio, FechaFin = @FechaFin, Activa = @Activa WHERE IdPromocion = @IdPromocion;"; if (transaction?.Connection == null) { throw new ArgumentNullException(nameof(transaction.Connection), "La conexión de la transacción no puede ser nula."); } var rows = await transaction.Connection.ExecuteAsync(sql, promocion, transaction); return rows == 1; } public async Task> GetPromocionesActivasParaSuscripcion(int idSuscripcion, DateTime fechaPeriodo, IDbTransaction transaction) { // Esta consulta ahora es más compleja para respetar ambas vigencias. const string sql = @" SELECT p.* FROM dbo.susc_Promociones p JOIN dbo.susc_SuscripcionPromociones sp ON p.IdPromocion = sp.IdPromocion WHERE sp.IdSuscripcion = @IdSuscripcion AND p.Activa = 1 -- 1. La promoción general debe estar activa en el período AND p.FechaInicio <= @FechaPeriodo AND (p.FechaFin IS NULL OR p.FechaFin >= @FechaPeriodo) -- 2. La asignación específica al cliente debe estar activa en el período AND sp.VigenciaDesde <= @FechaPeriodo AND (sp.VigenciaHasta IS NULL OR sp.VigenciaHasta >= @FechaPeriodo);"; if (transaction?.Connection == null) { throw new ArgumentNullException(nameof(transaction.Connection), "La conexión de la transacción no puede ser nula."); } return await transaction.Connection.QueryAsync(sql, new { IdSuscripcion = idSuscripcion, FechaPeriodo = fechaPeriodo }, transaction); } // Versión SIN transacción, para solo lectura public async Task> GetPromocionesActivasParaSuscripcion(int idSuscripcion, DateTime fechaPeriodo) { const string sql = @" SELECT p.* FROM dbo.susc_Promociones p JOIN dbo.susc_SuscripcionPromociones sp ON p.IdPromocion = sp.IdPromocion WHERE sp.IdSuscripcion = @IdSuscripcion AND p.Activa = 1 -- 1. La promoción general debe estar activa en el período AND p.FechaInicio <= @FechaPeriodo AND (p.FechaFin IS NULL OR p.FechaFin >= @FechaPeriodo) -- 2. La asignación específica al cliente debe estar activa en el período AND sp.VigenciaDesde <= @FechaPeriodo AND (sp.VigenciaHasta IS NULL OR sp.VigenciaHasta >= @FechaPeriodo);"; using var connection = _connectionFactory.CreateConnection(); return await connection.QueryAsync(sql, new { idSuscripcion, FechaPeriodo = fechaPeriodo }); } } }