using Dapper; using GestionIntegral.Api.Models.Suscripciones; using System.Data; using System.Text; namespace GestionIntegral.Api.Data.Repositories.Suscripciones { public class AjusteRepository : IAjusteRepository { private readonly DbConnectionFactory _connectionFactory; private readonly ILogger _logger; public AjusteRepository(DbConnectionFactory factory, ILogger logger) { _connectionFactory = factory; _logger = logger; } public async Task UpdateAsync(Ajuste ajuste, IDbTransaction transaction) { const string sql = @" UPDATE dbo.susc_Ajustes SET FechaAjuste = @FechaAjuste, TipoAjuste = @TipoAjuste, Monto = @Monto, Motivo = @Motivo WHERE IdAjuste = @IdAjuste AND Estado = 'Pendiente';"; // Solo se pueden editar los pendientes 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, ajuste, transaction); return rows == 1; } // Actualizar también el CreateAsync public async Task CreateAsync(Ajuste nuevoAjuste, IDbTransaction transaction) { const string sql = @" INSERT INTO dbo.susc_Ajustes (IdSuscriptor, FechaAjuste, TipoAjuste, Monto, Motivo, Estado, IdUsuarioAlta, FechaAlta) OUTPUT INSERTED.* VALUES (@IdSuscriptor, @FechaAjuste, @TipoAjuste, @Monto, @Motivo, 'Pendiente', @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.QuerySingleOrDefaultAsync(sql, nuevoAjuste, transaction); } public async Task> GetAjustesPorSuscriptorAsync(int idSuscriptor, DateTime? fechaDesde, DateTime? fechaHasta) { var sqlBuilder = new StringBuilder("SELECT * FROM dbo.susc_Ajustes WHERE IdSuscriptor = @IdSuscriptor"); var parameters = new DynamicParameters(); parameters.Add("IdSuscriptor", idSuscriptor); if (fechaDesde.HasValue) { sqlBuilder.Append(" AND FechaAjuste >= @FechaDesde"); parameters.Add("FechaDesde", fechaDesde.Value.Date); } if (fechaHasta.HasValue) { sqlBuilder.Append(" AND FechaAjuste <= @FechaHasta"); parameters.Add("FechaHasta", fechaHasta.Value.Date); } sqlBuilder.Append(" ORDER BY FechaAlta DESC;"); using var connection = _connectionFactory.CreateConnection(); return await connection.QueryAsync(sqlBuilder.ToString(), parameters); } public async Task> GetAjustesPendientesHastaFechaAsync(int idSuscriptor, DateTime fechaHasta, IDbTransaction transaction) { const string sql = @" SELECT * FROM dbo.susc_Ajustes WHERE IdSuscriptor = @IdSuscriptor AND Estado = 'Pendiente' AND FechaAjuste <= @FechaHasta;"; // La condición clave es que la fecha del ajuste sea HASTA la fecha límite 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 { idSuscriptor, FechaHasta = fechaHasta }, transaction); } public async Task MarcarAjustesComoAplicadosAsync(IEnumerable idsAjustes, int idFactura, IDbTransaction transaction) { if (!idsAjustes.Any()) return true; const string sql = @" UPDATE dbo.susc_Ajustes SET Estado = 'Aplicado', IdFacturaAplicado = @IdFactura WHERE IdAjuste IN @IdsAjustes;"; if (transaction?.Connection == null) { throw new ArgumentNullException(nameof(transaction.Connection), "La conexión de la transacción no puede ser nula."); } var rowsAffected = await transaction.Connection.ExecuteAsync(sql, new { IdsAjustes = idsAjustes, IdFactura = idFactura }, transaction); return rowsAffected == idsAjustes.Count(); } public async Task GetByIdAsync(int idAjuste) { const string sql = "SELECT * FROM dbo.susc_Ajustes WHERE IdAjuste = @IdAjuste;"; using var connection = _connectionFactory.CreateConnection(); return await connection.QuerySingleOrDefaultAsync(sql, new { idAjuste }); } public async Task AnularAjusteAsync(int idAjuste, int idUsuario, IDbTransaction transaction) { const string sql = @" UPDATE dbo.susc_Ajustes SET Estado = 'Anulado', IdUsuarioAnulo = @IdUsuario, FechaAnulacion = GETDATE() WHERE IdAjuste = @IdAjuste AND Estado = 'Pendiente';"; // Solo se pueden anular los pendientes 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, new { IdAjuste = idAjuste, IdUsuario = idUsuario }, transaction); return rows == 1; } public async Task> GetAjustesPorIdFacturaAsync(int idFactura) { const string sql = "SELECT * FROM dbo.susc_Ajustes WHERE IdFacturaAplicado = @IdFactura;"; using var connection = _connectionFactory.CreateConnection(); return await connection.QueryAsync(sql, new { IdFactura = idFactura }); } } }