Test Public Side

This commit is contained in:
2025-09-03 13:49:35 -03:00
parent 32e85b9b9d
commit a81f1fe894
33 changed files with 1205 additions and 133 deletions

View File

@@ -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

View File

@@ -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")]

View File

@@ -14,7 +14,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Api")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+6732a0e826a402495269212729673ebf1ff01916")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+32e85b9b9ddc7cd6422bfa52ff3c17fc6eff930b")]
[assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Api")]
[assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Api")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +1 @@
{"GlobalPropertiesHash":"b5T/+ta4fUd8qpIzUTm3KyEwAYYUsU5ASo+CSFM3ByE=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["h1yBBcAgq4jIQ1vINVvluRQMeuJlGA3/Zciq/j5c0AM=","t631p0kaOa0gMRIcaPzz1ZVPZ1kuq4pq4kYPWQgoPcM=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","E2ODTAlJxzsXY1iP1eB/02NIUK\u002BnQveGlWAOHY1cpgA=","6WTvWQ72AaZBYOVSmaxaci9tc1dW5p7IK9Kscjj2cb0=","vAy46VJ9Gp8QqG/Px4J1mj8jL6ws4/A01UKRmMYfYek=","cdgbHR/E4DJsddPc\u002BTpzoUMOVNaFJZm33Pw7AxU9Ees=","4r4JGR4hS5m4rsLfuCSZxzrknTBxKFkLQDXc\u002B2KbqTU=","yVoZ4UnBcSOapsJIi046hnn7ylD3jAcEBUxQ\u002Brkvj/4=","/GfbpJthEWmsuz0uFx1QLHM7gyM1wLLeQgAIl4SzUD4=","i5\u002B5LcfxQD8meRAkQbVf4wMvjxSE4\u002BjCd2/FdPtMpms=","AvSkxVPIg0GjnB1RJ4hDNyo9p9GONrzDs8uVuixH\u002BOE=","IgT9pOgRnK37qfILj2QcjFoBZ180HMt\u002BScgje2iYOo4=","ezUlOMzNZmyKDIe1wwXqvX\u002BvhwfB992xNVts7r2zcTc=","y2BV4WpkQuLfqQhfOQBtmuzh940c3s4LAopGKfztfTE=","lHTUEsMkDu8nqXtfTwl7FRfgocyyc7RI5O/edTHN1\u002B0=","A7nz7qgOtQ1CwZZLvNnr0b5QZB3fTi3y4i6y7rBIcxQ=","znnuRi2tsk7AACuYo4WSgj7NcLriG4PKVaF4L35SvDk=","GelE32odx/vTului267wqi6zL3abBnF9yvwC2Q66LoM=","FktDKOD55tGexuQTZYqJXFJKcfFUYha2UUveJ7i4d\u002B0=","6CAjHexjcmVc1caYyfNvMfhJRU6qtmi57Siv1ysirg0=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","yfarYtFn36AY3Hcf8kh\u002BwBS7wI/HSaScE\u002BTOvW5GoAM="],"CachedAssets":{},"CachedCopyCandidates":{}}
{"GlobalPropertiesHash":"b5T/+ta4fUd8qpIzUTm3KyEwAYYUsU5ASo+CSFM3ByE=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["h1yBBcAgq4jIQ1vINVvluRQMeuJlGA3/Zciq/j5c0AM=","t631p0kaOa0gMRIcaPzz1ZVPZ1kuq4pq4kYPWQgoPcM=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","E2ODTAlJxzsXY1iP1eB/02NIUK\u002BnQveGlWAOHY1cpgA=","6WTvWQ72AaZBYOVSmaxaci9tc1dW5p7IK9Kscjj2cb0=","vAy46VJ9Gp8QqG/Px4J1mj8jL6ws4/A01UKRmMYfYek=","cdgbHR/E4DJsddPc\u002BTpzoUMOVNaFJZm33Pw7AxU9Ees=","4r4JGR4hS5m4rsLfuCSZxzrknTBxKFkLQDXc\u002B2KbqTU=","yVoZ4UnBcSOapsJIi046hnn7ylD3jAcEBUxQ\u002Brkvj/4=","/GfbpJthEWmsuz0uFx1QLHM7gyM1wLLeQgAIl4SzUD4=","i5\u002B5LcfxQD8meRAkQbVf4wMvjxSE4\u002BjCd2/FdPtMpms=","AvSkxVPIg0GjnB1RJ4hDNyo9p9GONrzDs8uVuixH\u002BOE=","IgT9pOgRnK37qfILj2QcjFoBZ180HMt\u002BScgje2iYOo4=","ezUlOMzNZmyKDIe1wwXqvX\u002BvhwfB992xNVts7r2zcTc=","y2BV4WpkQuLfqQhfOQBtmuzh940c3s4LAopGKfztfTE=","lHTUEsMkDu8nqXtfTwl7FRfgocyyc7RI5O/edTHN1\u002B0=","A7nz7qgOtQ1CwZZLvNnr0b5QZB3fTi3y4i6y7rBIcxQ=","znnuRi2tsk7AACuYo4WSgj7NcLriG4PKVaF4L35SvDk=","GelE32odx/vTului267wqi6zL3abBnF9yvwC2Q66LoM=","TEsXImnzxFKTIq2f5fiDu7i6Ar/cbecW5MZ3z8Wb/a4=","6UbV83RDqihxiPJRSqBBce97kpcbB7parfVbqy/JDrA=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","4a8hgDNqfLAz7U5813iwPnUccUabxTlRH1USsCHCuGA="],"CachedAssets":{},"CachedCopyCandidates":{}}

View File

@@ -1 +1 @@
{"GlobalPropertiesHash":"tJTBjV/i0Ihkc6XuOu69wxL8PBac9c9Kak6srMso4pU=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["h1yBBcAgq4jIQ1vINVvluRQMeuJlGA3/Zciq/j5c0AM=","t631p0kaOa0gMRIcaPzz1ZVPZ1kuq4pq4kYPWQgoPcM=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","E2ODTAlJxzsXY1iP1eB/02NIUK\u002BnQveGlWAOHY1cpgA=","6WTvWQ72AaZBYOVSmaxaci9tc1dW5p7IK9Kscjj2cb0=","vAy46VJ9Gp8QqG/Px4J1mj8jL6ws4/A01UKRmMYfYek=","cdgbHR/E4DJsddPc\u002BTpzoUMOVNaFJZm33Pw7AxU9Ees=","4r4JGR4hS5m4rsLfuCSZxzrknTBxKFkLQDXc\u002B2KbqTU=","yVoZ4UnBcSOapsJIi046hnn7ylD3jAcEBUxQ\u002Brkvj/4=","/GfbpJthEWmsuz0uFx1QLHM7gyM1wLLeQgAIl4SzUD4=","i5\u002B5LcfxQD8meRAkQbVf4wMvjxSE4\u002BjCd2/FdPtMpms=","AvSkxVPIg0GjnB1RJ4hDNyo9p9GONrzDs8uVuixH\u002BOE=","IgT9pOgRnK37qfILj2QcjFoBZ180HMt\u002BScgje2iYOo4=","ezUlOMzNZmyKDIe1wwXqvX\u002BvhwfB992xNVts7r2zcTc=","y2BV4WpkQuLfqQhfOQBtmuzh940c3s4LAopGKfztfTE=","lHTUEsMkDu8nqXtfTwl7FRfgocyyc7RI5O/edTHN1\u002B0=","A7nz7qgOtQ1CwZZLvNnr0b5QZB3fTi3y4i6y7rBIcxQ=","znnuRi2tsk7AACuYo4WSgj7NcLriG4PKVaF4L35SvDk=","GelE32odx/vTului267wqi6zL3abBnF9yvwC2Q66LoM=","FktDKOD55tGexuQTZYqJXFJKcfFUYha2UUveJ7i4d\u002B0=","6CAjHexjcmVc1caYyfNvMfhJRU6qtmi57Siv1ysirg0=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","yfarYtFn36AY3Hcf8kh\u002BwBS7wI/HSaScE\u002BTOvW5GoAM="],"CachedAssets":{},"CachedCopyCandidates":{}}
{"GlobalPropertiesHash":"tJTBjV/i0Ihkc6XuOu69wxL8PBac9c9Kak6srMso4pU=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["h1yBBcAgq4jIQ1vINVvluRQMeuJlGA3/Zciq/j5c0AM=","t631p0kaOa0gMRIcaPzz1ZVPZ1kuq4pq4kYPWQgoPcM=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","E2ODTAlJxzsXY1iP1eB/02NIUK\u002BnQveGlWAOHY1cpgA=","6WTvWQ72AaZBYOVSmaxaci9tc1dW5p7IK9Kscjj2cb0=","vAy46VJ9Gp8QqG/Px4J1mj8jL6ws4/A01UKRmMYfYek=","cdgbHR/E4DJsddPc\u002BTpzoUMOVNaFJZm33Pw7AxU9Ees=","4r4JGR4hS5m4rsLfuCSZxzrknTBxKFkLQDXc\u002B2KbqTU=","yVoZ4UnBcSOapsJIi046hnn7ylD3jAcEBUxQ\u002Brkvj/4=","/GfbpJthEWmsuz0uFx1QLHM7gyM1wLLeQgAIl4SzUD4=","i5\u002B5LcfxQD8meRAkQbVf4wMvjxSE4\u002BjCd2/FdPtMpms=","AvSkxVPIg0GjnB1RJ4hDNyo9p9GONrzDs8uVuixH\u002BOE=","IgT9pOgRnK37qfILj2QcjFoBZ180HMt\u002BScgje2iYOo4=","ezUlOMzNZmyKDIe1wwXqvX\u002BvhwfB992xNVts7r2zcTc=","y2BV4WpkQuLfqQhfOQBtmuzh940c3s4LAopGKfztfTE=","lHTUEsMkDu8nqXtfTwl7FRfgocyyc7RI5O/edTHN1\u002B0=","A7nz7qgOtQ1CwZZLvNnr0b5QZB3fTi3y4i6y7rBIcxQ=","znnuRi2tsk7AACuYo4WSgj7NcLriG4PKVaF4L35SvDk=","GelE32odx/vTului267wqi6zL3abBnF9yvwC2Q66LoM=","TEsXImnzxFKTIq2f5fiDu7i6Ar/cbecW5MZ3z8Wb/a4=","6UbV83RDqihxiPJRSqBBce97kpcbB7parfVbqy/JDrA=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","4a8hgDNqfLAz7U5813iwPnUccUabxTlRH1USsCHCuGA="],"CachedAssets":{},"CachedCopyCandidates":{}}

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="GetEFProjectMetadata">
<MSBuild Condition=" '$(TargetFramework)' == '' "
Projects="$(MSBuildProjectFile)"
Targets="GetEFProjectMetadata"
Properties="TargetFramework=$(TargetFrameworks.Split(';')[0]);EFProjectMetadataFile=$(EFProjectMetadataFile)" />
<ItemGroup Condition=" '$(TargetFramework)' != '' ">
<EFProjectMetadata Include="AssemblyName: $(AssemblyName)" />
<EFProjectMetadata Include="Language: $(Language)" />
<EFProjectMetadata Include="OutputPath: $(OutputPath)" />
<EFProjectMetadata Include="Platform: $(Platform)" />
<EFProjectMetadata Include="PlatformTarget: $(PlatformTarget)" />
<EFProjectMetadata Include="ProjectAssetsFile: $(ProjectAssetsFile)" />
<EFProjectMetadata Include="ProjectDir: $(ProjectDir)" />
<EFProjectMetadata Include="RootNamespace: $(RootNamespace)" />
<EFProjectMetadata Include="RuntimeFrameworkVersion: $(RuntimeFrameworkVersion)" />
<EFProjectMetadata Include="TargetFileName: $(TargetFileName)" />
<EFProjectMetadata Include="TargetFrameworkMoniker: $(TargetFrameworkMoniker)" />
<EFProjectMetadata Include="Nullable: $(Nullable)" />
<EFProjectMetadata Include="TargetFramework: $(TargetFramework)" />
<EFProjectMetadata Include="TargetPlatformIdentifier: $(TargetPlatformIdentifier)" />
</ItemGroup>
<WriteLinesToFile Condition=" '$(TargetFramework)' != '' "
File="$(EFProjectMetadataFile)"
Lines="@(EFProjectMetadata)" />
</Target>
</Project>