Feat: Se añaden las capas de modelos y respositorios para el modulo de Suscripciones
This commit is contained in:
		| @@ -0,0 +1,95 @@ | ||||
| // Archivo: GestionIntegral.Api/Data/Repositories/Suscripciones/FacturaRepository.cs | ||||
|  | ||||
| using Dapper; | ||||
| using GestionIntegral.Api.Models.Suscripciones; | ||||
| using System.Data; | ||||
|  | ||||
| namespace GestionIntegral.Api.Data.Repositories.Suscripciones | ||||
| { | ||||
|     public class FacturaRepository : IFacturaRepository | ||||
|     { | ||||
|         private readonly DbConnectionFactory _connectionFactory; | ||||
|         private readonly ILogger<FacturaRepository> _logger; | ||||
|  | ||||
|         public FacturaRepository(DbConnectionFactory connectionFactory, ILogger<FacturaRepository> logger) | ||||
|         { | ||||
|             _connectionFactory = connectionFactory; | ||||
|             _logger = logger; | ||||
|         } | ||||
|  | ||||
|         public async Task<Factura?> GetByIdAsync(int idFactura) | ||||
|         { | ||||
|             const string sql = "SELECT * FROM dbo.susc_Facturas WHERE IdFactura = @IdFactura;"; | ||||
|             using var connection = _connectionFactory.CreateConnection(); | ||||
|             return await connection.QuerySingleOrDefaultAsync<Factura>(sql, new { idFactura }); | ||||
|         } | ||||
|  | ||||
|         public async Task<IEnumerable<Factura>> GetByPeriodoAsync(string periodo) | ||||
|         { | ||||
|             const string sql = "SELECT * FROM dbo.susc_Facturas WHERE Periodo = @Periodo ORDER BY IdFactura;"; | ||||
|             using var connection = _connectionFactory.CreateConnection(); | ||||
|             return await connection.QueryAsync<Factura>(sql, new { Periodo = periodo }); | ||||
|         } | ||||
|  | ||||
|         public async Task<Factura?> GetBySuscripcionYPeriodoAsync(int idSuscripcion, string periodo, IDbTransaction transaction) | ||||
|         { | ||||
|             const string sql = "SELECT TOP 1 * FROM dbo.susc_Facturas WHERE IdSuscripcion = @IdSuscripcion AND Periodo = @Periodo;"; | ||||
|              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.QuerySingleOrDefaultAsync<Factura>(sql, new { IdSuscripcion = idSuscripcion, Periodo = periodo }, transaction); | ||||
|         } | ||||
|  | ||||
|         public async Task<Factura?> CreateAsync(Factura nuevaFactura, 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_Facturas | ||||
|                     (IdSuscripcion, Periodo, FechaEmision, FechaVencimiento, ImporteBruto,  | ||||
|                      DescuentoAplicado, ImporteFinal, Estado) | ||||
|                 OUTPUT INSERTED.* | ||||
|                 VALUES | ||||
|                     (@IdSuscripcion, @Periodo, @FechaEmision, @FechaVencimiento, @ImporteBruto,  | ||||
|                      @DescuentoAplicado, @ImporteFinal, @Estado);"; | ||||
|              | ||||
|             return await transaction.Connection.QuerySingleAsync<Factura>(sqlInsert, nuevaFactura, transaction); | ||||
|         } | ||||
|  | ||||
|         public async Task<bool> UpdateEstadoAsync(int idFactura, string nuevoEstado, 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 sql = "UPDATE dbo.susc_Facturas SET Estado = @NuevoEstado WHERE IdFactura = @IdFactura;"; | ||||
|             var rowsAffected = await transaction.Connection.ExecuteAsync(sql, new { NuevoEstado = nuevoEstado, IdFactura = idFactura }, transaction); | ||||
|             return rowsAffected == 1; | ||||
|         } | ||||
|  | ||||
|         public async Task<bool> UpdateNumeroFacturaAsync(int idFactura, string numeroFactura, 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 sql = "UPDATE dbo.susc_Facturas SET NumeroFactura = @NumeroFactura, Estado = 'Pendiente de Cobro' WHERE IdFactura = @IdFactura;"; | ||||
|             var rowsAffected = await transaction.Connection.ExecuteAsync(sql, new { NumeroFactura = numeroFactura, IdFactura = idFactura }, transaction); | ||||
|             return rowsAffected == 1; | ||||
|         } | ||||
|          | ||||
|         public async Task<bool> UpdateLoteDebitoAsync(IEnumerable<int> idsFacturas, int idLoteDebito, 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 sql = "UPDATE dbo.susc_Facturas SET IdLoteDebito = @IdLoteDebito, Estado = 'Enviada a Débito' WHERE IdFactura IN @IdsFacturas;"; | ||||
|             var rowsAffected = await transaction.Connection.ExecuteAsync(sql, new { IdLoteDebito = idLoteDebito, IdsFacturas = idsFacturas }, transaction); | ||||
|             return rowsAffected == idsFacturas.Count(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,54 @@ | ||||
| using Dapper; | ||||
| using GestionIntegral.Api.Models.Suscripciones; | ||||
|  | ||||
| namespace GestionIntegral.Api.Data.Repositories.Suscripciones | ||||
| { | ||||
|     public class FormaPagoRepository : IFormaPagoRepository | ||||
|     { | ||||
|         private readonly DbConnectionFactory _connectionFactory; | ||||
|         private readonly ILogger<FormaPagoRepository> _logger; | ||||
|  | ||||
|         public FormaPagoRepository(DbConnectionFactory connectionFactory, ILogger<FormaPagoRepository> logger) | ||||
|         { | ||||
|             _connectionFactory = connectionFactory; | ||||
|             _logger = logger; | ||||
|         } | ||||
|  | ||||
|         public async Task<IEnumerable<FormaPago>> GetAllAsync() | ||||
|         { | ||||
|             const string sql = @" | ||||
|                 SELECT IdFormaPago, Nombre, RequiereCBU, Activo  | ||||
|                 FROM dbo.susc_FormasDePago  | ||||
|                 WHERE Activo = 1  | ||||
|                 ORDER BY Nombre;"; | ||||
|             try | ||||
|             { | ||||
|                 using var connection = _connectionFactory.CreateConnection(); | ||||
|                 return await connection.QueryAsync<FormaPago>(sql); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _logger.LogError(ex, "Error al obtener todas las Formas de Pago activas."); | ||||
|                 return Enumerable.Empty<FormaPago>(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async Task<FormaPago?> GetByIdAsync(int id) | ||||
|         { | ||||
|             const string sql = @" | ||||
|                 SELECT IdFormaPago, Nombre, RequiereCBU, Activo  | ||||
|                 FROM dbo.susc_FormasDePago  | ||||
|                 WHERE IdFormaPago = @Id;"; | ||||
|             try | ||||
|             { | ||||
|                 using var connection = _connectionFactory.CreateConnection(); | ||||
|                 return await connection.QuerySingleOrDefaultAsync<FormaPago>(sql, new { Id = id }); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _logger.LogError(ex, "Error al obtener Forma de Pago por ID: {IdFormaPago}", id); | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,16 @@ | ||||
| using GestionIntegral.Api.Models.Suscripciones; | ||||
| using System.Data; | ||||
|  | ||||
| namespace GestionIntegral.Api.Data.Repositories.Suscripciones | ||||
| { | ||||
|     public interface IFacturaRepository | ||||
|     { | ||||
|         Task<Factura?> GetByIdAsync(int idFactura); | ||||
|         Task<IEnumerable<Factura>> GetByPeriodoAsync(string periodo); | ||||
|         Task<Factura?> GetBySuscripcionYPeriodoAsync(int idSuscripcion, string periodo, IDbTransaction transaction); | ||||
|         Task<Factura?> CreateAsync(Factura nuevaFactura, IDbTransaction transaction); | ||||
|         Task<bool> UpdateEstadoAsync(int idFactura, string nuevoEstado, IDbTransaction transaction); | ||||
|         Task<bool> UpdateNumeroFacturaAsync(int idFactura, string numeroFactura, IDbTransaction transaction); | ||||
|         Task<bool> UpdateLoteDebitoAsync(IEnumerable<int> idsFacturas, int idLoteDebito, IDbTransaction transaction); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,10 @@ | ||||
| using GestionIntegral.Api.Models.Suscripciones; | ||||
|  | ||||
| namespace GestionIntegral.Api.Data.Repositories.Suscripciones | ||||
| { | ||||
|     public interface IFormaPagoRepository | ||||
|     { | ||||
|         Task<IEnumerable<FormaPago>> GetAllAsync(); | ||||
|         Task<FormaPago?> GetByIdAsync(int id); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,10 @@ | ||||
| using GestionIntegral.Api.Models.Suscripciones; | ||||
| using System.Data; | ||||
|  | ||||
| namespace GestionIntegral.Api.Data.Repositories.Suscripciones | ||||
| { | ||||
|   public interface ILoteDebitoRepository | ||||
|   { | ||||
|     Task<LoteDebito?> CreateAsync(LoteDebito nuevoLote, IDbTransaction transaction); | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| using GestionIntegral.Api.Models.Suscripciones; | ||||
| using System.Data; | ||||
|  | ||||
| namespace GestionIntegral.Api.Data.Repositories.Suscripciones | ||||
| { | ||||
|     public interface IPagoRepository | ||||
|     { | ||||
|         Task<IEnumerable<Pago>> GetByFacturaIdAsync(int idFactura); | ||||
|         Task<Pago?> CreateAsync(Pago nuevoPago, IDbTransaction transaction); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,14 @@ | ||||
| using GestionIntegral.Api.Models.Suscripciones; | ||||
| using System.Data; | ||||
|  | ||||
| namespace GestionIntegral.Api.Data.Repositories.Suscripciones | ||||
| { | ||||
|     public interface ISuscripcionRepository | ||||
|     { | ||||
|         Task<IEnumerable<Suscripcion>> GetBySuscriptorIdAsync(int idSuscriptor); | ||||
|         Task<Suscripcion?> GetByIdAsync(int idSuscripcion); | ||||
|         Task<Suscripcion?> CreateAsync(Suscripcion nuevaSuscripcion, IDbTransaction transaction); | ||||
|         Task<bool> UpdateAsync(Suscripcion suscripcionAActualizar, IDbTransaction transaction); | ||||
|         Task<IEnumerable<Suscripcion>> GetAllActivasParaFacturacion(string periodo, IDbTransaction transaction); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,16 @@ | ||||
| using GestionIntegral.Api.Models.Suscripciones; | ||||
| using System.Data; | ||||
|  | ||||
| namespace GestionIntegral.Api.Data.Repositories.Suscripciones | ||||
| { | ||||
|     public interface ISuscriptorRepository | ||||
|     { | ||||
|         Task<IEnumerable<Suscriptor>> GetAllAsync(string? nombreFilter, string? nroDocFilter, bool soloActivos); | ||||
|         Task<Suscriptor?> GetByIdAsync(int id); | ||||
|         Task<Suscriptor?> CreateAsync(Suscriptor nuevoSuscriptor, IDbTransaction transaction); | ||||
|         Task<bool> UpdateAsync(Suscriptor suscriptorAActualizar, IDbTransaction transaction); | ||||
|         Task<bool> ToggleActivoAsync(int id, bool activar, int idUsuario, IDbTransaction transaction); | ||||
|         Task<bool> ExistsByDocumentoAsync(string tipoDocumento, string nroDocumento, int? excludeId = null); | ||||
|         Task<bool> IsInUseAsync(int id); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,43 @@ | ||||
| using Dapper; | ||||
| using GestionIntegral.Api.Models.Suscripciones; | ||||
| using System.Data; | ||||
|  | ||||
| namespace GestionIntegral.Api.Data.Repositories.Suscripciones | ||||
| { | ||||
|     public class LoteDebitoRepository : ILoteDebitoRepository | ||||
|     { | ||||
|         private readonly DbConnectionFactory _connectionFactory; | ||||
|         private readonly ILogger<LoteDebitoRepository> _logger; | ||||
|  | ||||
|         public LoteDebitoRepository(DbConnectionFactory connectionFactory, ILogger<LoteDebitoRepository> logger) | ||||
|         { | ||||
|             _connectionFactory = connectionFactory; | ||||
|             _logger = logger; | ||||
|         } | ||||
|  | ||||
|         public async Task<LoteDebito?> CreateAsync(LoteDebito nuevoLote, 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_LotesDebito | ||||
|                     (FechaGeneracion, Periodo, NombreArchivo, ImporteTotal, CantidadRegistros, IdUsuarioGeneracion) | ||||
|                 OUTPUT INSERTED.* | ||||
|                 VALUES | ||||
|                     (GETDATE(), @Periodo, @NombreArchivo, @ImporteTotal, @CantidadRegistros, @IdUsuarioGeneracion);"; | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 return await transaction.Connection.QuerySingleAsync<LoteDebito>(sqlInsert, nuevoLote, transaction); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _logger.LogError(ex, "Error al crear el registro de LoteDebito para el período {Periodo}", nuevoLote.Periodo); | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,58 @@ | ||||
| using Dapper; | ||||
| using GestionIntegral.Api.Models.Suscripciones; | ||||
| using System.Data; | ||||
|  | ||||
| namespace GestionIntegral.Api.Data.Repositories.Suscripciones | ||||
| { | ||||
|     public class PagoRepository : IPagoRepository | ||||
|     { | ||||
|         private readonly DbConnectionFactory _connectionFactory; | ||||
|         private readonly ILogger<PagoRepository> _logger; | ||||
|  | ||||
|         public PagoRepository(DbConnectionFactory connectionFactory, ILogger<PagoRepository> logger) | ||||
|         { | ||||
|             _connectionFactory = connectionFactory; | ||||
|             _logger = logger; | ||||
|         } | ||||
|  | ||||
|         public async Task<IEnumerable<Pago>> GetByFacturaIdAsync(int idFactura) | ||||
|         { | ||||
|             const string sql = "SELECT * FROM dbo.susc_Pagos WHERE IdFactura = @IdFactura ORDER BY FechaPago DESC;"; | ||||
|             try | ||||
|             { | ||||
|                 using var connection = _connectionFactory.CreateConnection(); | ||||
|                 return await connection.QueryAsync<Pago>(sql, new { idFactura }); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _logger.LogError(ex, "Error al obtener pagos para la factura ID: {IdFactura}", idFactura); | ||||
|                 return Enumerable.Empty<Pago>(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async Task<Pago?> CreateAsync(Pago nuevoPago, 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_Pagos | ||||
|                     (IdFactura, FechaPago, IdFormaPago, Monto, Estado, Referencia, Observaciones, IdUsuarioRegistro) | ||||
|                 OUTPUT INSERTED.* | ||||
|                 VALUES | ||||
|                     (@IdFactura, @FechaPago, @IdFormaPago, @Monto, @Estado, @Referencia, @Observaciones, @IdUsuarioRegistro);"; | ||||
|              | ||||
|             try | ||||
|             { | ||||
|                 return await transaction.Connection.QuerySingleAsync<Pago>(sqlInsert, nuevoPago, transaction); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _logger.LogError(ex, "Error al registrar un nuevo Pago para la Factura ID: {IdFactura}", nuevoPago.IdFactura); | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,115 @@ | ||||
| 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<SuscripcionRepository> _logger; | ||||
|  | ||||
|         public SuscripcionRepository(DbConnectionFactory connectionFactory, ILogger<SuscripcionRepository> logger) | ||||
|         { | ||||
|             _connectionFactory = connectionFactory; | ||||
|             _logger = logger; | ||||
|         } | ||||
|  | ||||
|         public async Task<Suscripcion?> GetByIdAsync(int idSuscripcion) | ||||
|         { | ||||
|             const string sql = "SELECT * FROM dbo.susc_Suscripciones WHERE IdSuscripcion = @IdSuscripcion;"; | ||||
|             try | ||||
|             { | ||||
|                 using var connection = _connectionFactory.CreateConnection(); | ||||
|                 return await connection.QuerySingleOrDefaultAsync<Suscripcion>(sql, new { IdSuscripcion = idSuscripcion }); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _logger.LogError(ex, "Error al obtener Suscripción por ID: {IdSuscripcion}", idSuscripcion); | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async Task<IEnumerable<Suscripcion>> 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<Suscripcion>(sql, new { IdSuscriptor = idSuscriptor }); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _logger.LogError(ex, "Error al obtener suscripciones para el suscriptor ID: {IdSuscriptor}", idSuscriptor); | ||||
|                 return Enumerable.Empty<Suscripcion>(); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         public async Task<IEnumerable<Suscripcion>> 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<Suscripcion>(sql, new { PrimerDiaMes = primerDiaMes, UltimoDiaMes = ultimoDiaMes }, transaction); | ||||
|         } | ||||
|  | ||||
|         public async Task<Suscripcion?> 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<Suscripcion>(sqlInsert, nuevaSuscripcion, transaction); | ||||
|         } | ||||
|  | ||||
|         public async Task<bool> 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; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,195 @@ | ||||
| using Dapper; | ||||
| using GestionIntegral.Api.Models.Suscripciones; | ||||
| using System.Data; | ||||
| using System.Text; | ||||
|  | ||||
| namespace GestionIntegral.Api.Data.Repositories.Suscripciones | ||||
| { | ||||
|     public class SuscriptorRepository : ISuscriptorRepository | ||||
|     { | ||||
|         private readonly DbConnectionFactory _connectionFactory; | ||||
|         private readonly ILogger<SuscriptorRepository> _logger; | ||||
|  | ||||
|         public SuscriptorRepository(DbConnectionFactory connectionFactory, ILogger<SuscriptorRepository> logger) | ||||
|         { | ||||
|             _connectionFactory = connectionFactory; | ||||
|             _logger = logger; | ||||
|         } | ||||
|  | ||||
|         public async Task<IEnumerable<Suscriptor>> GetAllAsync(string? nombreFilter, string? nroDocFilter, bool soloActivos) | ||||
|         { | ||||
|             var sqlBuilder = new StringBuilder(@" | ||||
|                 SELECT IdSuscriptor, NombreCompleto, Email, Telefono, Direccion, TipoDocumento,  | ||||
|                        NroDocumento, CBU, IdFormaPagoPreferida, Observaciones, Activo,  | ||||
|                        IdUsuarioAlta, FechaAlta, IdUsuarioMod, FechaMod | ||||
|                 FROM dbo.susc_Suscriptores WHERE 1=1"); | ||||
|              | ||||
|             var parameters = new DynamicParameters(); | ||||
|  | ||||
|             if (soloActivos) | ||||
|             { | ||||
|                 sqlBuilder.Append(" AND Activo = 1"); | ||||
|             } | ||||
|             if (!string.IsNullOrWhiteSpace(nombreFilter)) | ||||
|             { | ||||
|                 sqlBuilder.Append(" AND NombreCompleto LIKE @NombreFilter"); | ||||
|                 parameters.Add("NombreFilter", $"%{nombreFilter}%"); | ||||
|             } | ||||
|             if (!string.IsNullOrWhiteSpace(nroDocFilter)) | ||||
|             { | ||||
|                 sqlBuilder.Append(" AND NroDocumento LIKE @NroDocFilter"); | ||||
|                 parameters.Add("NroDocFilter", $"%{nroDocFilter}%"); | ||||
|             } | ||||
|             sqlBuilder.Append(" ORDER BY NombreCompleto;"); | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 using var connection = _connectionFactory.CreateConnection(); | ||||
|                 return await connection.QueryAsync<Suscriptor>(sqlBuilder.ToString(), parameters); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _logger.LogError(ex, "Error al obtener todos los Suscriptores."); | ||||
|                 return Enumerable.Empty<Suscriptor>(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async Task<Suscriptor?> GetByIdAsync(int id) | ||||
|         { | ||||
|             const string sql = @" | ||||
|                 SELECT IdSuscriptor, NombreCompleto, Email, Telefono, Direccion, TipoDocumento,  | ||||
|                        NroDocumento, CBU, IdFormaPagoPreferida, Observaciones, Activo,  | ||||
|                        IdUsuarioAlta, FechaAlta, IdUsuarioMod, FechaMod | ||||
|                 FROM dbo.susc_Suscriptores WHERE IdSuscriptor = @Id;"; | ||||
|             try | ||||
|             { | ||||
|                 using var connection = _connectionFactory.CreateConnection(); | ||||
|                 return await connection.QuerySingleOrDefaultAsync<Suscriptor>(sql, new { Id = id }); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _logger.LogError(ex, "Error al obtener Suscriptor por ID: {IdSuscriptor}", id); | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         public async Task<bool> ExistsByDocumentoAsync(string tipoDocumento, string nroDocumento, int? excludeId = null) | ||||
|         { | ||||
|             var sqlBuilder = new StringBuilder("SELECT COUNT(1) FROM dbo.susc_Suscriptores WHERE TipoDocumento = @TipoDocumento AND NroDocumento = @NroDocumento"); | ||||
|             var parameters = new DynamicParameters(); | ||||
|             parameters.Add("TipoDocumento", tipoDocumento); | ||||
|             parameters.Add("NroDocumento", nroDocumento); | ||||
|  | ||||
|             if (excludeId.HasValue) | ||||
|             { | ||||
|                 sqlBuilder.Append(" AND IdSuscriptor != @ExcludeId"); | ||||
|                 parameters.Add("ExcludeId", excludeId.Value); | ||||
|             } | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 using var connection = _connectionFactory.CreateConnection(); | ||||
|                 return await connection.ExecuteScalarAsync<bool>(sqlBuilder.ToString(), parameters); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _logger.LogError(ex, "Error en ExistsByDocumentoAsync para Suscriptor."); | ||||
|                 return true; // Asumir que existe si hay error para prevenir duplicados. | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async Task<bool> IsInUseAsync(int id) | ||||
|         { | ||||
|             // Un suscriptor está en uso si tiene suscripciones activas. | ||||
|             const string sql = "SELECT TOP 1 1 FROM dbo.susc_Suscripciones WHERE IdSuscriptor = @Id AND Estado = 'Activa'"; | ||||
|             try | ||||
|             { | ||||
|                 using var connection = _connectionFactory.CreateConnection(); | ||||
|                 var inUse = await connection.ExecuteScalarAsync<int?>(sql, new { Id = id }); | ||||
|                 return inUse.HasValue && inUse.Value == 1; | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _logger.LogError(ex, "Error en IsInUseAsync para Suscriptor ID: {IdSuscriptor}", id); | ||||
|                 return true; // Asumir en uso si hay error. | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async Task<Suscriptor?> CreateAsync(Suscriptor nuevoSuscriptor, 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_Suscriptores  | ||||
|                     (NombreCompleto, Email, Telefono, Direccion, TipoDocumento, NroDocumento,  | ||||
|                      CBU, IdFormaPagoPreferida, Observaciones, Activo, IdUsuarioAlta, FechaAlta) | ||||
|                 OUTPUT INSERTED.* | ||||
|                 VALUES  | ||||
|                     (@NombreCompleto, @Email, @Telefono, @Direccion, @TipoDocumento, @NroDocumento,  | ||||
|                      @CBU, @IdFormaPagoPreferida, @Observaciones, 1, @IdUsuarioAlta, GETDATE());"; | ||||
|  | ||||
|             var suscriptorCreado = await transaction.Connection.QuerySingleAsync<Suscriptor>( | ||||
|                 sqlInsert, | ||||
|                 nuevoSuscriptor, | ||||
|                 transaction: transaction | ||||
|             ); | ||||
|  | ||||
|             // No se necesita historial para la creación, ya que la propia tabla tiene campos de auditoría. | ||||
|             // Si se necesitara una tabla _H, aquí iría el INSERT a esa tabla. | ||||
|  | ||||
|             return suscriptorCreado; | ||||
|         } | ||||
|  | ||||
|         public async Task<bool> UpdateAsync(Suscriptor suscriptor, IDbTransaction transaction) | ||||
|         { | ||||
|             // El servicio ya ha poblado IdUsuarioMod y FechaMod en la entidad. | ||||
|             const string sqlUpdate = @" | ||||
|                 UPDATE dbo.susc_Suscriptores SET | ||||
|                     NombreCompleto = @NombreCompleto, | ||||
|                     Email = @Email, | ||||
|                     Telefono = @Telefono, | ||||
|                     Direccion = @Direccion, | ||||
|                     TipoDocumento = @TipoDocumento, | ||||
|                     NroDocumento = @NroDocumento, | ||||
|                     CBU = @CBU, | ||||
|                     IdFormaPagoPreferida = @IdFormaPagoPreferida, | ||||
|                     Observaciones = @Observaciones, | ||||
|                     IdUsuarioMod = @IdUsuarioMod, | ||||
|                     FechaMod = @FechaMod | ||||
|                 WHERE IdSuscriptor = @IdSuscriptor;"; | ||||
|  | ||||
|             if (transaction == null || transaction.Connection == null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(transaction), "La transacción o su conexión no pueden ser nulas."); | ||||
|             } | ||||
|  | ||||
|             var rowsAffected = await transaction.Connection.ExecuteAsync(sqlUpdate, suscriptor, transaction: transaction); | ||||
|             return rowsAffected == 1; | ||||
|         } | ||||
|  | ||||
|         public async Task<bool> ToggleActivoAsync(int id, bool activar, int idUsuario, IDbTransaction transaction) | ||||
|         { | ||||
|             const string sqlToggle = @" | ||||
|                 UPDATE dbo.susc_Suscriptores SET | ||||
|                     Activo = @Activar, | ||||
|                     IdUsuarioMod = @IdUsuario, | ||||
|                     FechaMod = GETDATE() | ||||
|                 WHERE IdSuscriptor = @Id;"; | ||||
|  | ||||
|             if (transaction == null || transaction.Connection == null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(transaction), "La transacción o su conexión no pueden ser nulas."); | ||||
|             } | ||||
|  | ||||
|             var rowsAffected = await transaction.Connection.ExecuteAsync( | ||||
|                 sqlToggle,  | ||||
|                 new { Activar = activar, IdUsuario = idUsuario, Id = id },  | ||||
|                 transaction: transaction | ||||
|             ); | ||||
|             return rowsAffected == 1; | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user