Files
GestionIntegralWeb/Backend/GestionIntegral.Api/Data/Repositories/Distribucion/DistribuidorRepository.cs
dmolinari 5212e31a03
All checks were successful
Optimized Build and Deploy / remote-build-and-deploy (push) Successful in 8m32s
Feat: Baja Lógica de Distribuidores (Selectores Dropdown)
2026-03-23 14:09:26 -03:00

445 lines
22 KiB
C#

using Dapper;
using GestionIntegral.Api.Dtos.Distribucion;
using GestionIntegral.Api.Models.Distribucion;
using Microsoft.Extensions.Logging;
using System; // Añadido para Exception
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GestionIntegral.Api.Data.Repositories.Distribucion
{
public class DistribuidorRepository : IDistribuidorRepository
{
private readonly DbConnectionFactory _connectionFactory;
private readonly ILogger<DistribuidorRepository> _logger;
public DistribuidorRepository(DbConnectionFactory connectionFactory, ILogger<DistribuidorRepository> logger)
{
_connectionFactory = connectionFactory;
_logger = logger;
}
public async Task<IEnumerable<(Distribuidor Distribuidor, string? NombreZona)>> GetAllAsync(string? nombreFilter, string? nroDocFilter, bool? soloActivos = true)
{
var sqlBuilder = new StringBuilder(@"
SELECT
d.Id_Distribuidor AS IdDistribuidor, d.Nombre, d.Contacto, d.NroDoc, d.Id_Zona AS IdZona,
d.Calle, d.Numero, d.Piso, d.Depto, d.Telefono, d.Email, d.Localidad, d.Baja, d.FechaBaja,
z.Nombre AS NombreZona
FROM dbo.dist_dtDistribuidores d
LEFT JOIN dbo.dist_dtZonas z ON d.Id_Zona = z.Id_Zona
WHERE 1=1");
var parameters = new DynamicParameters();
if (!string.IsNullOrWhiteSpace(nombreFilter))
{
sqlBuilder.Append(" AND d.Nombre LIKE @NombreParam");
parameters.Add("NombreParam", $"%{nombreFilter}%");
}
if (!string.IsNullOrWhiteSpace(nroDocFilter))
{
sqlBuilder.Append(" AND d.NroDoc LIKE @NroDocParam");
parameters.Add("NroDocParam", $"%{nroDocFilter}%");
}
if (soloActivos.HasValue)
{
sqlBuilder.Append(" AND d.Baja = @BajaStatus ");
parameters.Add("BajaStatus", !soloActivos.Value);
}
sqlBuilder.Append(" ORDER BY d.Nombre;");
try
{
using var connection = _connectionFactory.CreateConnection();
return await connection.QueryAsync<Distribuidor, string, (Distribuidor, string?)>(
sqlBuilder.ToString(),
(dist, zona) => (dist, zona),
parameters,
splitOn: "NombreZona"
);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al obtener todos los Distribuidores. Filtros: Nombre='{NombreFilter}', NroDoc='{NroDocFilter}'", nombreFilter, nroDocFilter);
return Enumerable.Empty<(Distribuidor, string?)>();
}
}
public async Task<IEnumerable<DistribuidorDropdownDto?>> GetAllDropdownAsync(bool? soloActivos = true)
{
var sqlBuilder = new StringBuilder(@"
SELECT
Id_Distribuidor AS IdDistribuidor, Nombre
FROM dbo.dist_dtDistribuidores
WHERE 1=1");
var parameters = new DynamicParameters();
if (soloActivos.HasValue)
{
sqlBuilder.Append(" AND Baja = @BajaStatus ");
parameters.Add("BajaStatus", !soloActivos.Value);
}
sqlBuilder.Append(" ORDER BY Nombre;");
try
{
using var connection = _connectionFactory.CreateConnection();
return await connection.QueryAsync<DistribuidorDropdownDto>(
sqlBuilder.ToString(),
parameters
);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al obtener todos los Distribuidores.");
return Enumerable.Empty<DistribuidorDropdownDto>();
}
}
public async Task<(Distribuidor? Distribuidor, string? NombreZona)> GetByIdAsync(int id)
{
const string sql = @"
SELECT
d.Id_Distribuidor AS IdDistribuidor, d.Nombre, d.Contacto, d.NroDoc, d.Id_Zona AS IdZona,
d.Calle, d.Numero, d.Piso, d.Depto, d.Telefono, d.Email, d.Localidad, d.Baja, d.FechaBaja,
z.Nombre AS NombreZona
FROM dbo.dist_dtDistribuidores d
LEFT JOIN dbo.dist_dtZonas z ON d.Id_Zona = z.Id_Zona
WHERE d.Id_Distribuidor = @IdParam";
try
{
using var connection = _connectionFactory.CreateConnection();
var result = await connection.QueryAsync<Distribuidor, string, (Distribuidor?, string?)>(
sql,
(dist, zona) => (dist, zona),
new { IdParam = id },
splitOn: "NombreZona"
);
return result.SingleOrDefault();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al obtener Distribuidor por ID: {IdDistribuidor}", id);
return (null, null);
}
}
public async Task<DistribuidorLookupDto?> ObtenerLookupPorIdAsync(int id)
{
const string sql = @"
SELECT
Id_Distribuidor AS IdDistribuidor, Nombre
FROM dbo.dist_dtDistribuidores
WHERE Id_Distribuidor = @IdParam";
try
{
using var connection = _connectionFactory.CreateConnection();
return await connection.QuerySingleOrDefaultAsync<DistribuidorLookupDto>(sql, new { IdParam = id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al obtener Distribuidor por ID: {IdDistribuidor}", id);
return null;
}
}
public async Task<Distribuidor?> GetByIdSimpleAsync(int id)
{
const string sql = @"
SELECT
Id_Distribuidor AS IdDistribuidor, Nombre, Contacto, NroDoc, Id_Zona AS IdZona,
Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja
FROM dbo.dist_dtDistribuidores
WHERE Id_Distribuidor = @IdParam";
try
{
using var connection = _connectionFactory.CreateConnection();
return await connection.QuerySingleOrDefaultAsync<Distribuidor>(sql, new { IdParam = id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al obtener Distribuidor (simple) por ID: {IdDistribuidor}", id);
return null;
}
}
public async Task<bool> ExistsByNroDocAsync(string nroDoc, int? excludeIdDistribuidor = null)
{
var sqlBuilder = new StringBuilder("SELECT COUNT(1) FROM dbo.dist_dtDistribuidores WHERE NroDoc = @NroDocParam");
var parameters = new DynamicParameters();
parameters.Add("NroDocParam", nroDoc);
if (excludeIdDistribuidor.HasValue)
{
sqlBuilder.Append(" AND Id_Distribuidor != @ExcludeIdParam");
parameters.Add("ExcludeIdParam", excludeIdDistribuidor.Value);
}
try
{
using var connection = _connectionFactory.CreateConnection();
return await connection.ExecuteScalarAsync<bool>(sqlBuilder.ToString(), parameters);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error en ExistsByNroDocAsync. NroDoc: {NroDoc}", nroDoc);
return true;
}
}
public async Task<bool> ExistsByNameAsync(string nombre, int? excludeIdDistribuidor = null)
{
var sqlBuilder = new StringBuilder("SELECT COUNT(1) FROM dbo.dist_dtDistribuidores WHERE Nombre = @NombreParam");
var parameters = new DynamicParameters();
parameters.Add("NombreParam", nombre);
if (excludeIdDistribuidor.HasValue)
{
sqlBuilder.Append(" AND Id_Distribuidor != @ExcludeIdParam");
parameters.Add("ExcludeIdParam", excludeIdDistribuidor.Value);
}
try
{
using var connection = _connectionFactory.CreateConnection();
return await connection.ExecuteScalarAsync<bool>(sqlBuilder.ToString(), parameters);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error en ExistsByNameAsync. Nombre: {Nombre}", nombre);
return true;
}
}
public async Task<bool> IsInUseAsync(int id)
{
using var connection = _connectionFactory.CreateConnection();
string[] checkQueries = {
"SELECT TOP 1 1 FROM dbo.dist_EntradasSalidas WHERE Id_Distribuidor = @IdParam",
"SELECT TOP 1 1 FROM dbo.cue_PagosDistribuidor WHERE Id_Distribuidor = @IdParam",
"SELECT TOP 1 1 FROM dbo.dist_PorcPago WHERE Id_Distribuidor = @IdParam"
};
try
{
foreach (var query in checkQueries)
{
if (await connection.ExecuteScalarAsync<int?>(query, new { IdParam = id }) == 1) return true;
}
return false;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error en IsInUseAsync para Distribuidor ID: {IdDistribuidor}", id);
return true;
}
}
public async Task<Distribuidor?> CreateAsync(Distribuidor nuevoDistribuidor, int idUsuario, IDbTransaction transaction)
{
const string sqlInsert = @"
INSERT INTO dbo.dist_dtDistribuidores (Nombre, Contacto, NroDoc, Id_Zona, Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja)
OUTPUT INSERTED.Id_Distribuidor AS IdDistribuidor, INSERTED.Nombre, INSERTED.Contacto, INSERTED.NroDoc, INSERTED.Id_Zona AS IdZona,
INSERTED.Calle, INSERTED.Numero, INSERTED.Piso, INSERTED.Depto, INSERTED.Telefono, INSERTED.Email, INSERTED.Localidad, INSERTED.Baja, INSERTED.FechaBaja
VALUES (@Nombre, @Contacto, @NroDoc, @IdZona, @Calle, @Numero, @Piso, @Depto, @Telefono, @Email, @Localidad, 0, NULL);";
var connection = transaction.Connection!;
var inserted = await connection.QuerySingleAsync<Distribuidor>(sqlInsert, nuevoDistribuidor, transaction);
if (inserted == null || inserted.IdDistribuidor == 0) throw new DataException("Error al crear distribuidor o al obtener el ID generado.");
const string sqlInsertHistorico = @"
INSERT INTO dbo.dist_dtDistribuidores_H
(Id_Distribuidor, Nombre, Contacto, NroDoc, Id_Zona, Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja, Id_Usuario, FechaMod, TipoMod)
VALUES (@IdDistribuidorParam, @NombreParam, @ContactoParam, @NroDocParam, @IdZonaParam, @CalleParam, @NumeroParam, @PisoParam, @DeptoParam, @TelefonoParam, @EmailParam, @LocalidadParam, @BajaParam, @FechaBajaParam, @IdUsuarioParam, @FechaModParam, @TipoModParam);";
await connection.ExecuteAsync(sqlInsertHistorico, new
{
IdDistribuidorParam = inserted.IdDistribuidor,
NombreParam = inserted.Nombre,
ContactoParam = inserted.Contacto,
NroDocParam = inserted.NroDoc,
IdZonaParam = inserted.IdZona,
CalleParam = inserted.Calle,
NumeroParam = inserted.Numero,
PisoParam = inserted.Piso,
DeptoParam = inserted.Depto,
TelefonoParam = inserted.Telefono,
EmailParam = inserted.Email,
LocalidadParam = inserted.Localidad,
BajaParam = inserted.Baja,
FechaBajaParam = inserted.FechaBaja,
IdUsuarioParam = idUsuario,
FechaModParam = DateTime.Now,
TipoModParam = "Creado"
}, transaction);
return inserted;
}
public async Task<bool> UpdateAsync(Distribuidor distribuidorAActualizar, int idUsuario, IDbTransaction transaction)
{
var connection = transaction.Connection!;
var actual = await connection.QuerySingleOrDefaultAsync<Distribuidor>(
@"SELECT Id_Distribuidor AS IdDistribuidor, Nombre, Contacto, NroDoc, Id_Zona AS IdZona,
Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja
FROM dbo.dist_dtDistribuidores WHERE Id_Distribuidor = @IdDistribuidorParam",
new { IdDistribuidorParam = distribuidorAActualizar.IdDistribuidor }, transaction);
if (actual == null) throw new KeyNotFoundException("Distribuidor no encontrado.");
const string sqlUpdate = @"
UPDATE dbo.dist_dtDistribuidores SET
Nombre = @Nombre, Contacto = @Contacto, NroDoc = @NroDoc, Id_Zona = @IdZona, Calle = @Calle, Numero = @Numero,
Piso = @Piso, Depto = @Depto, Telefono = @Telefono, Email = @Email, Localidad = @Localidad
WHERE Id_Distribuidor = @IdDistribuidor;";
const string sqlInsertHistorico = @"
INSERT INTO dbo.dist_dtDistribuidores_H
(Id_Distribuidor, Nombre, Contacto, NroDoc, Id_Zona, Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja, Id_Usuario, FechaMod, TipoMod)
VALUES (@IdDistribuidorParam, @NombreParam, @ContactoParam, @NroDocParam, @IdZonaParam, @CalleParam, @NumeroParam, @PisoParam, @DeptoParam, @TelefonoParam, @EmailParam, @LocalidadParam, @BajaParam, @FechaBajaParam, @IdUsuarioParam, @FechaModParam, @TipoModParam);";
await connection.ExecuteAsync(sqlInsertHistorico, new
{
IdDistribuidorParam = actual.IdDistribuidor,
NombreParam = actual.Nombre,
ContactoParam = actual.Contacto,
NroDocParam = actual.NroDoc,
IdZonaParam = actual.IdZona,
CalleParam = actual.Calle,
NumeroParam = actual.Numero,
PisoParam = actual.Piso,
DeptoParam = actual.Depto,
TelefonoParam = actual.Telefono,
EmailParam = actual.Email,
LocalidadParam = actual.Localidad,
BajaParam = actual.Baja,
FechaBajaParam = actual.FechaBaja,
IdUsuarioParam = idUsuario,
FechaModParam = DateTime.Now,
TipoModParam = "Actualizado"
}, transaction);
var rowsAffected = await connection.ExecuteAsync(sqlUpdate, distribuidorAActualizar, transaction);
return rowsAffected == 1;
}
public async Task<bool> DeleteAsync(int id, int idUsuario, IDbTransaction transaction)
{
var connection = transaction.Connection!;
var actual = await connection.QuerySingleOrDefaultAsync<Distribuidor>(
@"SELECT Id_Distribuidor AS IdDistribuidor, Nombre, Contacto, NroDoc, Id_Zona AS IdZona,
Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja
FROM dbo.dist_dtDistribuidores WHERE Id_Distribuidor = @IdParam", new { IdParam = id }, transaction);
if (actual == null) throw new KeyNotFoundException("Distribuidor no encontrado.");
// ... (resto del método DeleteAsync)
const string sqlDelete = "DELETE FROM dbo.dist_dtDistribuidores WHERE Id_Distribuidor = @IdParam";
const string sqlInsertHistorico = @"
INSERT INTO dbo.dist_dtDistribuidores_H
(Id_Distribuidor, Nombre, Contacto, NroDoc, Id_Zona, Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja, Id_Usuario, FechaMod, TipoMod)
VALUES (@IdDistribuidorParam, @NombreParam, @ContactoParam, @NroDocParam, @IdZonaParam, @CalleParam, @NumeroParam, @PisoParam, @DeptoParam, @TelefonoParam, @EmailParam, @LocalidadParam, @BajaParam, @FechaBajaParam, @IdUsuarioParam, @FechaModParam, @TipoModParam);";
await connection.ExecuteAsync(sqlInsertHistorico, new
{
IdDistribuidorParam = actual.IdDistribuidor,
NombreParam = actual.Nombre,
ContactoParam = actual.Contacto,
NroDocParam = actual.NroDoc,
IdZonaParam = actual.IdZona,
CalleParam = actual.Calle,
NumeroParam = actual.Numero,
PisoParam = actual.Piso,
DeptoParam = actual.Depto,
TelefonoParam = actual.Telefono,
EmailParam = actual.Email,
LocalidadParam = actual.Localidad,
BajaParam = actual.Baja,
FechaBajaParam = actual.FechaBaja,
IdUsuarioParam = idUsuario,
FechaModParam = DateTime.Now,
TipoModParam = "Eliminado"
}, transaction);
var rowsAffected = await connection.ExecuteAsync(sqlDelete, new { IdParam = id }, transaction);
return rowsAffected == 1;
}
public async Task<bool> ToggleBajaAsync(int id, bool darDeBaja, DateTime? fechaBaja, int idUsuario, IDbTransaction transaction)
{
var connection = transaction.Connection!;
var actual = await connection.QuerySingleOrDefaultAsync<Distribuidor>(
@"SELECT Id_Distribuidor AS IdDistribuidor, Nombre, Contacto, NroDoc, Id_Zona AS IdZona,
Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja
FROM dbo.dist_dtDistribuidores WHERE Id_Distribuidor = @IdDistribuidorParam",
new { IdDistribuidorParam = id }, transaction);
if (actual == null) throw new KeyNotFoundException("Distribuidor no encontrado para dar de baja/alta.");
const string sqlUpdate = "UPDATE dbo.dist_dtDistribuidores SET Baja = @BajaParam, FechaBaja = @FechaBajaParam WHERE Id_Distribuidor = @IdDistribuidorParam;";
const string sqlInsertHistorico = @"
INSERT INTO dbo.dist_dtDistribuidores_H
(Id_Distribuidor, Nombre, Contacto, NroDoc, Id_Zona, Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja, Id_Usuario, FechaMod, TipoMod)
VALUES (@IdDistribuidorParam, @NombreParam, @ContactoParam, @NroDocParam, @IdZonaParam, @CalleParam, @NumeroParam, @PisoParam, @DeptoParam, @TelefonoParam, @EmailParam, @LocalidadParam, @BajaNuevaParam, @FechaBajaNuevaParam, @IdUsuarioParam, @FechaModParam, @TipoModHistParam);";
await connection.ExecuteAsync(sqlInsertHistorico, new
{
IdDistribuidorParam = actual.IdDistribuidor,
NombreParam = actual.Nombre,
ContactoParam = actual.Contacto,
NroDocParam = actual.NroDoc,
IdZonaParam = actual.IdZona,
CalleParam = actual.Calle,
NumeroParam = actual.Numero,
PisoParam = actual.Piso,
DeptoParam = actual.Depto,
TelefonoParam = actual.Telefono,
EmailParam = actual.Email,
LocalidadParam = actual.Localidad,
BajaNuevaParam = darDeBaja,
FechaBajaNuevaParam = (darDeBaja ? fechaBaja : null),
IdUsuarioParam = idUsuario,
FechaModParam = DateTime.Now,
TipoModHistParam = (darDeBaja ? "Baja" : "Alta")
}, transaction);
var rowsAffected = await connection.ExecuteAsync(sqlUpdate, new { BajaParam = darDeBaja, FechaBajaParam = (darDeBaja ? fechaBaja : null), IdDistribuidorParam = id }, transaction);
return rowsAffected == 1;
}
public async Task<IEnumerable<(DistribuidorHistorico Historial, string NombreUsuarioModifico)>> GetHistorialAsync(
DateTime? fechaDesde, DateTime? fechaHasta,
int? idUsuarioModifico, string? tipoModificacion,
int? idDistribuidorOriginal)
{
using var connection = _connectionFactory.CreateConnection(); // Asumiendo _connectionFactory
var sqlBuilder = new StringBuilder(@"
SELECT
h.Id_Distribuidor, h.Nombre, h.Contacto, h.NroDoc, h.Id_Zona, h.Calle, h.Numero,
h.Piso, h.Depto, h.Telefono, h.Email, h.Localidad,
h.Id_Usuario, h.FechaMod, h.TipoMod,
u.Nombre + ' ' + u.Apellido AS NombreUsuarioModifico
FROM dbo.dist_dtDistribuidores_H h
JOIN dbo.gral_Usuarios u ON h.Id_Usuario = u.Id
WHERE 1=1");
var parameters = new DynamicParameters();
if (fechaDesde.HasValue) { sqlBuilder.Append(" AND h.FechaMod >= @FechaDesdeParam"); parameters.Add("FechaDesdeParam", fechaDesde.Value.Date); }
if (fechaHasta.HasValue) { sqlBuilder.Append(" AND h.FechaMod <= @FechaHastaParam"); parameters.Add("FechaHastaParam", fechaHasta.Value.Date.AddDays(1).AddTicks(-1)); }
if (idUsuarioModifico.HasValue) { sqlBuilder.Append(" AND h.Id_Usuario = @IdUsuarioModificoParam"); parameters.Add("IdUsuarioModificoParam", idUsuarioModifico.Value); }
if (!string.IsNullOrWhiteSpace(tipoModificacion)) { sqlBuilder.Append(" AND h.TipoMod = @TipoModParam"); parameters.Add("TipoModParam", tipoModificacion); }
if (idDistribuidorOriginal.HasValue) { sqlBuilder.Append(" AND h.Id_Distribuidor = @IdDistribuidorOriginalParam"); parameters.Add("IdDistribuidorOriginalParam", idDistribuidorOriginal.Value); }
sqlBuilder.Append(" ORDER BY h.FechaMod DESC;");
try
{
var result = await connection.QueryAsync<DistribuidorHistorico, string, (DistribuidorHistorico, string)>(
sqlBuilder.ToString(),
(hist, userName) => (hist, userName),
parameters,
splitOn: "NombreUsuarioModifico"
);
return result;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al obtener historial de Distribuidores (Maestro)."); // Asumiendo _logger
return Enumerable.Empty<(DistribuidorHistorico, string)>();
}
}
}
}