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")] | ||||
|   | ||||
| @@ -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")] | ||||
|   | ||||
| @@ -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":{}} | ||||
| @@ -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":{}} | ||||
| @@ -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> | ||||
		Reference in New Issue
	
	Block a user