Fix catalogo y removido el fake de pruebas

This commit is contained in:
2025-08-16 11:12:54 -03:00
parent 527839dd6d
commit b89c4c0b8b
6 changed files with 69 additions and 263 deletions

View File

@@ -30,9 +30,6 @@ var connectionString = builder.Configuration.GetConnectionString("DefaultConnect
builder.Services.AddDbContext<EleccionesDbContext>(options =>
options.UseSqlServer(connectionString));
#if DEBUG
builder.Services.AddSingleton<IElectoralApiService, FakeElectoralApiService>();
#else
builder.Services.AddHttpClient("ElectoralApiClient", client =>
{
var baseUrl = builder.Configuration["ElectoralApi:BaseUrl"];
@@ -80,8 +77,6 @@ builder.Services.AddHttpClient("ElectoralApiClient", client =>
builder.Services.AddSingleton<IElectoralApiService, ElectoralApiService>();
#endif
builder.Services.AddHostedService<Worker>();
var host = builder.Build();

View File

@@ -170,126 +170,81 @@ public class Worker : BackgroundService
using var scope = _serviceProvider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<EleccionesDbContext>();
// --- 1. SINCRONIZACIÓN DE CATEGORÍAS (NUEVO) ---
// --- 1. OBTENEMOS LA LISTA COMPLETA DE CATEGORÍAS DISPONIBLES ---
var categoriasApi = await _apiService.GetCategoriasAsync(_authToken);
if (categoriasApi is { Count: > 0 })
if (categoriasApi is null || !categoriasApi.Any())
{
// Primero, nos aseguramos de procesar solo IDs de categoría únicos desde la API
// para evitar conflictos de seguimiento en Entity Framework.
var distinctCategoriasApi = categoriasApi
.GroupBy(c => c.CategoriaId)
.Select(g => g.First()) // Tomamos la primera aparición de cada ID único
.ToList();
_logger.LogWarning("No se recibieron datos del catálogo de Categorías. No se puede continuar con la sincronización.");
return;
}
var categoriasEnDb = await dbContext.CategoriasElectorales.ToDictionaryAsync(c => c.Id, c => c, stoppingToken);
// Depuramos la lista para evitar duplicados
var distinctCategorias = categoriasApi
.GroupBy(c => c.CategoriaId)
.Select(g => g.First())
.OrderBy(c => c.Orden) // Procesamos en el orden definido
.ToList();
// Ahora iteramos sobre la lista depurada
foreach (var categoriaDto in distinctCategoriasApi)
_logger.LogInformation("Se procesarán {count} categorías electorales.", distinctCategorias.Count);
// --- 2. ITERAMOS SOBRE CADA CATEGORÍA PARA DESCARGAR SUS CATÁLOGOS ---
foreach (var categoria in distinctCategorias)
{
if (stoppingToken.IsCancellationRequested) break;
_logger.LogInformation("--- Sincronizando catálogos para la categoría: {NombreCategoria} (ID: {CategoriaId}) ---", categoria.Nombre, categoria.CategoriaId);
// --- SINCRONIZACIÓN DE ÁMBITOS GEOGRÁFICOS ---
var catalogoAmbitosApi = await _apiService.GetCatalogoAmbitosAsync(_authToken, categoria.CategoriaId);
if (catalogoAmbitosApi is { Count: > 0 })
{
if (categoriasEnDb.TryGetValue(categoriaDto.CategoriaId, out var categoriaExistente))
var ambitosEnDb = await dbContext.AmbitosGeograficos.ToDictionaryAsync(a => (a.DistritoId, a.SeccionId, a.MunicipioId), a => a, stoppingToken);
foreach (var ambitoDto in catalogoAmbitosApi.SelectMany(c => c.Ambitos))
{
// La categoría ya existe, actualizamos sus datos
categoriaExistente.Nombre = categoriaDto.Nombre;
categoriaExistente.Orden = categoriaDto.Orden;
}
else
{
// La categoría es nueva, la añadimos
await dbContext.CategoriasElectorales.AddAsync(new CategoriaElectoral
var claveUnica = (ambitoDto.CodigoAmbitos.DistritoId, ambitoDto.CodigoAmbitos.SeccionId, ambitoDto.CodigoAmbitos.MunicipioId);
if (!ambitosEnDb.TryGetValue(claveUnica, out var ambitoExistente))
{
Id = categoriaDto.CategoriaId,
Nombre = categoriaDto.Nombre,
Orden = categoriaDto.Orden
}, stoppingToken);
await dbContext.AmbitosGeograficos.AddAsync(new AmbitoGeografico
{
Nombre = ambitoDto.Nombre,
NivelId = ambitoDto.NivelId,
DistritoId = ambitoDto.CodigoAmbitos.DistritoId,
SeccionId = ambitoDto.CodigoAmbitos.SeccionId,
MunicipioId = ambitoDto.CodigoAmbitos.MunicipioId,
SeccionProvincialId = ambitoDto.CodigoAmbitos.SeccionProvincialId
}, stoppingToken);
}
}
_logger.LogInformation("Sincronización de Ámbitos Geográficos completada para la categoría actual.");
}
// --- SINCRONIZACIÓN DE AGRUPACIONES POLÍTICAS ---
var provincia = catalogoAmbitosApi?.SelectMany(c => c.Ambitos).FirstOrDefault(a => a.NivelId == 10);
if (provincia != null)
{
var agrupacionesApi = await _apiService.GetAgrupacionesAsync(_authToken, provincia.CodigoAmbitos.DistritoId, categoria.CategoriaId);
if (agrupacionesApi is { Count: > 0 })
{
var agrupacionesEnDb = await dbContext.AgrupacionesPoliticas.ToDictionaryAsync(a => a.Id, a => a, stoppingToken);
foreach (var agrupacionDto in agrupacionesApi)
{
if (!agrupacionesEnDb.TryGetValue(agrupacionDto.IdAgrupacion, out var agrupacionExistente))
{
await dbContext.AgrupacionesPoliticas.AddAsync(new AgrupacionPolitica
{
Id = agrupacionDto.IdAgrupacion,
IdTelegrama = agrupacionDto.IdAgrupacionTelegrama,
Nombre = agrupacionDto.NombreAgrupacion
}, stoppingToken);
}
}
_logger.LogInformation("Sincronización de Agrupaciones Políticas completada para la categoría actual.");
}
}
_logger.LogInformation("Sincronización de Categorías Electorales completada.");
}
else
{
_logger.LogWarning("No se recibieron datos del catálogo de Categorías.");
}
} // Fin del bucle foreach
// --- 2. SINCRONIZACIÓN DE ÁMBITOS GEOGRÁFICOS ---
var catalogoAmbitosApi = await _apiService.GetCatalogoCompletoAsync(_authToken);
if (catalogoAmbitosApi is { Count: > 0 })
{
// Cargamos los ámbitos existentes de la BD en un diccionario para búsqueda rápida
var ambitosEnDb = await dbContext.AmbitosGeograficos
.ToDictionaryAsync(a => a.MunicipioId ?? a.SeccionId ?? a.DistritoId ?? a.Nombre, a => a, stoppingToken);
foreach (var ambitoDto in catalogoAmbitosApi.SelectMany(c => c.Ambitos))
{
// Usamos una clave única para identificar el ámbito (ej. ID de municipio)
var claveUnica = ambitoDto.CodigoAmbitos.MunicipioId ?? ambitoDto.CodigoAmbitos.SeccionId ?? ambitoDto.CodigoAmbitos.DistritoId ?? ambitoDto.Nombre;
if (ambitosEnDb.TryGetValue(claveUnica, out var ambitoExistente))
{
// El ámbito ya existe, actualizamos sus datos descriptivos.
// No actualizamos los IDs, ya que forman parte de la identidad del ámbito.
ambitoExistente.Nombre = ambitoDto.Nombre;
ambitoExistente.NivelId = ambitoDto.NivelId;
}
else
{
// El ámbito es nuevo, lo añadimos (el código de inserción que ya tenemos es correcto)
var nuevoAmbito = new AmbitoGeografico
{
Nombre = ambitoDto.Nombre,
NivelId = ambitoDto.NivelId,
DistritoId = ambitoDto.CodigoAmbitos.DistritoId,
SeccionId = ambitoDto.CodigoAmbitos.SeccionId,
MunicipioId = ambitoDto.CodigoAmbitos.MunicipioId,
SeccionProvincialId = ambitoDto.CodigoAmbitos.SeccionProvincialId
};
await dbContext.AmbitosGeograficos.AddAsync(nuevoAmbito, stoppingToken);
}
}
_logger.LogInformation("Sincronización de Ámbitos Geográficos completada.");
}
else
{
_logger.LogWarning("No se recibieron datos del catálogo de Ámbitos. Los datos existentes no serán modificados.");
}
// --- 3. SINCRONIZACIÓN DE AGRUPACIONES POLÍTICAS ---
var agrupacionesApi = await _apiService.GetAgrupacionesAsync(_authToken, "02", 5);
if (agrupacionesApi is { Count: > 0 })
{
var agrupacionesEnDb = await dbContext.AgrupacionesPoliticas
.ToDictionaryAsync(a => a.Id, a => a, stoppingToken);
foreach (var agrupacionDto in agrupacionesApi)
{
if (agrupacionesEnDb.TryGetValue(agrupacionDto.IdAgrupacion, out var agrupacionExistente))
{
// La agrupación ya existe, actualizamos el nombre por si cambia
agrupacionExistente.Nombre = agrupacionDto.NombreAgrupacion;
agrupacionExistente.IdTelegrama = agrupacionDto.IdAgrupacionTelegrama;
}
else
{
// La agrupación es nueva, la añadimos
var nuevaAgrupacion = new AgrupacionPolitica
{
Id = agrupacionDto.IdAgrupacion,
IdTelegrama = agrupacionDto.IdAgrupacionTelegrama,
Nombre = agrupacionDto.NombreAgrupacion
};
await dbContext.AgrupacionesPoliticas.AddAsync(nuevaAgrupacion, stoppingToken);
}
}
_logger.LogInformation("Sincronización de Agrupaciones Políticas completada.");
}
else
{
_logger.LogWarning("No se recibieron datos del catálogo de Agrupaciones. Los datos existentes no serán modificados.");
}
// --- 4. GUARDADO FINAL ---
// --- 3. GUARDADO FINAL ---
int cambiosGuardados = await dbContext.SaveChangesAsync(stoppingToken);
_logger.LogInformation("{count} cambios en los catálogos han sido guardados en la base de datos.", cambiosGuardados);
_logger.LogInformation("{count} cambios totales en los catálogos han sido guardados en la base de datos.", cambiosGuardados);
_logger.LogInformation("Sincronización de catálogos maestros finalizada.");
}
catch (Exception ex)