Test Public Side
This commit is contained in:
		| @@ -63,21 +63,40 @@ public class CatalogosController : ControllerBase | ||||
|     } | ||||
|  | ||||
|     [HttpGet("secciones-electorales")] | ||||
|     public async Task<IActionResult> GetSeccionesElectorales() | ||||
|     public async Task<IActionResult> GetSeccionesElectorales([FromQuery] int? categoriaId) | ||||
|     { | ||||
|         var secciones = await _dbContext.AmbitosGeograficos | ||||
|         var seccionesQuery = _dbContext.AmbitosGeograficos | ||||
|             .AsNoTracking() | ||||
|             // Buscamos los ámbitos que son Secciones Electorales (Nivel 20) | ||||
|             .Where(a => a.NivelId == 20 && a.SeccionProvincialId != null) | ||||
|             .Select(a => new MunicipioSimpleDto // Reutilizamos el DTO porque tiene la misma estructura {Id, Nombre} | ||||
|             { | ||||
|                 Id = a.SeccionProvincialId!, // El ID que usaremos es el SeccionProvincialId | ||||
|                 Nombre = a.Nombre | ||||
|             }) | ||||
|             .OrderBy(s => s.Nombre) | ||||
|             .Where(a => a.NivelId == 20); // Nivel 20 = Sección Electoral | ||||
|  | ||||
|         // Si NO se proporciona una categoriaId, devolvemos todas las secciones. | ||||
|         if (categoriaId == null) | ||||
|         { | ||||
|             var todasLasSecciones = await seccionesQuery | ||||
|                 .OrderBy(a => a.Nombre) | ||||
|                 .Select(a => new { Id = a.SeccionProvincialId, a.Nombre }) | ||||
|                 .ToListAsync(); | ||||
|             return Ok(todasLasSecciones); | ||||
|         } | ||||
|  | ||||
|         // --- LÓGICA DE FILTRADO --- | ||||
|         // 1. Encontrar las Secciones Provinciales que SÍ tienen resultados para la categoría solicitada. | ||||
|         //    Usamos ProyeccionesBancas como fuente de verdad, ya que es el dato más relevante. | ||||
|         var seccionesActivasIds = await _dbContext.ProyeccionesBancas | ||||
|             .AsNoTracking() | ||||
|             .Where(p => p.CategoriaId == categoriaId) | ||||
|             .Select(p => p.AmbitoGeografico.SeccionProvincialId) | ||||
|             .Distinct() | ||||
|             .ToListAsync(); | ||||
|  | ||||
|         return Ok(secciones); | ||||
|         // 2. Filtramos la lista de secciones. | ||||
|         var seccionesFiltradas = await seccionesQuery | ||||
|             .Where(s => seccionesActivasIds.Contains(s.SeccionProvincialId)) | ||||
|             .OrderBy(a => a.Nombre) | ||||
|             .Select(a => new { Id = a.SeccionProvincialId, a.Nombre }) | ||||
|             .ToListAsync(); | ||||
|  | ||||
|         return Ok(seccionesFiltradas); | ||||
|     } | ||||
|  | ||||
|     // Nivel 20: Sección Electoral | ||||
|   | ||||
| @@ -531,8 +531,8 @@ public class ResultadosController : ControllerBase | ||||
|         return Ok(configuracionPublica); | ||||
|     } | ||||
|  | ||||
|     [HttpGet("concejales/{seccionId}")] | ||||
|     public async Task<IActionResult> GetResultadosConcejalesPorSeccion(string seccionId) | ||||
|     [HttpGet("seccion-resultados/{seccionId}")] | ||||
|     public async Task<IActionResult> GetResultadosAgregadosPorSeccion(string seccionId, [FromQuery] int categoriaId) | ||||
|     { | ||||
|         var municipiosDeLaSeccion = await _dbContext.AmbitosGeograficos | ||||
|             .AsNoTracking() | ||||
| @@ -548,40 +548,51 @@ public class ResultadosController : ControllerBase | ||||
|         var resultadosMunicipales = await _dbContext.ResultadosVotos | ||||
|             .AsNoTracking() | ||||
|             .Include(r => r.AgrupacionPolitica) | ||||
|             .Where(r => r.CategoriaId == 7 && municipiosDeLaSeccion.Contains(r.AmbitoGeograficoId)) | ||||
|             // Usamos la categoriaId del parámetro | ||||
|             .Where(r => r.CategoriaId == categoriaId && municipiosDeLaSeccion.Contains(r.AmbitoGeograficoId)) | ||||
|             .ToListAsync(); | ||||
|  | ||||
|         var logosConcejales = await _dbContext.LogosAgrupacionesCategorias | ||||
|         var logos = await _dbContext.LogosAgrupacionesCategorias | ||||
|             .AsNoTracking() | ||||
|             .Where(l => l.CategoriaId == 7) | ||||
|             // Usamos la categoriaId del parámetro | ||||
|             .Where(l => l.CategoriaId == categoriaId) | ||||
|             .ToDictionaryAsync(l => l.AgrupacionPoliticaId); | ||||
|  | ||||
|         var totalVotosSeccion = (decimal)resultadosMunicipales.Sum(r => r.CantidadVotos); | ||||
|  | ||||
|         var resultadosFinales = resultadosMunicipales | ||||
|             // 1. Agrupamos por el ID del partido para evitar duplicados. | ||||
|             .GroupBy(r => r.AgrupacionPoliticaId) | ||||
|             .Select(g => new | ||||
|             { | ||||
|                 // 2. Obtenemos la entidad completa del primer elemento del grupo. | ||||
|                 Agrupacion = g.First().AgrupacionPolitica, | ||||
|                 Votos = g.Sum(r => r.CantidadVotos) | ||||
|             }) | ||||
|             .OrderByDescending(r => r.Votos) | ||||
|             .Select(r => new | ||||
|             { | ||||
|                 Id = r.Agrupacion.Id, // Aseguramos que el Id esté en el objeto final | ||||
|                 Id = r.Agrupacion.Id, | ||||
|                 r.Agrupacion.Nombre, | ||||
|                 r.Agrupacion.NombreCorto, | ||||
|                 r.Agrupacion.Color, | ||||
|                 LogoUrl = logosConcejales.GetValueOrDefault(r.Agrupacion.Id)?.LogoUrl, | ||||
|                 LogoUrl = logos.GetValueOrDefault(r.Agrupacion.Id)?.LogoUrl, | ||||
|                 Votos = r.Votos, | ||||
|                 // 3. Usamos el nombre de propiedad correcto que el frontend espera: 'votosPorcentaje' | ||||
|                 VotosPorcentaje = totalVotosSeccion > 0 ? ((decimal)r.Votos * 100 / totalVotosSeccion) : 0 | ||||
|                 Porcentaje = totalVotosSeccion > 0 ? ((decimal)r.Votos * 100 / totalVotosSeccion) : 0 | ||||
|             }) | ||||
|             .ToList(); | ||||
|  | ||||
|         return Ok(resultadosFinales); | ||||
|         // Devolvemos un objeto para poder añadir la fecha de actualización | ||||
|         var seccionAmbito = await _dbContext.AmbitosGeograficos.AsNoTracking() | ||||
|             .FirstOrDefaultAsync(a => a.SeccionProvincialId == seccionId && a.NivelId == 20); | ||||
|         var estadoRecuento = seccionAmbito != null | ||||
|             ? await _dbContext.EstadosRecuentos.AsNoTracking() | ||||
|                 .FirstOrDefaultAsync(e => e.AmbitoGeograficoId == seccionAmbito.Id && e.CategoriaId == categoriaId) | ||||
|             : null; | ||||
|  | ||||
|         return Ok(new | ||||
|         { | ||||
|             UltimaActualizacion = estadoRecuento?.FechaTotalizacion ?? DateTime.UtcNow, | ||||
|             Resultados = resultadosFinales | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     [HttpGet("mapa-por-seccion")] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user