Fix Añade FechaTotalizado en Proyeccion Bancas

This commit is contained in:
2025-08-23 12:54:57 -03:00
parent 303a469c57
commit 13c6accd15
11 changed files with 453 additions and 47 deletions

View File

@@ -239,26 +239,10 @@ public class LowPriorityDataWorker : BackgroundService
/// <summary>
/// Sondea la proyección de bancas. Este método ahora es más completo:
/// 1. Consulta el reparto de bancas a nivel PROVINCIAL para cada categoría.
/// 2. Consulta el reparto de bancas desglosado por SECCIÓN ELECTORAL para cada categoría.
/// </summary>
/// <summary>
/// Sondea la proyección de bancas a nivel Provincial y por Sección Electoral.
/// Esta versión recolecta todos los datos disponibles y los guarda en una única transacción.
/// </summary>
/// <summary>
/// Sondea la proyección de bancas a nivel Provincial y por Sección Electoral.
/// Esta versión incluye logging detallado para diagnosticar problemas de deserialización
/// o respuestas inesperadas de la API, y guarda los datos en una transacción atómica.
/// </summary>
/// <param name="authToken">El token de autenticación válido para la sesión.</param>
/// <param name="stoppingToken">El token de cancelación para detener la operación.</param>
/// <summary>
/// Sondea la proyección de bancas a nivel Provincial y por Sección Electoral.
/// Esta versión guarda la CategoriaId junto con cada proyección para poder distinguir
/// entre diferentes elecciones (ej. Senadores vs. Diputados).
/// Esta versión es completamente robusta: maneja respuestas de API vacías o con fechas mal formadas,
/// guarda la CategoriaId y usa una transacción atómica para la escritura en base de datos.
/// </summary>
/// <param name="authToken">El token de autenticación válido para la sesión.</param>
/// <param name="stoppingToken">El token de cancelación para detener la operación.</param>
@@ -266,30 +250,23 @@ public class LowPriorityDataWorker : BackgroundService
{
try
{
// Usamos un scope de DbContext para esta operación, asegurando una conexión limpia.
using var scope = _serviceProvider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<EleccionesDbContext>();
// 1. OBTENER DATOS DE CONFIGURACIÓN DE NUESTRA BD
// Buscamos las categorías que reparten bancas (Senadores y Diputados).
var categoriasDeBancas = await dbContext.CategoriasElectorales
.AsNoTracking()
.Where(c => c.Nombre.Contains("SENADORES") || c.Nombre.Contains("DIPUTADOS"))
.ToListAsync(stoppingToken);
// Obtenemos el registro de la Provincia para hacer la consulta a nivel provincial.
var provincia = await dbContext.AmbitosGeograficos
.AsNoTracking()
.FirstOrDefaultAsync(a => a.NivelId == 10, stoppingToken);
// Obtenemos todas las Secciones Electorales para hacer las consultas por sección.
var seccionesElectorales = await dbContext.AmbitosGeograficos
.AsNoTracking()
.Where(a => a.NivelId == 20 && a.DistritoId != null && a.SeccionProvincialId != null)
.ToListAsync(stoppingToken);
// Si falta alguna configuración base, no podemos continuar.
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.");
@@ -298,25 +275,32 @@ public class LowPriorityDataWorker : BackgroundService
_logger.LogInformation("Iniciando sondeo de Bancas a nivel Provincial y para {count} Secciones Electorales...", seccionesElectorales.Count);
// 2. RECOLECTAR DATOS DE LA API
// Una lista para acumular todas las proyecciones que encontremos.
var todasLasProyecciones = new List<ProyeccionBanca>();
// Una bandera para saber si hemos recibido al menos una banca con datos.
bool hasReceivedAnyNewData = false;
// Bucle para el nivel Provincial
foreach (var categoria in categoriasDeBancas)
{
if (stoppingToken.IsCancellationRequested) break;
var repartoBancasDto = await _apiService.GetBancasAsync(authToken, provincia.DistritoId!, null, categoria.Id);
var repartoBancas = await _apiService.GetBancasAsync(authToken, provincia.DistritoId!, null, categoria.Id);
if (repartoBancas?.RepartoBancas is { Count: > 0 } bancas)
if (repartoBancasDto?.RepartoBancas is { Count: > 0 } bancas)
{
_logger.LogInformation("Se encontraron {count} registros de bancas a nivel provincial para la categoría {catId}.", bancas.Count, categoria.Id);
hasReceivedAnyNewData = true;
// --- CORRECCIÓN DE 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
@@ -324,7 +308,8 @@ public class LowPriorityDataWorker : BackgroundService
AmbitoGeograficoId = provincia.Id,
AgrupacionPoliticaId = banca.IdAgrupacion,
NroBancas = banca.NroBancas,
CategoriaId = categoria.Id // <-- CORRECCIÓN: Se guarda la CategoriaId
CategoriaId = categoria.Id,
FechaTotalizacion = fechaTotalizacion
});
}
}
@@ -337,11 +322,24 @@ public class LowPriorityDataWorker : BackgroundService
foreach (var categoria in categoriasDeBancas)
{
if (stoppingToken.IsCancellationRequested) break;
var repartoBancas = await _apiService.GetBancasAsync(authToken, seccion.DistritoId!, seccion.SeccionProvincialId!, categoria.Id);
var repartoBancasDto = await _apiService.GetBancasAsync(authToken, seccion.DistritoId!, seccion.SeccionProvincialId!, categoria.Id);
if (repartoBancas?.RepartoBancas is { Count: > 0 } bancas)
if (repartoBancasDto?.RepartoBancas is { Count: > 0 } bancas)
{
hasReceivedAnyNewData = true;
// --- APLICAMOS LA MISMA CORRECCIÓN DE 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);
fechaTotalizacion = DateTime.UtcNow;
}
else
{
fechaTotalizacion = parsedDate.ToUniversalTime();
}
foreach (var banca in bancas)
{
todasLasProyecciones.Add(new ProyeccionBanca
@@ -349,20 +347,17 @@ public class LowPriorityDataWorker : BackgroundService
AmbitoGeograficoId = seccion.Id,
AgrupacionPoliticaId = banca.IdAgrupacion,
NroBancas = banca.NroBancas,
CategoriaId = categoria.Id // <-- CORRECCIÓN: Se guarda la CategoriaId
CategoriaId = categoria.Id,
FechaTotalizacion = fechaTotalizacion
});
}
}
}
}
// 3. GUARDAR DATOS EN LA BASE DE DATOS
// Solo procedemos a escribir en la BD si la bandera se activó.
if (hasReceivedAnyNewData)
{
_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);
await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM ProyeccionesBancas", stoppingToken);