Fix Iteración por Provincias en Catálogo Maestro

This commit is contained in:
2025-10-21 18:16:54 -03:00
parent c5c1872ab8
commit ced1ae6b3f

View File

@@ -196,8 +196,7 @@ public class LowPriorityDataWorker : BackgroundService
/// <summary> /// <summary>
/// Descarga y sincroniza los catálogos base (Categorías, Ámbitos, Agrupaciones) /// Descarga y sincroniza los catálogos base (Categorías, Ámbitos, Agrupaciones)
/// desde la API a la base de datos local. Se ejecuta una sola vez al iniciar el worker. /// desde la API a la base de datos local. Se ejecuta una sola vez al iniciar el worker.
/// Utiliza una estrategia de guardado en lotes para manejar grandes volúmenes de datos /// La sincronización de agrupaciones ahora itera por cada provincia para obtener listas completas.
/// sin sobrecargar la base de datos.
/// </summary> /// </summary>
/// <param name="stoppingToken">El token de cancelación para detener la operación.</param> /// <param name="stoppingToken">El token de cancelación para detener la operación.</param>
private async Task SincronizarCatalogosMaestrosAsync(CancellationToken stoppingToken) private async Task SincronizarCatalogosMaestrosAsync(CancellationToken stoppingToken)
@@ -215,7 +214,7 @@ public class LowPriorityDataWorker : BackgroundService
using var scope = _serviceProvider.CreateScope(); using var scope = _serviceProvider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<EleccionesDbContext>(); var dbContext = scope.ServiceProvider.GetRequiredService<EleccionesDbContext>();
// 1. SINCRONIZAR CATEGORÍAS // --- PASO 1: SINCRONIZAR CATEGORÍAS ---
var categoriasApi = await _apiService.GetCategoriasAsync(authToken); var categoriasApi = await _apiService.GetCategoriasAsync(authToken);
if (categoriasApi is null || !categoriasApi.Any()) if (categoriasApi is null || !categoriasApi.Any())
{ {
@@ -234,38 +233,7 @@ public class LowPriorityDataWorker : BackgroundService
await dbContext.SaveChangesAsync(stoppingToken); await dbContext.SaveChangesAsync(stoppingToken);
_logger.LogInformation("Catálogo de Categorías Electorales sincronizado."); _logger.LogInformation("Catálogo de Categorías Electorales sincronizado.");
// 2. SINCRONIZAR AGRUPACIONES POLÍTICAS // --- PASO 2: SINCRONIZAR ÁMBITOS GEOGRÁFICOS ---
_logger.LogInformation("Iniciando sincronización de Agrupaciones Políticas...");
var agrupacionesEnDb = await dbContext.AgrupacionesPoliticas.ToDictionaryAsync(a => a.Id, a => a, stoppingToken);
foreach (var categoria in distinctCategorias)
{
if (stoppingToken.IsCancellationRequested) break;
// Se pasa 'null' como distritoId para obtener todas las agrupaciones de la categoría.
var agrupacionesApi = await _apiService.GetAgrupacionesAsync(authToken, null, categoria.CategoriaId);
if (agrupacionesApi != null)
{
foreach (var agrupacionDto in agrupacionesApi)
{
if (!agrupacionesEnDb.ContainsKey(agrupacionDto.IdAgrupacion))
{
var nuevaAgrupacion = new AgrupacionPolitica
{
Id = agrupacionDto.IdAgrupacion,
IdTelegrama = agrupacionDto.IdAgrupacionTelegrama,
Nombre = agrupacionDto.NombreAgrupacion
};
dbContext.AgrupacionesPoliticas.Add(nuevaAgrupacion);
agrupacionesEnDb.Add(nuevaAgrupacion.Id, nuevaAgrupacion); // Añadir al diccionario para evitar duplicados en el mismo ciclo
}
}
}
}
int agrupacionesGuardadas = await dbContext.SaveChangesAsync(stoppingToken);
_logger.LogInformation("Catálogo de Agrupaciones Políticas sincronizado. Se guardaron {count} nuevos registros.", agrupacionesGuardadas);
// 3. SINCRONIZAR ÁMBITOS GEOGRÁFICOS
_logger.LogInformation("Iniciando sincronización de Ámbitos Geográficos..."); _logger.LogInformation("Iniciando sincronización de Ámbitos Geográficos...");
var ambitosEnDbKeys = new HashSet<string>( var ambitosEnDbKeys = new HashSet<string>(
await dbContext.AmbitosGeograficos.Select(a => $"{a.NivelId}|{a.DistritoId}|{a.SeccionProvincialId}|{a.SeccionId}|{a.MunicipioId}|{a.CircuitoId}|{a.EstablecimientoId}|{a.MesaId}").ToListAsync(stoppingToken) await dbContext.AmbitosGeograficos.Select(a => $"{a.NivelId}|{a.DistritoId}|{a.SeccionProvincialId}|{a.SeccionId}|{a.MunicipioId}|{a.CircuitoId}|{a.EstablecimientoId}|{a.MesaId}").ToListAsync(stoppingToken)
@@ -281,7 +249,7 @@ public class LowPriorityDataWorker : BackgroundService
foreach (var ambitoDto in catalogoDto.Ambitos) foreach (var ambitoDto in catalogoDto.Ambitos)
{ {
string claveUnica = $"{ambitoDto.NivelId}|{ambitoDto.CodigoAmbitos.DistritoId}|{ambitoDto.CodigoAmbitos.SeccionProvincialId}|{ambitoDto.CodigoAmbitos.SeccionId}|{ambitoDto.CodigoAmbitos.MunicipioId}|{ambitoDto.CodigoAmbitos.CircuitoId}|{ambitoDto.CodigoAmbitos.EstablecimientoId}|{ambitoDto.CodigoAmbitos.MesaId}"; string claveUnica = $"{ambitoDto.NivelId}|{ambitoDto.CodigoAmbitos.DistritoId}|{ambitoDto.CodigoAmbitos.SeccionProvincialId}|{ambitoDto.CodigoAmbitos.SeccionId}|{ambitoDto.CodigoAmbitos.MunicipioId}|{ambitoDto.CodigoAmbitos.CircuitoId}|{ambitoDto.CodigoAmbitos.EstablecimientoId}|{ambitoDto.CodigoAmbitos.MesaId}";
if (ambitosEnDbKeys.Add(claveUnica)) // HashSet.Add devuelve true si el elemento no existía if (ambitosEnDbKeys.Add(claveUnica))
{ {
string nombreCorregido = ambitoDto.Nombre; string nombreCorregido = ambitoDto.Nombre;
if (ambitoDto.CodigoAmbitos.DistritoId == "01" && ambitoDto.NivelId == 30 && int.TryParse(ambitoDto.Nombre, out int numeroComuna)) if (ambitoDto.CodigoAmbitos.DistritoId == "01" && ambitoDto.NivelId == 30 && int.TryParse(ambitoDto.Nombre, out int numeroComuna))
@@ -307,10 +275,68 @@ public class LowPriorityDataWorker : BackgroundService
{ {
int ambitosGuardados = await dbContext.SaveChangesAsync(stoppingToken); int ambitosGuardados = await dbContext.SaveChangesAsync(stoppingToken);
totalNuevosAmbitos += ambitosGuardados; totalNuevosAmbitos += ambitosGuardados;
_logger.LogInformation("Guardados {count} nuevos ámbitos para la categoría '{catNombre}'.", ambitosGuardados, categoria.Nombre);
} }
} }
_logger.LogInformation("Catálogo de Ámbitos Geográficos sincronizado. Se guardaron {count} nuevos registros en total.", totalNuevosAmbitos); _logger.LogInformation("Catálogo de Ámbitos Geográficos sincronizado. Se guardaron {count} nuevos registros en total.", totalNuevosAmbitos);
_logger.LogInformation("Iniciando sincronización de Agrupaciones Políticas por provincia y categoría...");
// Obtenemos todas las provincias (Nivel 10) que ya sincronizamos.
var provincias = await dbContext.AmbitosGeograficos
.AsNoTracking()
.Where(a => a.NivelId == 10 && a.DistritoId != null)
.ToListAsync(stoppingToken);
// Definimos las constantes para las categorías y las provincias que renuevan senadores.
const int catDiputadosNac = 3;
const int catSenadoresNac = 2;
var provinciasQueRenuevanSenadores = new HashSet<string> { "01", "06", "08", "15", "16", "17", "22", "24" };
var agrupacionesEnDb = await dbContext.AgrupacionesPoliticas.ToDictionaryAsync(a => a.Id, a => a, stoppingToken);
// Iteramos sobre cada provincia.
foreach (var provincia in provincias)
{
if (stoppingToken.IsCancellationRequested) break;
// Determinamos qué categorías consultar para esta provincia.
var categoriasParaSondear = new List<int> { catDiputadosNac }; // Todas las provincias eligen diputados.
if (provinciasQueRenuevanSenadores.Contains(provincia.DistritoId!))
{
categoriasParaSondear.Add(catSenadoresNac); // Solo algunas eligen senadores.
}
// Iteramos sobre las categorías aplicables para la provincia actual.
foreach (var categoriaId in categoriasParaSondear)
{
_logger.LogDebug("Consultando agrupaciones para {Provincia} ({DistritoId}), Categoría: {CategoriaId}", provincia.Nombre, provincia.DistritoId, categoriaId);
var agrupacionesApi = await _apiService.GetAgrupacionesAsync(authToken, provincia.DistritoId, categoriaId);
if (agrupacionesApi != null)
{
foreach (var agrupacionDto in agrupacionesApi)
{
// Si la agrupación no está en nuestro diccionario, la añadimos.
if (!agrupacionesEnDb.ContainsKey(agrupacionDto.IdAgrupacion))
{
var nuevaAgrupacion = new AgrupacionPolitica
{
Id = agrupacionDto.IdAgrupacion,
IdTelegrama = agrupacionDto.IdAgrupacionTelegrama,
Nombre = agrupacionDto.NombreAgrupacion
};
dbContext.AgrupacionesPoliticas.Add(nuevaAgrupacion);
// La añadimos también al diccionario para no intentar agregarla de nuevo en este ciclo.
agrupacionesEnDb.Add(nuevaAgrupacion.Id, nuevaAgrupacion);
}
}
}
}
}
// Guardamos todos los cambios de agrupaciones al final, en una sola transacción.
int agrupacionesGuardadas = await dbContext.SaveChangesAsync(stoppingToken);
_logger.LogInformation("Catálogo de Agrupaciones Políticas sincronizado. Se guardaron {count} nuevos registros.", agrupacionesGuardadas);
_logger.LogInformation("Sincronización de catálogos maestros finalizada."); _logger.LogInformation("Sincronización de catálogos maestros finalizada.");
} }
catch (Exception ex) catch (Exception ex)