diff --git a/Elecciones-Web/src/Elecciones.Worker/LowPriorityDataWorker.cs b/Elecciones-Web/src/Elecciones.Worker/LowPriorityDataWorker.cs
index 3582405..68429bd 100644
--- a/Elecciones-Web/src/Elecciones.Worker/LowPriorityDataWorker.cs
+++ b/Elecciones-Web/src/Elecciones.Worker/LowPriorityDataWorker.cs
@@ -196,8 +196,7 @@ public class LowPriorityDataWorker : BackgroundService
///
/// 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.
- /// Utiliza una estrategia de guardado en lotes para manejar grandes volúmenes de datos
- /// sin sobrecargar la base de datos.
+ /// La sincronización de agrupaciones ahora itera por cada provincia para obtener listas completas.
///
/// El token de cancelación para detener la operación.
private async Task SincronizarCatalogosMaestrosAsync(CancellationToken stoppingToken)
@@ -215,7 +214,7 @@ public class LowPriorityDataWorker : BackgroundService
using var scope = _serviceProvider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService();
- // 1. SINCRONIZAR CATEGORÍAS
+ // --- PASO 1: SINCRONIZAR CATEGORÍAS ---
var categoriasApi = await _apiService.GetCategoriasAsync(authToken);
if (categoriasApi is null || !categoriasApi.Any())
{
@@ -234,38 +233,7 @@ public class LowPriorityDataWorker : BackgroundService
await dbContext.SaveChangesAsync(stoppingToken);
_logger.LogInformation("Catálogo de Categorías Electorales sincronizado.");
- // 2. SINCRONIZAR AGRUPACIONES POLÍTICAS
- _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
+ // --- PASO 2: SINCRONIZAR ÁMBITOS GEOGRÁFICOS ---
_logger.LogInformation("Iniciando sincronización de Ámbitos Geográficos...");
var ambitosEnDbKeys = new HashSet(
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)
{
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;
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);
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("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 { "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 { 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.");
}
catch (Exception ex)