Files
SIG-CM2.0/src/api/SIGCM2.Infrastructure/Persistence/MedioRepository.cs

189 lines
6.0 KiB
C#
Raw Normal View History

using System.Text;
using Dapper;
using SIGCM2.Application.Abstractions.Persistence;
using SIGCM2.Application.Common;
using SIGCM2.Domain.Entities;
namespace SIGCM2.Infrastructure.Persistence;
public sealed class MedioRepository : IMedioRepository
{
private readonly SqlConnectionFactory _connectionFactory;
public MedioRepository(SqlConnectionFactory connectionFactory)
{
_connectionFactory = connectionFactory;
}
public async Task<int> AddAsync(Medio m, CancellationToken ct = default)
{
// DF handles: Activo (1), FechaCreacion (SYSUTCDATETIME()).
const string sql = """
INSERT INTO dbo.Medio (Codigo, Nombre, Tipo, PlataformaEmpresaId)
OUTPUT INSERTED.Id
VALUES (@Codigo, @Nombre, @Tipo, @PlataformaEmpresaId)
""";
await using var connection = _connectionFactory.CreateConnection();
await connection.OpenAsync(ct);
return await connection.ExecuteScalarAsync<int>(sql, new
{
m.Codigo,
m.Nombre,
Tipo = (int)m.Tipo,
m.PlataformaEmpresaId,
});
}
public async Task<Medio?> GetByIdAsync(int id, CancellationToken ct = default)
{
const string sql = """
SELECT Id, Codigo, Nombre, Tipo, PlataformaEmpresaId, Activo, FechaCreacion, FechaModificacion
FROM dbo.Medio
WHERE Id = @Id
""";
await using var connection = _connectionFactory.CreateConnection();
await connection.OpenAsync(ct);
var row = await connection.QuerySingleOrDefaultAsync<MedioRow>(sql, new { Id = id });
return row is null ? null : MapRow(row);
}
public async Task<bool> ExistsByCodigoAsync(string codigo, CancellationToken ct = default)
{
const string sql = """
SELECT COUNT(1) FROM dbo.Medio WHERE Codigo = @Codigo
""";
await using var connection = _connectionFactory.CreateConnection();
await connection.OpenAsync(ct);
var count = await connection.ExecuteScalarAsync<int>(sql, new { Codigo = codigo });
return count > 0;
}
public async Task UpdateAsync(Medio m, CancellationToken ct = default)
{
const string sql = """
UPDATE dbo.Medio
SET Nombre = @Nombre,
Tipo = @Tipo,
PlataformaEmpresaId = @PlataformaEmpresaId,
Activo = @Activo,
FechaModificacion = @FechaModificacion
WHERE Id = @Id
""";
await using var connection = _connectionFactory.CreateConnection();
await connection.OpenAsync(ct);
await connection.ExecuteAsync(sql, new
{
m.Nombre,
Tipo = (int)m.Tipo,
m.PlataformaEmpresaId,
m.Activo,
FechaModificacion = m.FechaModificacion,
m.Id,
});
}
public async Task<PagedResult<Medio>> GetPagedAsync(MediosQuery q, CancellationToken ct = default)
{
var page = Math.Max(1, q.Page);
var pageSize = Math.Clamp(q.PageSize, 1, 100);
var offset = (page - 1) * pageSize;
var where = new StringBuilder("WHERE 1=1");
var parameters = new DynamicParameters();
parameters.Add("PageSize", pageSize);
parameters.Add("Offset", offset);
if (q.Activo.HasValue)
{
where.Append(" AND Activo = @Activo");
parameters.Add("Activo", q.Activo.Value ? 1 : 0);
}
if (q.Tipo.HasValue)
{
where.Append(" AND Tipo = @Tipo");
parameters.Add("Tipo", (int)q.Tipo.Value);
}
if (!string.IsNullOrWhiteSpace(q.Search))
{
where.Append(" AND (Codigo LIKE @Search OR Nombre LIKE @Search)");
parameters.Add("Search", $"%{q.Search}%");
}
var sql = $"""
SELECT
Id, Codigo, Nombre, Tipo, PlataformaEmpresaId, Activo, FechaCreacion, FechaModificacion,
COUNT(*) OVER() AS TotalCount
FROM dbo.Medio
{where}
ORDER BY Codigo
OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY
""";
await using var connection = _connectionFactory.CreateConnection();
await connection.OpenAsync(ct);
var rows = await connection.QueryAsync<MedioPagedRow>(sql, parameters);
var list = rows.ToList();
var total = list.Count > 0 ? list[0].TotalCount : 0;
var items = list.Select(r => MapRow(r)).ToList();
return new PagedResult<Medio>(items, page, pageSize, total);
}
// ── mapping ───────────────────────────────────────────────────────────────
private static Medio MapRow(MedioRow r)
=> new(
id: r.Id,
codigo: r.Codigo,
nombre: r.Nombre,
tipo: (TipoMedio)r.Tipo,
plataformaEmpresaId: r.PlataformaEmpresaId,
activo: r.Activo,
fechaCreacion: r.FechaCreacion,
fechaModificacion: r.FechaModificacion);
private static Medio MapRow(MedioPagedRow r)
=> new(
id: r.Id,
codigo: r.Codigo,
nombre: r.Nombre,
tipo: (TipoMedio)r.Tipo,
plataformaEmpresaId: r.PlataformaEmpresaId,
activo: r.Activo,
fechaCreacion: r.FechaCreacion,
fechaModificacion: r.FechaModificacion);
private sealed record MedioRow(
int Id,
string Codigo,
string Nombre,
byte Tipo,
int? PlataformaEmpresaId,
bool Activo,
DateTime FechaCreacion,
DateTime? FechaModificacion);
private sealed record MedioPagedRow(
int Id,
string Codigo,
string Nombre,
byte Tipo,
int? PlataformaEmpresaId,
bool Activo,
DateTime FechaCreacion,
DateTime? FechaModificacion,
int TotalCount);
}