Fix Captura de Datos Bancas
This commit is contained in:
		| @@ -109,15 +109,15 @@ public class CriticalDataWorker : BackgroundService | ||||
|           .Where(c => c.Nombre.Contains("SENADORES") || c.Nombre.Contains("DIPUTADOS")) | ||||
|           .ToListAsync(stoppingToken); | ||||
|  | ||||
|       var provincia = await dbContext.AmbitosGeograficos | ||||
|       // --- MODIFICACIÓN 1: Obtener todos los ámbitos en una sola consulta --- | ||||
|       var ambitosASondear = await dbContext.AmbitosGeograficos | ||||
|           .AsNoTracking() | ||||
|           .FirstOrDefaultAsync(a => a.NivelId == 10, stoppingToken); | ||||
|  | ||||
|       var seccionesElectorales = await dbContext.AmbitosGeograficos | ||||
|           .AsNoTracking() | ||||
|           .Where(a => a.NivelId == 20 && a.DistritoId != null && a.SeccionProvincialId != null) | ||||
|           .Where(a => (a.NivelId == 10 || a.NivelId == 20) && a.DistritoId != null) | ||||
|           .ToListAsync(stoppingToken); | ||||
|  | ||||
|       var provincia = ambitosASondear.FirstOrDefault(a => a.NivelId == 10); | ||||
|       var seccionesElectorales = ambitosASondear.Where(a => a.NivelId == 20).ToList(); | ||||
|  | ||||
|       if (!categoriasDeBancas.Any() || provincia == null) | ||||
|       { | ||||
|         _logger.LogWarning("No se encontraron categorías de bancas o el ámbito provincial en la BD. Omitiendo sondeo de bancas."); | ||||
| @@ -129,62 +129,29 @@ public class CriticalDataWorker : BackgroundService | ||||
|       var todasLasProyecciones = new List<ProyeccionBanca>(); | ||||
|       bool hasReceivedAnyNewData = false; | ||||
|  | ||||
|       // Bucle para el nivel Provincial | ||||
|       foreach (var categoria in categoriasDeBancas) | ||||
|       // --- MODIFICACIÓN 2: Usar un diccionario para no buscar repetidamente en la BD --- | ||||
|       var agrupacionesEnDb = await dbContext.AgrupacionesPoliticas.ToDictionaryAsync(a => a.Id, a => a, stoppingToken); | ||||
|  | ||||
|       // Bucle combinado para todos los ámbitos | ||||
|       foreach (var ambito in ambitosASondear) | ||||
|       { | ||||
|         if (stoppingToken.IsCancellationRequested) break; | ||||
|         var repartoBancasDto = await _apiService.GetBancasAsync(authToken, provincia.DistritoId!, null, categoria.Id); | ||||
|  | ||||
|         if (repartoBancasDto?.RepartoBancas is { Count: > 0 } bancas) | ||||
|         { | ||||
|           hasReceivedAnyNewData = true; | ||||
|  | ||||
|           // --- SEGURIDAD: Usar TryParse para la fecha --- | ||||
|           DateTime fechaTotalizacion; | ||||
|           if (!DateTime.TryParse(repartoBancasDto.FechaTotalizacion, out var parsedDate)) | ||||
|           { | ||||
|             // Si la fecha es inválida (nula, vacía, mal formada), lo registramos y usamos la hora actual como respaldo. | ||||
|             _logger.LogWarning("No se pudo parsear FechaTotalizacion ('{dateString}') para bancas provinciales. Usando la hora actual.", repartoBancasDto.FechaTotalizacion); | ||||
|             fechaTotalizacion = DateTime.UtcNow; | ||||
|           } | ||||
|           else | ||||
|           { | ||||
|             fechaTotalizacion = parsedDate.ToUniversalTime(); | ||||
|           } | ||||
|  | ||||
|           foreach (var banca in bancas) | ||||
|           { | ||||
|             todasLasProyecciones.Add(new ProyeccionBanca | ||||
|             { | ||||
|               EleccionId = EleccionId, | ||||
|               AmbitoGeograficoId = provincia.Id, | ||||
|               AgrupacionPoliticaId = banca.IdAgrupacion, | ||||
|               NroBancas = banca.NroBancas, | ||||
|               CategoriaId = categoria.Id, | ||||
|               FechaTotalizacion = fechaTotalizacion | ||||
|             }); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       // Bucle para el nivel de Sección Electoral | ||||
|       foreach (var seccion in seccionesElectorales) | ||||
|       { | ||||
|         if (stoppingToken.IsCancellationRequested) break; | ||||
|         foreach (var categoria in categoriasDeBancas) | ||||
|         { | ||||
|           if (stoppingToken.IsCancellationRequested) break; | ||||
|           var repartoBancasDto = await _apiService.GetBancasAsync(authToken, seccion.DistritoId!, seccion.SeccionProvincialId!, categoria.Id); | ||||
|  | ||||
|           // Llamada a la API (lógica adaptada para ambos niveles) | ||||
|           var repartoBancasDto = await _apiService.GetBancasAsync(authToken, ambito.DistritoId!, ambito.SeccionProvincialId, categoria.Id); | ||||
|  | ||||
|           if (repartoBancasDto?.RepartoBancas is { Count: > 0 } bancas) | ||||
|           { | ||||
|             hasReceivedAnyNewData = true; | ||||
|  | ||||
|             // --- APLICAMOS LA MISMA SEGURIDAD AQUÍ --- | ||||
|             DateTime fechaTotalizacion; | ||||
|             if (!DateTime.TryParse(repartoBancasDto.FechaTotalizacion, out var parsedDate)) | ||||
|             { | ||||
|               _logger.LogWarning("No se pudo parsear FechaTotalizacion ('{dateString}') para bancas de sección. Usando la hora actual.", repartoBancasDto.FechaTotalizacion); | ||||
|               _logger.LogWarning("No se pudo parsear FechaTotalizacion ('{dateString}') para bancas. Usando la hora actual.", repartoBancasDto.FechaTotalizacion); | ||||
|               fechaTotalizacion = DateTime.UtcNow; | ||||
|             } | ||||
|             else | ||||
| @@ -194,10 +161,26 @@ public class CriticalDataWorker : BackgroundService | ||||
|  | ||||
|             foreach (var banca in bancas) | ||||
|             { | ||||
|               // --- MODIFICACIÓN 3: Lógica de "Upsert" para Agrupaciones --- | ||||
|               if (!agrupacionesEnDb.ContainsKey(banca.IdAgrupacion)) | ||||
|               { | ||||
|                 _logger.LogWarning("Agrupación con ID {AgrupacionId} ('{Nombre}') no encontrada. Creándola desde los datos de bancas.", banca.IdAgrupacion, banca.NombreAgrupacion); | ||||
|  | ||||
|                 var nuevaAgrupacion = new AgrupacionPolitica | ||||
|                 { | ||||
|                   Id = banca.IdAgrupacion, | ||||
|                   Nombre = banca.NombreAgrupacion, | ||||
|                   IdTelegrama = banca.IdAgrupacionTelegrama ?? string.Empty | ||||
|                 }; | ||||
|  | ||||
|                 await dbContext.AgrupacionesPoliticas.AddAsync(nuevaAgrupacion, stoppingToken); | ||||
|                 agrupacionesEnDb.Add(nuevaAgrupacion.Id, nuevaAgrupacion); // Añadir al diccionario para no volver a crearla | ||||
|               } | ||||
|  | ||||
|               todasLasProyecciones.Add(new ProyeccionBanca | ||||
|               { | ||||
|                 EleccionId = EleccionId, | ||||
|                 AmbitoGeograficoId = seccion.Id, | ||||
|                 AmbitoGeograficoId = ambito.Id, | ||||
|                 AgrupacionPoliticaId = banca.IdAgrupacion, | ||||
|                 NroBancas = banca.NroBancas, | ||||
|                 CategoriaId = categoria.Id, | ||||
| @@ -213,6 +196,10 @@ public class CriticalDataWorker : BackgroundService | ||||
|         _logger.LogInformation("Se recibieron datos válidos de bancas. Procediendo a actualizar la base de datos..."); | ||||
|         await using var transaction = await dbContext.Database.BeginTransactionAsync(stoppingToken); | ||||
|  | ||||
|         // Si se crearon nuevas agrupaciones, se guardarán aquí primero. | ||||
|         await dbContext.SaveChangesAsync(stoppingToken); | ||||
|  | ||||
|         // Luego, procedemos con las proyecciones. | ||||
|         await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM ProyeccionesBancas", stoppingToken); | ||||
|         await dbContext.ProyeccionesBancas.AddRangeAsync(todasLasProyecciones, stoppingToken); | ||||
|         await dbContext.SaveChangesAsync(stoppingToken); | ||||
| @@ -222,7 +209,7 @@ public class CriticalDataWorker : BackgroundService | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|         _logger.LogInformation("Sondeo de Bancas completado. No se encontraron datos nuevos de proyección, la tabla no fue modificada."); | ||||
|         _logger.LogInformation("Sondeo de Bancas completado. No se encontraron datos nuevos, la tabla no fue modificada."); | ||||
|       } | ||||
|     } | ||||
|     catch (OperationCanceledException) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user