Fix Iteración por Provincias en Catálogo Maestro
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user