Feat Widgets Cards y Optimización de Consultas
This commit is contained in:
@@ -92,6 +92,36 @@ public class AdminController : ControllerBase
|
||||
return Ok();
|
||||
}
|
||||
|
||||
// --- ENDPOINTS PARA NACIONALES ---
|
||||
|
||||
[HttpPut("agrupaciones/orden-diputados-nacionales")]
|
||||
public async Task<IActionResult> UpdateDiputadosNacionalesOrden([FromBody] List<string> idsAgrupacionesOrdenadas)
|
||||
{
|
||||
await _dbContext.AgrupacionesPoliticas.ExecuteUpdateAsync(s => s.SetProperty(a => a.OrdenDiputadosNacionales, (int?)null));
|
||||
|
||||
for (int i = 0; i < idsAgrupacionesOrdenadas.Count; i++)
|
||||
{
|
||||
var agrupacion = await _dbContext.AgrupacionesPoliticas.FindAsync(idsAgrupacionesOrdenadas[i]);
|
||||
if (agrupacion != null) agrupacion.OrdenDiputadosNacionales = i + 1;
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPut("agrupaciones/orden-senadores-nacionales")]
|
||||
public async Task<IActionResult> UpdateSenadoresNacionalesOrden([FromBody] List<string> idsAgrupacionesOrdenadas)
|
||||
{
|
||||
await _dbContext.AgrupacionesPoliticas.ExecuteUpdateAsync(s => s.SetProperty(a => a.OrdenSenadoresNacionales, (int?)null));
|
||||
|
||||
for (int i = 0; i < idsAgrupacionesOrdenadas.Count; i++)
|
||||
{
|
||||
var agrupacion = await _dbContext.AgrupacionesPoliticas.FindAsync(idsAgrupacionesOrdenadas[i]);
|
||||
if (agrupacion != null) agrupacion.OrdenSenadoresNacionales = i + 1;
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
return Ok();
|
||||
}
|
||||
|
||||
// LEER todas las configuraciones
|
||||
[HttpGet("configuracion")]
|
||||
public async Task<IActionResult> GetConfiguracion()
|
||||
@@ -125,14 +155,15 @@ public class AdminController : ControllerBase
|
||||
|
||||
// LEER: Obtener todas las bancadas para una cámara, con su partido y ocupante actual
|
||||
[HttpGet("bancadas/{camara}")]
|
||||
public async Task<IActionResult> GetBancadas(TipoCamara camara)
|
||||
public async Task<IActionResult> GetBancadas(TipoCamara camara, [FromQuery] int eleccionId)
|
||||
{
|
||||
// 3. La lógica interna se mantiene igual, ya que filtra por ambos parámetros.
|
||||
var bancadas = await _dbContext.Bancadas
|
||||
.AsNoTracking()
|
||||
.Include(b => b.AgrupacionPolitica)
|
||||
.Include(b => b.Ocupante)
|
||||
.Where(b => b.Camara == camara)
|
||||
.OrderBy(b => b.Id) // Ordenar por ID para consistencia
|
||||
.Where(b => b.EleccionId == eleccionId && b.Camara == camara)
|
||||
.OrderBy(b => b.NumeroBanca)
|
||||
.ToListAsync();
|
||||
|
||||
return Ok(bancadas);
|
||||
@@ -181,10 +212,39 @@ public class AdminController : ControllerBase
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpGet("logos")]
|
||||
public async Task<IActionResult> GetLogos()
|
||||
[HttpGet("catalogos/provincias")]
|
||||
public async Task<IActionResult> GetProvinciasForAdmin()
|
||||
{
|
||||
return Ok(await _dbContext.LogosAgrupacionesCategorias.AsNoTracking().ToListAsync());
|
||||
var provincias = await _dbContext.AmbitosGeograficos
|
||||
.AsNoTracking()
|
||||
.Where(a => a.NivelId == 10) // Nivel 10 = Provincia
|
||||
.OrderBy(a => a.Nombre)
|
||||
.Select(a => new { Id = a.Id.ToString(), Nombre = a.Nombre })
|
||||
.ToListAsync();
|
||||
return Ok(provincias);
|
||||
}
|
||||
|
||||
// --- ENDPOINTS MODIFICADOS ---
|
||||
|
||||
[HttpGet("logos")]
|
||||
public async Task<IActionResult> GetLogos([FromQuery] int eleccionId)
|
||||
{
|
||||
// Añadimos el filtro por EleccionId
|
||||
return Ok(await _dbContext.LogosAgrupacionesCategorias
|
||||
.AsNoTracking()
|
||||
.Where(l => l.EleccionId == eleccionId)
|
||||
.ToListAsync());
|
||||
}
|
||||
|
||||
[HttpGet("candidatos")]
|
||||
public async Task<IActionResult> GetCandidatos([FromQuery] int eleccionId)
|
||||
{
|
||||
// Añadimos el filtro por EleccionId
|
||||
var candidatos = await _dbContext.CandidatosOverrides
|
||||
.AsNoTracking()
|
||||
.Where(c => c.EleccionId == eleccionId)
|
||||
.ToListAsync();
|
||||
return Ok(candidatos);
|
||||
}
|
||||
|
||||
[HttpPut("logos")]
|
||||
@@ -239,18 +299,6 @@ public class AdminController : ControllerBase
|
||||
return Ok(municipios);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Obtiene todos los overrides de candidatos configurados.
|
||||
/// </summary>
|
||||
[HttpGet("candidatos")]
|
||||
public async Task<IActionResult> GetCandidatos()
|
||||
{
|
||||
var candidatos = await _dbContext.CandidatosOverrides
|
||||
.AsNoTracking()
|
||||
.ToListAsync();
|
||||
return Ok(candidatos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Guarda (actualiza o crea) una lista de overrides de candidatos.
|
||||
/// </summary>
|
||||
@@ -337,4 +385,40 @@ public class AdminController : ControllerBase
|
||||
_logger.LogWarning("El nivel de logging ha sido cambiado a: {Level}", request.Level);
|
||||
return Ok(new { message = $"Nivel de logging actualizado a '{request.Level}'." });
|
||||
}
|
||||
|
||||
// LEER todas las bancas previas para una elección
|
||||
[HttpGet("bancas-previas/{eleccionId}")]
|
||||
public async Task<IActionResult> GetBancasPrevias(int eleccionId)
|
||||
{
|
||||
var bancas = await _dbContext.BancasPrevias
|
||||
.AsNoTracking()
|
||||
.Where(b => b.EleccionId == eleccionId)
|
||||
.Include(b => b.AgrupacionPolitica)
|
||||
.ToListAsync();
|
||||
return Ok(bancas);
|
||||
}
|
||||
|
||||
// GUARDAR (Upsert) una lista de bancas previas
|
||||
[HttpPut("bancas-previas/{eleccionId}")]
|
||||
public async Task<IActionResult> UpdateBancasPrevias(int eleccionId, [FromBody] List<BancaPrevia> bancas)
|
||||
{
|
||||
// Borramos los registros existentes para esta elección para simplificar la lógica
|
||||
await _dbContext.BancasPrevias.Where(b => b.EleccionId == eleccionId).ExecuteDeleteAsync();
|
||||
|
||||
// Añadimos los nuevos registros que tienen al menos una banca
|
||||
foreach (var banca in bancas.Where(b => b.Cantidad > 0))
|
||||
{
|
||||
_dbContext.BancasPrevias.Add(new BancaPrevia
|
||||
{
|
||||
EleccionId = eleccionId,
|
||||
Camara = banca.Camara,
|
||||
AgrupacionPoliticaId = banca.AgrupacionPoliticaId,
|
||||
Cantidad = banca.Cantidad
|
||||
});
|
||||
}
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
_logger.LogInformation("Se actualizaron las bancas previas para la EleccionId: {EleccionId}", eleccionId);
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
@@ -1208,13 +1208,16 @@ public class ResultadosController : ControllerBase
|
||||
|
||||
[HttpGet("mapa-resultados")]
|
||||
public async Task<IActionResult> GetResultadosMapaPorMunicipio(
|
||||
[FromRoute] int eleccionId,
|
||||
[FromQuery] int categoriaId,
|
||||
[FromQuery] string? distritoId = null)
|
||||
[FromRoute] int eleccionId,
|
||||
[FromQuery] int categoriaId,
|
||||
[FromQuery] string? distritoId = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(distritoId))
|
||||
{
|
||||
// --- VISTA NACIONAL (Ya corregida y funcionando) ---
|
||||
// --- VISTA NACIONAL (LÓGICA CORRECTA Y ROBUSTA) ---
|
||||
|
||||
// PASO 1: Agrupar y sumar los votos por provincia y partido directamente en la BD.
|
||||
// Esto crea una lista con los totales, que es mucho más pequeña que los datos crudos.
|
||||
var votosAgregadosPorProvincia = await _dbContext.ResultadosVotos
|
||||
.AsNoTracking()
|
||||
.Where(r => r.EleccionId == eleccionId
|
||||
@@ -1224,23 +1227,26 @@ public class ResultadosController : ControllerBase
|
||||
.GroupBy(r => new { r.AmbitoGeografico.DistritoId, r.AgrupacionPoliticaId })
|
||||
.Select(g => new
|
||||
{
|
||||
g.Key.DistritoId,
|
||||
g.Key.AgrupacionPoliticaId,
|
||||
DistritoId = g.Key.DistritoId!, // Sabemos que no es nulo por el .Where()
|
||||
AgrupacionPoliticaId = g.Key.AgrupacionPoliticaId,
|
||||
TotalVotos = g.Sum(r => r.CantidadVotos)
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
var agrupacionesInfo = await _dbContext.AgrupacionesPoliticas.AsNoTracking().ToDictionaryAsync(a => a.Id);
|
||||
var provinciasInfo = await _dbContext.AmbitosGeograficos.AsNoTracking().Where(a => a.NivelId == 10).ToListAsync();
|
||||
|
||||
// PASO 2: Encontrar el ganador para cada provincia en la memoria de la aplicación.
|
||||
// Esto es muy rápido porque se hace sobre la lista ya agregada.
|
||||
var ganadoresPorProvincia = votosAgregadosPorProvincia
|
||||
.GroupBy(r => r.DistritoId)
|
||||
.Select(g => g.OrderByDescending(x => x.TotalVotos).First())
|
||||
.ToList();
|
||||
|
||||
// PASO 3: Obtener los datos adicionales (nombres, colores) para construir la respuesta final.
|
||||
var agrupacionesInfo = await _dbContext.AgrupacionesPoliticas.AsNoTracking().ToDictionaryAsync(a => a.Id);
|
||||
var provinciasInfo = await _dbContext.AmbitosGeograficos.AsNoTracking().Where(a => a.NivelId == 10).ToListAsync();
|
||||
|
||||
var mapaDataNacional = ganadoresPorProvincia.Select(g => new ResultadoMapaDto
|
||||
{
|
||||
AmbitoId = g.DistritoId!,
|
||||
AmbitoId = g.DistritoId,
|
||||
AmbitoNombre = provinciasInfo.FirstOrDefault(p => p.DistritoId == g.DistritoId)?.Nombre ?? "Desconocido",
|
||||
AgrupacionGanadoraId = g.AgrupacionPoliticaId,
|
||||
ColorGanador = agrupacionesInfo.GetValueOrDefault(g.AgrupacionPoliticaId)?.Color ?? "#808080"
|
||||
@@ -1250,16 +1256,13 @@ public class ResultadosController : ControllerBase
|
||||
}
|
||||
else
|
||||
{
|
||||
// --- VISTA PROVINCIAL (AHORA CORREGIDA CON LA MISMA LÓGICA) ---
|
||||
|
||||
// PASO 1: Agrupar por IDs y sumar votos en la base de datos.
|
||||
// --- VISTA PROVINCIAL (SIN CAMBIOS, YA ERA EFICIENTE) ---
|
||||
var votosAgregadosPorMunicipio = await _dbContext.ResultadosVotos
|
||||
.AsNoTracking()
|
||||
.Where(r => r.EleccionId == eleccionId
|
||||
&& r.CategoriaId == categoriaId
|
||||
&& r.AmbitoGeografico.DistritoId == distritoId
|
||||
&& r.AmbitoGeografico.NivelId == 30)
|
||||
// Agrupamos por los IDs (int y string)
|
||||
.GroupBy(r => new { r.AmbitoGeograficoId, r.AgrupacionPoliticaId })
|
||||
.Select(g => new
|
||||
{
|
||||
@@ -1269,13 +1272,11 @@ public class ResultadosController : ControllerBase
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
// PASO 2: Encontrar el ganador para cada municipio en memoria.
|
||||
var ganadoresPorMunicipio = votosAgregadosPorMunicipio
|
||||
.GroupBy(r => r.AmbitoGeograficoId)
|
||||
.Select(g => g.OrderByDescending(x => x.TotalVotos).First())
|
||||
.ToList();
|
||||
|
||||
// PASO 3: Hidratar con los nombres y colores (muy rápido).
|
||||
var idsMunicipios = ganadoresPorMunicipio.Select(g => g.AmbitoGeograficoId).ToList();
|
||||
var idsAgrupaciones = ganadoresPorMunicipio.Select(g => g.AgrupacionPoliticaId).ToList();
|
||||
|
||||
@@ -1285,7 +1286,6 @@ public class ResultadosController : ControllerBase
|
||||
var agrupacionesInfo = await _dbContext.AgrupacionesPoliticas.AsNoTracking()
|
||||
.Where(a => idsAgrupaciones.Contains(a.Id)).ToDictionaryAsync(a => a.Id);
|
||||
|
||||
// Mapeo final a DTO.
|
||||
var mapaDataProvincial = ganadoresPorMunicipio.Select(g => new ResultadoMapaDto
|
||||
{
|
||||
AmbitoId = g.AmbitoGeograficoId.ToString(),
|
||||
@@ -1297,4 +1297,193 @@ public class ResultadosController : ControllerBase
|
||||
return Ok(mapaDataProvincial);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("composicion-nacional")]
|
||||
public async Task<IActionResult> GetComposicionNacional([FromRoute] int eleccionId)
|
||||
{
|
||||
// 1. Obtener todas las configuraciones relevantes en una sola consulta.
|
||||
var config = await _dbContext.Configuraciones.AsNoTracking().ToDictionaryAsync(c => c.Clave, c => c.Valor);
|
||||
|
||||
// 2. Obtener todas las agrupaciones políticas en una sola consulta.
|
||||
var todasAgrupaciones = await _dbContext.AgrupacionesPoliticas.AsNoTracking().ToDictionaryAsync(a => a.Id);
|
||||
|
||||
// 3. Obtener las bancas PREVIAS (las que no están en juego).
|
||||
var bancasPrevias = await _dbContext.BancasPrevias
|
||||
.AsNoTracking()
|
||||
.Where(b => b.EleccionId == eleccionId)
|
||||
.ToListAsync();
|
||||
|
||||
// 4. Obtener las bancas EN JUEGO (proyectadas por provincia).
|
||||
var proyecciones = await _dbContext.ProyeccionesBancas
|
||||
.AsNoTracking()
|
||||
.Where(p => p.EleccionId == eleccionId && p.AmbitoGeografico.NivelId == 10) // Nivel 10 = Ámbito Provincial
|
||||
.ToListAsync();
|
||||
|
||||
//Calculamos la fecha de la última proyección.
|
||||
// Si no hay proyecciones aún, usamos la fecha y hora actual como un fallback seguro.
|
||||
var ultimaActualizacion = proyecciones.Any()
|
||||
? proyecciones.Max(p => p.FechaTotalizacion)
|
||||
: DateTime.UtcNow;
|
||||
|
||||
// 5. Combinar los datos para obtener la composición final de cada partido.
|
||||
var composicionFinal = todasAgrupaciones.Values.Select(agrupacion => new
|
||||
{
|
||||
Agrupacion = agrupacion,
|
||||
DiputadosFijos = bancasPrevias.FirstOrDefault(b => b.AgrupacionPoliticaId == agrupacion.Id && b.Camara == Core.Enums.TipoCamara.Diputados)?.Cantidad ?? 0,
|
||||
DiputadosGanados = proyecciones.Where(p => p.AgrupacionPoliticaId == agrupacion.Id && p.CategoriaId == 2).Sum(p => p.NroBancas),
|
||||
SenadoresFijos = bancasPrevias.FirstOrDefault(b => b.AgrupacionPoliticaId == agrupacion.Id && b.Camara == Core.Enums.TipoCamara.Senadores)?.Cantidad ?? 0,
|
||||
SenadoresGanados = proyecciones.Where(p => p.AgrupacionPoliticaId == agrupacion.Id && p.CategoriaId == 1).Sum(p => p.NroBancas)
|
||||
})
|
||||
.Select(r => new
|
||||
{
|
||||
r.Agrupacion,
|
||||
r.DiputadosFijos,
|
||||
r.DiputadosGanados,
|
||||
DiputadosTotales = r.DiputadosFijos + r.DiputadosGanados,
|
||||
r.SenadoresFijos,
|
||||
r.SenadoresGanados,
|
||||
SenadoresTotales = r.SenadoresFijos + r.SenadoresGanados
|
||||
})
|
||||
.ToList();
|
||||
|
||||
// 6. Determinar la información de la presidencia para cada cámara.
|
||||
config.TryGetValue("PresidenciaDiputadosNacional", out var idPartidoPresDip);
|
||||
var partidoPresidenteDiputados = !string.IsNullOrEmpty(idPartidoPresDip) ? todasAgrupaciones.GetValueOrDefault(idPartidoPresDip) : null;
|
||||
config.TryGetValue("PresidenciaDiputadosNacional_TipoBanca", out var tipoBancaDip);
|
||||
|
||||
config.TryGetValue("PresidenciaSenadoNacional", out var idPartidoPresSen);
|
||||
var partidoPresidenteSenadores = !string.IsNullOrEmpty(idPartidoPresSen) ? todasAgrupaciones.GetValueOrDefault(idPartidoPresSen) : null;
|
||||
config.TryGetValue("PresidenciaSenadoNacional_TipoBanca", out var tipoBancaSen);
|
||||
|
||||
|
||||
// 7. Construir el objeto de respuesta final para D Diputados
|
||||
var diputados = new
|
||||
{
|
||||
CamaraNombre = "Cámara de Diputados",
|
||||
TotalBancas = 257,
|
||||
BancasEnJuego = 127,
|
||||
UltimaActualizacion = ultimaActualizacion,
|
||||
Partidos = composicionFinal
|
||||
.Where(p => p.DiputadosTotales > 0)
|
||||
.OrderByDescending(p => p.DiputadosTotales)
|
||||
.Select(p => new
|
||||
{
|
||||
p.Agrupacion.Id,
|
||||
p.Agrupacion.Nombre,
|
||||
p.Agrupacion.NombreCorto,
|
||||
p.Agrupacion.Color,
|
||||
BancasFijos = p.DiputadosFijos,
|
||||
BancasGanadas = p.DiputadosGanados,
|
||||
BancasTotales = p.DiputadosTotales,
|
||||
p.Agrupacion.OrdenDiputadosNacionales,
|
||||
p.Agrupacion.OrdenSenadoresNacionales
|
||||
}).ToList(),
|
||||
PresidenteBancada = partidoPresidenteDiputados != null
|
||||
? new { Color = partidoPresidenteDiputados.Color, TipoBanca = tipoBancaDip ?? "ganada" }
|
||||
: null
|
||||
};
|
||||
|
||||
// 8. Construir el objeto de respuesta final para Senadores
|
||||
var senadores = new
|
||||
{
|
||||
CamaraNombre = "Senado de la Nación",
|
||||
TotalBancas = 72,
|
||||
BancasEnJuego = 24,
|
||||
UltimaActualizacion = ultimaActualizacion,
|
||||
Partidos = composicionFinal
|
||||
.Where(p => p.SenadoresTotales > 0)
|
||||
.OrderByDescending(p => p.SenadoresTotales)
|
||||
.Select(p => new
|
||||
{
|
||||
p.Agrupacion.Id,
|
||||
p.Agrupacion.Nombre,
|
||||
p.Agrupacion.NombreCorto,
|
||||
p.Agrupacion.Color,
|
||||
BancasFijos = p.SenadoresFijos,
|
||||
BancasGanadas = p.SenadoresGanados,
|
||||
BancasTotales = p.SenadoresTotales,
|
||||
p.Agrupacion.OrdenDiputadosNacionales,
|
||||
p.Agrupacion.OrdenSenadoresNacionales
|
||||
}).ToList(),
|
||||
PresidenteBancada = partidoPresidenteSenadores != null
|
||||
? new { Color = partidoPresidenteSenadores.Color, TipoBanca = tipoBancaSen ?? "ganada" }
|
||||
: null
|
||||
};
|
||||
|
||||
return Ok(new { Diputados = diputados, Senadores = senadores });
|
||||
}
|
||||
|
||||
[HttpGet("resumen-por-provincia")]
|
||||
public async Task<IActionResult> GetResumenPorProvincia([FromRoute] int eleccionId)
|
||||
{
|
||||
const int categoriaDiputadosNacionales = 2;
|
||||
|
||||
var todasLasProyecciones = await _dbContext.ProyeccionesBancas.AsNoTracking()
|
||||
.Where(p => p.EleccionId == eleccionId && p.CategoriaId == categoriaDiputadosNacionales)
|
||||
.ToDictionaryAsync(p => p.AmbitoGeograficoId + "_" + p.AgrupacionPoliticaId);
|
||||
|
||||
var todosLosOverrides = await _dbContext.CandidatosOverrides.AsNoTracking()
|
||||
.Where(c => c.EleccionId == eleccionId && c.CategoriaId == categoriaDiputadosNacionales)
|
||||
.ToListAsync();
|
||||
|
||||
var todosLosLogos = await _dbContext.LogosAgrupacionesCategorias.AsNoTracking()
|
||||
.Where(l => l.EleccionId == eleccionId && l.CategoriaId == categoriaDiputadosNacionales)
|
||||
.ToListAsync();
|
||||
|
||||
var datosBrutos = await _dbContext.AmbitosGeograficos.AsNoTracking()
|
||||
.Where(a => a.NivelId == 10)
|
||||
.Select(provincia => new
|
||||
{
|
||||
ProvinciaAmbitoId = provincia.Id,
|
||||
ProvinciaDistritoId = provincia.DistritoId!,
|
||||
ProvinciaNombre = provincia.Nombre,
|
||||
EstadoRecuento = _dbContext.EstadosRecuentosGenerales
|
||||
.Where(e => e.EleccionId == eleccionId && e.CategoriaId == categoriaDiputadosNacionales && e.AmbitoGeograficoId == provincia.Id)
|
||||
.Select(e => new EstadoRecuentoDto { /* ... */ })
|
||||
.FirstOrDefault(),
|
||||
ResultadosBrutos = _dbContext.ResultadosVotos
|
||||
.Where(r => r.EleccionId == eleccionId && r.CategoriaId == categoriaDiputadosNacionales && r.AmbitoGeografico.DistritoId == provincia.DistritoId)
|
||||
.GroupBy(r => r.AgrupacionPolitica)
|
||||
.Select(g => new { Agrupacion = g.Key, Votos = g.Sum(r => r.CantidadVotos) })
|
||||
.OrderByDescending(x => x.Votos)
|
||||
.Take(2)
|
||||
.ToList()
|
||||
})
|
||||
.OrderBy(p => p.ProvinciaNombre)
|
||||
.ToListAsync();
|
||||
|
||||
var resultadosFinales = datosBrutos.Select(provinciaData =>
|
||||
{
|
||||
var totalVotosProvincia = (decimal)provinciaData.ResultadosBrutos.Sum(r => r.Votos);
|
||||
return new ResumenProvinciaDto
|
||||
{
|
||||
ProvinciaId = provinciaData.ProvinciaDistritoId,
|
||||
ProvinciaNombre = provinciaData.ProvinciaNombre,
|
||||
EstadoRecuento = provinciaData.EstadoRecuento,
|
||||
Resultados = provinciaData.ResultadosBrutos.Select(r =>
|
||||
{
|
||||
var provinciaAmbitoId = provinciaData.ProvinciaAmbitoId;
|
||||
return new ResultadoCandidatoDto
|
||||
{
|
||||
AgrupacionId = r.Agrupacion.Id,
|
||||
NombreAgrupacion = r.Agrupacion.NombreCorto ?? r.Agrupacion.Nombre,
|
||||
Color = r.Agrupacion.Color,
|
||||
Votos = r.Votos,
|
||||
NombreCandidato = (todosLosOverrides.FirstOrDefault(c => c.AgrupacionPoliticaId == r.Agrupacion.Id && c.AmbitoGeograficoId == provinciaAmbitoId)
|
||||
?? todosLosOverrides.FirstOrDefault(c => c.AgrupacionPoliticaId == r.Agrupacion.Id && c.AmbitoGeograficoId == null))
|
||||
?.NombreCandidato,
|
||||
FotoUrl = (todosLosLogos.FirstOrDefault(l => l.AgrupacionPoliticaId == r.Agrupacion.Id && l.AmbitoGeograficoId == provinciaAmbitoId)
|
||||
?? todosLosLogos.FirstOrDefault(l => l.AgrupacionPoliticaId == r.Agrupacion.Id && l.AmbitoGeograficoId == null))
|
||||
?.LogoUrl,
|
||||
BancasObtenidas = todasLasProyecciones.ContainsKey(provinciaAmbitoId + "_" + r.Agrupacion.Id)
|
||||
? todasLasProyecciones[provinciaAmbitoId + "_" + r.Agrupacion.Id].NroBancas
|
||||
: 0,
|
||||
Porcentaje = totalVotosProvincia > 0 ? (r.Votos / totalVotosProvincia) * 100 : 0
|
||||
};
|
||||
}).ToList()
|
||||
};
|
||||
}).ToList();
|
||||
|
||||
return Ok(resultadosFinales);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user