Feat Tabla de Datos Redaccion
- Tabla de Top 2 Conurbano - Tabla de Top 2 Por Secciones Electorales Bs. As.
This commit is contained in:
		| @@ -5,7 +5,7 @@ import type { | ||||
|   ApiResponseTablaDetallada, ProyeccionBancas, MunicipioSimple, | ||||
|   TelegramaData, CatalogoItem, CategoriaResumen, ResultadoTicker, | ||||
|   ApiResponseResultadosPorSeccion, PanelElectoralDto, ResumenProvincia, | ||||
|   CategoriaResumenHome | ||||
|   CategoriaResumenHome, ResultadoFila, ResultadoSeccion | ||||
| } from './types/types'; | ||||
|  | ||||
| /** | ||||
| @@ -337,4 +337,14 @@ export const getHomeResumenNacional = async (eleccionId: number, categoriaId: nu | ||||
|   const url = `/elecciones/home-resumen-nacional?${queryParams.toString()}`; | ||||
|   const { data } = await apiClient.get(url); | ||||
|   return data; | ||||
| }; | ||||
|  | ||||
| export const getTablaConurbano = async (eleccionId: number): Promise<ResultadoFila[]> => { | ||||
|   const { data } = await apiClient.get(`/elecciones/${eleccionId}/tabla-conurbano`); | ||||
|   return data; | ||||
| }; | ||||
|  | ||||
| export const getTablaSecciones = async (eleccionId: number): Promise<ResultadoSeccion[]> => { | ||||
|   const { data } = await apiClient.get(`/elecciones/${eleccionId}/tabla-secciones`); | ||||
|   return data; | ||||
| }; | ||||
| @@ -6,6 +6,8 @@ import { PanelNacionalWidget } from './nacionales/PanelNacionalWidget'; | ||||
| import { HomeCarouselWidget } from './nacionales/HomeCarouselWidget'; | ||||
| import './DevAppStyle.css' | ||||
| import { HomeCarouselNacionalWidget } from './nacionales/HomeCarouselNacionalWidget'; | ||||
| import { TablaConurbanoWidget } from './nacionales/TablaConurbanoWidget'; | ||||
| import { TablaSeccionesWidget } from './nacionales/TablaSeccionesWidget'; | ||||
|  | ||||
| // --- NUEVO COMPONENTE REUTILIZABLE PARA CONTENIDO COLAPSABLE --- | ||||
| const CollapsibleWidgetWrapper = ({ children }: { children: React.ReactNode }) => { | ||||
| @@ -163,7 +165,15 @@ export const DevAppLegislativas = () => { | ||||
|                     Uso: <code style={codeStyle}><ResultadosNacionalesCardsWidget eleccionId={2} focoDistritoId="16" focoCategoriaId={2} cantidadResultados={1} /></code> | ||||
|                 </p> | ||||
|                 <ResultadosNacionalesCardsWidget eleccionId={2} focoDistritoId="16" focoCategoriaId={2} cantidadResultados={1} /> | ||||
|                 <div style={sectionStyle}> | ||||
|                     <h2>Widget: Tabla de Resultados del Conurbano</h2> | ||||
|                     <TablaConurbanoWidget /> | ||||
|                 </div> | ||||
|  | ||||
|                 <div style={sectionStyle}> | ||||
|                     <h2>Widget: Tabla de Resultados por Sección Electoral</h2> | ||||
|                     <TablaSeccionesWidget /> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     ); | ||||
|   | ||||
| @@ -0,0 +1,53 @@ | ||||
| // src/features/legislativas/nacionales/TablaConurbanoWidget.tsx | ||||
| import { useQuery } from '@tanstack/react-query'; | ||||
| import { getTablaConurbano } from '../../../apiService'; | ||||
| import styles from './TablaResultadosWidget.module.css'; | ||||
|  | ||||
| export const TablaConurbanoWidget = () => { | ||||
|   // CORRECCIÓN: Se elimina el estado y el selector de categoría. | ||||
|   const ELECCION_ID = 2; // Exclusivo para elecciones nacionales | ||||
|  | ||||
|   const { data, isLoading, error } = useQuery({ | ||||
|     // La queryKey ya no necesita la categoría | ||||
|     queryKey: ['tablaConurbano', ELECCION_ID], | ||||
|     // La llamada a la API ya no necesita la categoría | ||||
|     queryFn: () => getTablaConurbano(ELECCION_ID), | ||||
|     refetchInterval: 60000, | ||||
|   }); | ||||
|  | ||||
|   const formatPercent = (num: number) => `${num.toFixed(2)}%`; | ||||
|  | ||||
|   return ( | ||||
|     <div className={styles.widgetContainer}> | ||||
|       <div className={styles.header}> | ||||
|         <h3>Resultados Conurbano - Diputados Nacionales</h3> | ||||
|       </div> | ||||
|       {isLoading && <p>Cargando resultados...</p>} | ||||
|       {error && <p>Error al cargar los datos.</p>} | ||||
|       {data && ( | ||||
|         <table className={styles.resultsTable}> | ||||
|           <thead> | ||||
|             <tr> | ||||
|               <th>Distrito</th> | ||||
|               <th>1ra Fuerza</th> | ||||
|               <th>%</th> | ||||
|               <th>2da Fuerza</th> | ||||
|               <th>%</th> | ||||
|             </tr> | ||||
|           </thead> | ||||
|           <tbody> | ||||
|             {data.map((fila, index) => ( | ||||
|               <tr key={fila.ambitoId}> | ||||
|                 <td className={styles.distritoCell}><span className={styles.distritoIndex}>{index + 1}.</span>{fila.nombre}</td> | ||||
|                 <td className={styles.fuerzaCell}>{fila.fuerza1Display}</td> | ||||
|                 <td className={styles.porcentajeCell}>{formatPercent(fila.fuerza1Porcentaje)}</td> | ||||
|                 <td className={styles.fuerzaCell}>{fila.fuerza2Display}</td> | ||||
|                 <td className={styles.porcentajeCell}>{formatPercent(fila.fuerza2Porcentaje)}</td> | ||||
|               </tr> | ||||
|             ))} | ||||
|           </tbody> | ||||
|         </table> | ||||
|       )} | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
| @@ -0,0 +1,76 @@ | ||||
| /* src/features/legislativas/nacionales/TablaResultadosWidget.module.css */ | ||||
| .widgetContainer { | ||||
|   font-family: 'Roboto', sans-serif; | ||||
|   max-width: 900px; | ||||
|   margin: 2rem auto; | ||||
|   border: 1px solid #e0e0e0; | ||||
|   border-radius: 8px; | ||||
|   padding: 1rem; | ||||
| } | ||||
|  | ||||
| .header { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
|   margin-bottom: 1rem; | ||||
|   padding-bottom: 1rem; | ||||
|   border-bottom: 1px solid #e0e0e0; | ||||
| } | ||||
|  | ||||
| .header h3 { | ||||
|   margin: 0; | ||||
|   font-size: 1.5rem; | ||||
| } | ||||
|  | ||||
| .categoriaSelector { | ||||
|   min-width: 250px; | ||||
| } | ||||
|  | ||||
| .resultsTable { | ||||
|   width: 100%; | ||||
|   border-collapse: separate; | ||||
|   border-spacing: 0; | ||||
| } | ||||
|  | ||||
| .resultsTable th, | ||||
| .resultsTable td { | ||||
|   padding: 0.75rem; | ||||
|   text-align: left; | ||||
|   border-bottom: 1px solid #f0f0f0; | ||||
| } | ||||
|  | ||||
| .resultsTable th { | ||||
|   font-weight: 700; | ||||
|   font-size: 0.8rem; | ||||
|   text-transform: uppercase; | ||||
|   color: #6c757d; | ||||
| } | ||||
|  | ||||
| .distritoCell { | ||||
|   font-weight: 500; | ||||
| } | ||||
|  | ||||
| .fuerzaCell { | ||||
|   color: #212529; | ||||
| } | ||||
|  | ||||
| .porcentajeCell { | ||||
|   font-weight: 700; | ||||
|   text-align: right; | ||||
|   min-width: 80px; | ||||
| } | ||||
|  | ||||
| .seccionHeader td { | ||||
|   background-color: #f8f9fa; | ||||
|   font-weight: 700; | ||||
|   font-size: 1.1rem; | ||||
|   color: #007bff; | ||||
|   border-top: 2px solid #007bff; | ||||
|   border-bottom: 2px solid #007bff; | ||||
| } | ||||
|  | ||||
| .distritoIndex { | ||||
|   font-weight: 400; | ||||
|   color: #6c757d; | ||||
|   padding-right: 0.5rem; | ||||
| } | ||||
| @@ -0,0 +1,58 @@ | ||||
| // src/features/legislativas/nacionales/TablaSeccionesWidget.tsx | ||||
| import React from 'react'; // Importar React para React.Fragment | ||||
| import { useQuery } from '@tanstack/react-query'; | ||||
| import { getTablaSecciones } from '../../../apiService'; | ||||
| import styles from './TablaResultadosWidget.module.css'; | ||||
|  | ||||
| export const TablaSeccionesWidget = () => { | ||||
|   const ELECCION_ID = 2; | ||||
|  | ||||
|   const { data, isLoading, error } = useQuery({ | ||||
|     queryKey: ['tablaSecciones', ELECCION_ID], | ||||
|     queryFn: () => getTablaSecciones(ELECCION_ID), | ||||
|     refetchInterval: 60000, | ||||
|   }); | ||||
|  | ||||
|   const formatPercent = (num: number) => `${num.toFixed(2)}%`; | ||||
|  | ||||
|   return ( | ||||
|     <div className={styles.widgetContainer}> | ||||
|       <div className={styles.header}> | ||||
|         <h3>Resultados por Sección - Diputados Nacionales</h3> | ||||
|       </div> | ||||
|       {isLoading && <p>Cargando resultados...</p>} | ||||
|       {error && <p>Error al cargar los datos.</p>} | ||||
|       {data && ( | ||||
|         <table className={styles.resultsTable}> | ||||
|           <thead> | ||||
|             <tr> | ||||
|               <th>Municipio</th> | ||||
|               <th>1ra Fuerza</th> | ||||
|               <th>%</th> | ||||
|               <th>2da Fuerza</th> | ||||
|               <th>%</th> | ||||
|             </tr> | ||||
|           </thead> | ||||
|           <tbody> | ||||
|             {data.map((seccion) => ( | ||||
|               <React.Fragment key={seccion.seccionId}> | ||||
|                 <tr className={styles.seccionHeader}> | ||||
|                   <td colSpan={5}>{seccion.nombre}</td> | ||||
|                 </tr> | ||||
|                 {seccion.municipios.map((fila, index) => ( | ||||
|                   <tr key={fila.ambitoId}> | ||||
|                     <td className={styles.distritoCell}><span className={styles.distritoIndex}>{index + 1}.</span>{fila.nombre}</td> | ||||
|                     <td className={styles.fuerzaCell}>{fila.fuerza1Display}</td> | ||||
|                     <td className={styles.porcentajeCell}>{formatPercent(fila.fuerza1Porcentaje)}</td> | ||||
|                     <td className={styles.fuerzaCell}>{fila.fuerza2Display}</td> | ||||
|                     <td className={styles.porcentajeCell}>{formatPercent(fila.fuerza2Porcentaje)}</td> | ||||
|                   </tr> | ||||
|                 ))} | ||||
|               </React.Fragment> | ||||
|             ))} | ||||
|           </tbody> | ||||
|         </table> | ||||
|       )} | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
| @@ -152,7 +152,7 @@ export interface ResultadoCandidato { | ||||
|   color: string | null; | ||||
|   porcentaje: number; | ||||
|   votos: number; | ||||
|   bancasObtenidas?: number;  | ||||
|   bancasObtenidas?: number; | ||||
| } | ||||
|  | ||||
| // Definición para una categoría. | ||||
| @@ -171,12 +171,29 @@ export interface ResumenProvincia { | ||||
| } | ||||
|  | ||||
| export interface CategoriaResumenHome { | ||||
|     categoriaId: number; | ||||
|     categoriaNombre: string; | ||||
|     estadoRecuento: EstadoRecuentoDto | null; | ||||
|     resultados: ResultadoCandidato[]; | ||||
|     votosEnBlanco: number; | ||||
|     votosEnBlancoPorcentaje: number; | ||||
|     votosTotales: number; | ||||
|     ultimaActualizacion: string; | ||||
|   categoriaId: number; | ||||
|   categoriaNombre: string; | ||||
|   estadoRecuento: EstadoRecuentoDto | null; | ||||
|   resultados: ResultadoCandidato[]; | ||||
|   votosEnBlanco: number; | ||||
|   votosEnBlancoPorcentaje: number; | ||||
|   votosTotales: number; | ||||
|   ultimaActualizacion: string; | ||||
| } | ||||
|  | ||||
| // --- TIPOS PARA WIDGETS DE TABLAS --- | ||||
| export interface ResultadoFila { | ||||
|   ambitoId: number; | ||||
|   nombre: string; | ||||
|   orden: number; | ||||
|   fuerza1Display: string; | ||||
|   fuerza1Porcentaje: number; | ||||
|   fuerza2Display: string; | ||||
|   fuerza2Porcentaje: number; | ||||
| } | ||||
|  | ||||
| export interface ResultadoSeccion { | ||||
|   seccionId: string; | ||||
|   nombre: string; | ||||
|   municipios: ResultadoFila[]; | ||||
| } | ||||
| @@ -1676,7 +1676,6 @@ List<CandidatoOverride> overrides, string agrupacionId, int categoriaId, int? am | ||||
|         var todosLosLogos = await _dbContext.LogosAgrupacionesCategorias.AsNoTracking().Where(l => l.EleccionId == eleccionId || l.EleccionId == 0).ToListAsync(); | ||||
|         var categoriaInfo = await _dbContext.CategoriasElectorales.AsNoTracking().FirstOrDefaultAsync(c => c.Id == categoriaId); | ||||
|  | ||||
|         // Calculamos los totales nacionales sumando los datos de todas las provincias (NivelId = 10). | ||||
|         var totalesProvincialesAgregados = await _dbContext.EstadosRecuentosGenerales | ||||
|             .AsNoTracking() | ||||
|             .Where(e => e.EleccionId == eleccionId && e.CategoriaId == categoriaId && e.AmbitoGeografico.NivelId == 10) | ||||
| @@ -1687,7 +1686,7 @@ List<CandidatoOverride> overrides, string agrupacionId, int categoriaId, int? am | ||||
|                 TotalElectores = g.Sum(e => e.CantidadElectores), | ||||
|                 TotalMesasTotalizadas = g.Sum(e => e.MesasTotalizadas), | ||||
|                 TotalMesasEsperadas = g.Sum(e => e.MesasEsperadas), | ||||
|                 UltimaFecha = g.Max(e => e.FechaTotalizacion) // También obtenemos la fecha más reciente. | ||||
|                 UltimaFecha = g.Max(e => e.FechaTotalizacion) | ||||
|             }) | ||||
|             .FirstOrDefaultAsync(); | ||||
|  | ||||
| @@ -1748,4 +1747,128 @@ List<CandidatoOverride> overrides, string agrupacionId, int categoriaId, int? am | ||||
|  | ||||
|         return Ok(respuesta); | ||||
|     } | ||||
|  | ||||
|     [HttpGet("tabla-conurbano")] | ||||
|     public async Task<IActionResult> GetTablaConurbano([FromRoute] int eleccionId) | ||||
|     { | ||||
|         const int categoriaId = 3; // Diputados Nacionales | ||||
|  | ||||
|         var municipiosConurbano = await ( | ||||
|             from conurbano in _dbContext.Conurbano | ||||
|             join ambito in _dbContext.AmbitosGeograficos on conurbano.AmbitoGeograficoId equals ambito.Id | ||||
|             orderby conurbano.Orden | ||||
|             select new | ||||
|             { | ||||
|                 conurbano.AmbitoGeograficoId, | ||||
|                 conurbano.Orden, | ||||
|                 ambito.Nombre | ||||
|             }) | ||||
|             .AsNoTracking() | ||||
|             .ToListAsync(); | ||||
|  | ||||
|         var idsMunicipios = municipiosConurbano.Select(m => m.AmbitoGeograficoId).ToList(); | ||||
|  | ||||
|         var todosLosVotos = await _dbContext.ResultadosVotos | ||||
|             .AsNoTracking() | ||||
|             .Include(rv => rv.AgrupacionPolitica) | ||||
|             .Where(rv => rv.EleccionId == eleccionId && rv.CategoriaId == categoriaId && idsMunicipios.Contains(rv.AmbitoGeograficoId)) | ||||
|             .ToListAsync(); | ||||
|  | ||||
|         var resultadosFinales = new List<Elecciones.Core.DTOs.ApiResponses.Tablas.ResultadoFilaDto>(); | ||||
|  | ||||
|         foreach (var municipio in municipiosConurbano) | ||||
|         { | ||||
|             var votosMunicipio = todosLosVotos.Where(v => v.AmbitoGeograficoId == municipio.AmbitoGeograficoId).ToList(); | ||||
|             var totalVotos = (decimal)votosMunicipio.Sum(v => v.CantidadVotos); | ||||
|             var top2 = votosMunicipio.OrderByDescending(v => v.CantidadVotos).Take(2).ToList(); | ||||
|  | ||||
|             string GetDisplayName(ResultadoVoto? voto) | ||||
|             { | ||||
|                 if (voto == null) return "N/D"; | ||||
|                 return voto.AgrupacionPolitica.NombreCorto ?? voto.AgrupacionPolitica.Nombre; | ||||
|             } | ||||
|  | ||||
|             var fila = new Elecciones.Core.DTOs.ApiResponses.Tablas.ResultadoFilaDto | ||||
|             { | ||||
|                 AmbitoId = municipio.AmbitoGeograficoId, | ||||
|                 Nombre = municipio.Nombre, | ||||
|                 Orden = municipio.Orden, | ||||
|                 Fuerza1Display = GetDisplayName(top2.FirstOrDefault()), | ||||
|                 Fuerza1Porcentaje = top2.Count > 0 && totalVotos > 0 ? (top2[0].CantidadVotos / totalVotos) * 100 : 0, | ||||
|                 Fuerza2Display = GetDisplayName(top2.Skip(1).FirstOrDefault()), | ||||
|                 Fuerza2Porcentaje = top2.Count > 1 && totalVotos > 0 ? (top2[1].CantidadVotos / totalVotos) * 100 : 0, | ||||
|             }; | ||||
|             resultadosFinales.Add(fila); | ||||
|         } | ||||
|  | ||||
|         return Ok(resultadosFinales); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     [HttpGet("tabla-secciones")] | ||||
|     public async Task<IActionResult> GetTablaSecciones([FromRoute] int eleccionId) | ||||
|     { | ||||
|         const int categoriaId = 3; | ||||
|  | ||||
|         var provinciaBA = await _dbContext.AmbitosGeograficos.AsNoTracking().FirstOrDefaultAsync(a => a.DistritoId == "02" && a.NivelId == 10); | ||||
|         if (provinciaBA == null) return NotFound("No se encontró el ámbito de la Provincia de Buenos Aires."); | ||||
|  | ||||
|         var secciones = await _dbContext.AmbitosGeograficos | ||||
|             .AsNoTracking() | ||||
|             .Where(a => a.NivelId == 20 && a.DistritoId == "02" && a.SeccionProvincialId != null) | ||||
|             .OrderBy(a => a.SeccionProvincialId) | ||||
|             .ToListAsync(); | ||||
|  | ||||
|         var idsSecciones = secciones.Select(s => s.SeccionProvincialId).ToList(); | ||||
|         var municipiosDeSecciones = await _dbContext.AmbitosGeograficos.AsNoTracking() | ||||
|             .Where(a => a.NivelId == 30 && a.DistritoId == "02" && idsSecciones.Contains(a.SeccionProvincialId)).ToListAsync(); | ||||
|         var idsMunicipios = municipiosDeSecciones.Select(m => m.Id).ToList(); | ||||
|  | ||||
|         var todosLosVotos = await _dbContext.ResultadosVotos.AsNoTracking() | ||||
|             .Include(rv => rv.AgrupacionPolitica) | ||||
|             .Where(rv => rv.EleccionId == eleccionId && rv.CategoriaId == categoriaId && idsMunicipios.Contains(rv.AmbitoGeograficoId)).ToListAsync(); | ||||
|  | ||||
|         var todosLosCandidatos = await _dbContext.CandidatosOverrides.AsNoTracking() | ||||
|             .Where(c => (c.EleccionId == eleccionId || c.EleccionId == 0) && c.CategoriaId == categoriaId).ToListAsync(); | ||||
|  | ||||
|         var resultadosFinales = new List<Elecciones.Core.DTOs.ApiResponses.Tablas.ResultadoSeccionDto>(); | ||||
|  | ||||
|         foreach (var seccion in secciones) | ||||
|         { | ||||
|             var seccionDto = new Elecciones.Core.DTOs.ApiResponses.Tablas.ResultadoSeccionDto { SeccionId = seccion.SeccionProvincialId!, Nombre = seccion.Nombre }; | ||||
|             var municipiosDeEstaSeccion = municipiosDeSecciones.Where(m => m.SeccionProvincialId == seccion.SeccionProvincialId).OrderBy(m => m.Nombre); | ||||
|  | ||||
|             foreach (var municipio in municipiosDeEstaSeccion) | ||||
|             { | ||||
|                 var votosMunicipio = todosLosVotos.Where(v => v.AmbitoGeograficoId == municipio.Id).ToList(); | ||||
|                 var totalVotos = (decimal)votosMunicipio.Sum(v => v.CantidadVotos); | ||||
|                 var top2 = votosMunicipio.OrderByDescending(v => v.CantidadVotos).Take(2).ToList(); | ||||
|  | ||||
|                 string GetDisplayName(ResultadoVoto? voto) | ||||
|                 { | ||||
|                     if (voto == null) return "N/D"; | ||||
|  | ||||
|                     var candidato = todosLosCandidatos.FirstOrDefault(c => c.AgrupacionPoliticaId == voto.AgrupacionPoliticaId && c.AmbitoGeograficoId == voto.AmbitoGeograficoId) | ||||
|                         ?? todosLosCandidatos.FirstOrDefault(c => c.AgrupacionPoliticaId == voto.AgrupacionPoliticaId && c.AmbitoGeograficoId == provinciaBA.Id) | ||||
|                         ?? todosLosCandidatos.FirstOrDefault(c => c.AgrupacionPoliticaId == voto.AgrupacionPoliticaId && c.AmbitoGeograficoId == null); | ||||
|  | ||||
|                     return candidato?.NombreCandidato ?? voto.AgrupacionPolitica.NombreCorto ?? voto.AgrupacionPolitica.Nombre; | ||||
|                 } | ||||
|  | ||||
|                 seccionDto.Municipios.Add(new Elecciones.Core.DTOs.ApiResponses.Tablas.ResultadoFilaDto | ||||
|                 { | ||||
|                     AmbitoId = municipio.Id, | ||||
|                     Nombre = municipio.Nombre, | ||||
|                     Orden = municipio.Id, | ||||
|                     Fuerza1Display = GetDisplayName(top2.FirstOrDefault()), | ||||
|                     Fuerza1Porcentaje = top2.Count > 0 && totalVotos > 0 ? (top2[0].CantidadVotos / totalVotos) * 100 : 0, | ||||
|                     Fuerza2Display = GetDisplayName(top2.Skip(1).FirstOrDefault()), | ||||
|                     Fuerza2Porcentaje = top2.Count > 1 && totalVotos > 0 ? (top2[1].CantidadVotos / totalVotos) * 100 : 0, | ||||
|                 }); | ||||
|             } | ||||
|             resultadosFinales.Add(seccionDto); | ||||
|         } | ||||
|  | ||||
|         return Ok(resultadosFinales); | ||||
|     } | ||||
| } | ||||
| @@ -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+814b24cefbaf491f4b43e55a0ded7431f679486d")] | ||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+3c364ef373330eaa052fa0d2aad92e71d0bfd7df")] | ||||
| [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":["YB39loxHH43S4MF8aTOiogcIbBAIq5Qj3dlJkIfYVxI=","t631p0kaOa0gMRIcaPzz1ZVPZ1kuq4pq4kYPWQgoPcM=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","E2ODTAlJxzsXY1iP1eB/02NIUK\u002BnQveGlWAOHY1cpgA=","ePXrkee3hv3wHUr8S7aYmRVvXUTxQf76zApKGv3/l3o=","DXx5dQywLo3UsY2zQaUG\u002BbW4ObiYbybxPBWxeJD2bhk=","muVh5sjH3sgdvuz4TbuTwTggX1uDnsWXgoosMKST/r4=","nrP5gSIA5vzgp8v12CAOr943QYLxU4Til6oiCcWSNI8=","yMd45U9BK07I3b3fBQ627PWTYyZ2ZjrmFc5VD\u002BQVx1Q=","xKskvcoJU0RVRN1a5dRqKRM7IP5vmmbraUaPFYjhnCc=","p7BjQw7aSZjfOCqmKm7/kPO9qegEQZBfirMjlOx/I1I=","MI0hVVLYavEhzHq/Z1UbajfrxanA1aET19aOH8G2ImI=","2dY8CqW9fAY8yN0foa\u002BZp2gc0RfPoPmB/tKSj1QoTw0=","79rfGLH4UjfTPvc//\u002BZjnBqdz585pUtYZ0/hwE2iEic=","PUqgvMdfTQkF5lpBVtHv2teQLV5WaEH0xMKTmINe2YQ=","\u002BFI0b4ppdxel/pby/y/xKImHrtdxo2g83OhskdREyIg=","jEESu6\u002BhbDvNMjLt/6OufuK\u002B9cHmzx\u002BTCIn4fWa9nSc=","UaCPJEvR4nVxxGCB5CUnRlJiw4drDW3Q3Nss\u002Bya2cv4=","ZqF13CT3rok/Gzl\u002BMsw3q9X1nf65bwEVD670efE3k\u002Bk=","gH3W7phPzBCY1DAVn4YnP4SA8Uaq73TpctS0yFSvzNM=","u5F4J4\u002BLHUIOCz5ze5NSF42mDeAaAfi\u002BKN3Ay3rKLY8=","GeUUID0ymF5rrBWdX7YHzWA5GiGkNWCNUog4sp4xL3c=","3BxX4I0JXoDqmE8m0BrRZhixBRlHEueS3jAlmUXE/I8=","IlET7uqumshgFxIEvfKRskON\u002BeAKZ7OfD/kCeAwn0PM=","NN2rS\u002B89ZAITWlNODPcF/lHIh3ZNmAHvUX4EjqSkX4s=","OE89N/FsYhRU1Dy5Ne83ehzSwlNc/RcxHrJpHxPHfqY=","QI7IL4TkYEqfUiIEXQiVCaZx4vrM9/wZlvOrhnUd4jQ=","UIntj4QoiyGr7bnJN8KK5PGrhQd89m\u002BLfh4T8VKPxAk=","J\u002Bfv/j3QyIW9bxolc46wDka8641F622/QgIllt0Re80=","Y/o0rakw9VYzEfz9M659qW77P9kvz\u002B2gTe1Lv3zgUDE=","8QWUReqP8upfOnmA5lMNgBxAfYJ1z3zv/WYBUXBEiog=","1L7p1HQI/Uoosqm7RyBuYjKbRFTycFgJEtHPSdlXWhU=","ZxPpBx5gkHuilHLcg/vcjvaXswvTqiUM0YaAEwbNSLI=","zSbNtRd32h6wCMWjU5ecl5a3ECd\u002BVBstFC3etkdk4s0=","oncJIM8bHl6Y6SOcfvvBEQqLSQ06eswRhLoWIZejO5w=","BY4GeeFiQbYpWuSzb2XIY4JatmLNOZ6dhKs4ZT92nsM=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","8MmMrEQZa7r\u002B8J2r9WqeQZOEj806afRSF6ducpDWGG0="],"CachedAssets":{},"CachedCopyCandidates":{}} | ||||
| {"GlobalPropertiesHash":"b5T/+ta4fUd8qpIzUTm3KyEwAYYUsU5ASo+CSFM3ByE=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["YB39loxHH43S4MF8aTOiogcIbBAIq5Qj3dlJkIfYVxI=","t631p0kaOa0gMRIcaPzz1ZVPZ1kuq4pq4kYPWQgoPcM=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","E2ODTAlJxzsXY1iP1eB/02NIUK\u002BnQveGlWAOHY1cpgA=","DXx5dQywLo3UsY2zQaUG\u002BbW4ObiYbybxPBWxeJD2bhk=","muVh5sjH3sgdvuz4TbuTwTggX1uDnsWXgoosMKST/r4=","nrP5gSIA5vzgp8v12CAOr943QYLxU4Til6oiCcWSNI8=","yMd45U9BK07I3b3fBQ627PWTYyZ2ZjrmFc5VD\u002BQVx1Q=","xKskvcoJU0RVRN1a5dRqKRM7IP5vmmbraUaPFYjhnCc=","p7BjQw7aSZjfOCqmKm7/kPO9qegEQZBfirMjlOx/I1I=","MI0hVVLYavEhzHq/Z1UbajfrxanA1aET19aOH8G2ImI=","2dY8CqW9fAY8yN0foa\u002BZp2gc0RfPoPmB/tKSj1QoTw0=","79rfGLH4UjfTPvc//\u002BZjnBqdz585pUtYZ0/hwE2iEic=","PUqgvMdfTQkF5lpBVtHv2teQLV5WaEH0xMKTmINe2YQ=","\u002BFI0b4ppdxel/pby/y/xKImHrtdxo2g83OhskdREyIg=","jEESu6\u002BhbDvNMjLt/6OufuK\u002B9cHmzx\u002BTCIn4fWa9nSc=","UaCPJEvR4nVxxGCB5CUnRlJiw4drDW3Q3Nss\u002Bya2cv4=","ZqF13CT3rok/Gzl\u002BMsw3q9X1nf65bwEVD670efE3k\u002Bk=","gH3W7phPzBCY1DAVn4YnP4SA8Uaq73TpctS0yFSvzNM=","u5F4J4\u002BLHUIOCz5ze5NSF42mDeAaAfi\u002BKN3Ay3rKLY8=","GeUUID0ymF5rrBWdX7YHzWA5GiGkNWCNUog4sp4xL3c=","3BxX4I0JXoDqmE8m0BrRZhixBRlHEueS3jAlmUXE/I8=","IlET7uqumshgFxIEvfKRskON\u002BeAKZ7OfD/kCeAwn0PM=","NN2rS\u002B89ZAITWlNODPcF/lHIh3ZNmAHvUX4EjqSkX4s=","OE89N/FsYhRU1Dy5Ne83ehzSwlNc/RcxHrJpHxPHfqY=","QI7IL4TkYEqfUiIEXQiVCaZx4vrM9/wZlvOrhnUd4jQ=","UIntj4QoiyGr7bnJN8KK5PGrhQd89m\u002BLfh4T8VKPxAk=","J\u002Bfv/j3QyIW9bxolc46wDka8641F622/QgIllt0Re80=","Y/o0rakw9VYzEfz9M659qW77P9kvz\u002B2gTe1Lv3zgUDE=","8QWUReqP8upfOnmA5lMNgBxAfYJ1z3zv/WYBUXBEiog=","1L7p1HQI/Uoosqm7RyBuYjKbRFTycFgJEtHPSdlXWhU=","ZxPpBx5gkHuilHLcg/vcjvaXswvTqiUM0YaAEwbNSLI=","zSbNtRd32h6wCMWjU5ecl5a3ECd\u002BVBstFC3etkdk4s0=","urIQ/RlknPjR8\u002BeAcCsDIPiRjQGFfUdIC\u002BoT3wYB2dU=","0GIIj19uQyjDIXFgf3aZC3MWTTr0ockrC95FYCZEyN4=","BY4GeeFiQbYpWuSzb2XIY4JatmLNOZ6dhKs4ZT92nsM=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","YscOvhINdry\u002BI95UO\u002BBCycn6KSJEZQzHtH6Q7oRYqCI="],"CachedAssets":{},"CachedCopyCandidates":{}} | ||||
| @@ -1 +1 @@ | ||||
| {"GlobalPropertiesHash":"tJTBjV/i0Ihkc6XuOu69wxL8PBac9c9Kak6srMso4pU=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["YB39loxHH43S4MF8aTOiogcIbBAIq5Qj3dlJkIfYVxI=","t631p0kaOa0gMRIcaPzz1ZVPZ1kuq4pq4kYPWQgoPcM=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","E2ODTAlJxzsXY1iP1eB/02NIUK\u002BnQveGlWAOHY1cpgA=","ePXrkee3hv3wHUr8S7aYmRVvXUTxQf76zApKGv3/l3o=","DXx5dQywLo3UsY2zQaUG\u002BbW4ObiYbybxPBWxeJD2bhk=","muVh5sjH3sgdvuz4TbuTwTggX1uDnsWXgoosMKST/r4=","nrP5gSIA5vzgp8v12CAOr943QYLxU4Til6oiCcWSNI8=","yMd45U9BK07I3b3fBQ627PWTYyZ2ZjrmFc5VD\u002BQVx1Q=","xKskvcoJU0RVRN1a5dRqKRM7IP5vmmbraUaPFYjhnCc=","p7BjQw7aSZjfOCqmKm7/kPO9qegEQZBfirMjlOx/I1I=","MI0hVVLYavEhzHq/Z1UbajfrxanA1aET19aOH8G2ImI=","2dY8CqW9fAY8yN0foa\u002BZp2gc0RfPoPmB/tKSj1QoTw0=","79rfGLH4UjfTPvc//\u002BZjnBqdz585pUtYZ0/hwE2iEic=","PUqgvMdfTQkF5lpBVtHv2teQLV5WaEH0xMKTmINe2YQ=","\u002BFI0b4ppdxel/pby/y/xKImHrtdxo2g83OhskdREyIg=","jEESu6\u002BhbDvNMjLt/6OufuK\u002B9cHmzx\u002BTCIn4fWa9nSc=","UaCPJEvR4nVxxGCB5CUnRlJiw4drDW3Q3Nss\u002Bya2cv4=","ZqF13CT3rok/Gzl\u002BMsw3q9X1nf65bwEVD670efE3k\u002Bk=","gH3W7phPzBCY1DAVn4YnP4SA8Uaq73TpctS0yFSvzNM=","u5F4J4\u002BLHUIOCz5ze5NSF42mDeAaAfi\u002BKN3Ay3rKLY8=","GeUUID0ymF5rrBWdX7YHzWA5GiGkNWCNUog4sp4xL3c=","3BxX4I0JXoDqmE8m0BrRZhixBRlHEueS3jAlmUXE/I8=","IlET7uqumshgFxIEvfKRskON\u002BeAKZ7OfD/kCeAwn0PM=","NN2rS\u002B89ZAITWlNODPcF/lHIh3ZNmAHvUX4EjqSkX4s=","OE89N/FsYhRU1Dy5Ne83ehzSwlNc/RcxHrJpHxPHfqY=","QI7IL4TkYEqfUiIEXQiVCaZx4vrM9/wZlvOrhnUd4jQ=","UIntj4QoiyGr7bnJN8KK5PGrhQd89m\u002BLfh4T8VKPxAk=","J\u002Bfv/j3QyIW9bxolc46wDka8641F622/QgIllt0Re80=","Y/o0rakw9VYzEfz9M659qW77P9kvz\u002B2gTe1Lv3zgUDE=","8QWUReqP8upfOnmA5lMNgBxAfYJ1z3zv/WYBUXBEiog=","1L7p1HQI/Uoosqm7RyBuYjKbRFTycFgJEtHPSdlXWhU=","ZxPpBx5gkHuilHLcg/vcjvaXswvTqiUM0YaAEwbNSLI=","zSbNtRd32h6wCMWjU5ecl5a3ECd\u002BVBstFC3etkdk4s0=","oncJIM8bHl6Y6SOcfvvBEQqLSQ06eswRhLoWIZejO5w=","BY4GeeFiQbYpWuSzb2XIY4JatmLNOZ6dhKs4ZT92nsM=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","8MmMrEQZa7r\u002B8J2r9WqeQZOEj806afRSF6ducpDWGG0="],"CachedAssets":{},"CachedCopyCandidates":{}} | ||||
| {"GlobalPropertiesHash":"tJTBjV/i0Ihkc6XuOu69wxL8PBac9c9Kak6srMso4pU=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["YB39loxHH43S4MF8aTOiogcIbBAIq5Qj3dlJkIfYVxI=","t631p0kaOa0gMRIcaPzz1ZVPZ1kuq4pq4kYPWQgoPcM=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","E2ODTAlJxzsXY1iP1eB/02NIUK\u002BnQveGlWAOHY1cpgA=","DXx5dQywLo3UsY2zQaUG\u002BbW4ObiYbybxPBWxeJD2bhk=","muVh5sjH3sgdvuz4TbuTwTggX1uDnsWXgoosMKST/r4=","nrP5gSIA5vzgp8v12CAOr943QYLxU4Til6oiCcWSNI8=","yMd45U9BK07I3b3fBQ627PWTYyZ2ZjrmFc5VD\u002BQVx1Q=","xKskvcoJU0RVRN1a5dRqKRM7IP5vmmbraUaPFYjhnCc=","p7BjQw7aSZjfOCqmKm7/kPO9qegEQZBfirMjlOx/I1I=","MI0hVVLYavEhzHq/Z1UbajfrxanA1aET19aOH8G2ImI=","2dY8CqW9fAY8yN0foa\u002BZp2gc0RfPoPmB/tKSj1QoTw0=","79rfGLH4UjfTPvc//\u002BZjnBqdz585pUtYZ0/hwE2iEic=","PUqgvMdfTQkF5lpBVtHv2teQLV5WaEH0xMKTmINe2YQ=","\u002BFI0b4ppdxel/pby/y/xKImHrtdxo2g83OhskdREyIg=","jEESu6\u002BhbDvNMjLt/6OufuK\u002B9cHmzx\u002BTCIn4fWa9nSc=","UaCPJEvR4nVxxGCB5CUnRlJiw4drDW3Q3Nss\u002Bya2cv4=","ZqF13CT3rok/Gzl\u002BMsw3q9X1nf65bwEVD670efE3k\u002Bk=","gH3W7phPzBCY1DAVn4YnP4SA8Uaq73TpctS0yFSvzNM=","u5F4J4\u002BLHUIOCz5ze5NSF42mDeAaAfi\u002BKN3Ay3rKLY8=","GeUUID0ymF5rrBWdX7YHzWA5GiGkNWCNUog4sp4xL3c=","3BxX4I0JXoDqmE8m0BrRZhixBRlHEueS3jAlmUXE/I8=","IlET7uqumshgFxIEvfKRskON\u002BeAKZ7OfD/kCeAwn0PM=","NN2rS\u002B89ZAITWlNODPcF/lHIh3ZNmAHvUX4EjqSkX4s=","OE89N/FsYhRU1Dy5Ne83ehzSwlNc/RcxHrJpHxPHfqY=","QI7IL4TkYEqfUiIEXQiVCaZx4vrM9/wZlvOrhnUd4jQ=","UIntj4QoiyGr7bnJN8KK5PGrhQd89m\u002BLfh4T8VKPxAk=","J\u002Bfv/j3QyIW9bxolc46wDka8641F622/QgIllt0Re80=","Y/o0rakw9VYzEfz9M659qW77P9kvz\u002B2gTe1Lv3zgUDE=","8QWUReqP8upfOnmA5lMNgBxAfYJ1z3zv/WYBUXBEiog=","1L7p1HQI/Uoosqm7RyBuYjKbRFTycFgJEtHPSdlXWhU=","ZxPpBx5gkHuilHLcg/vcjvaXswvTqiUM0YaAEwbNSLI=","zSbNtRd32h6wCMWjU5ecl5a3ECd\u002BVBstFC3etkdk4s0=","urIQ/RlknPjR8\u002BeAcCsDIPiRjQGFfUdIC\u002BoT3wYB2dU=","0GIIj19uQyjDIXFgf3aZC3MWTTr0ockrC95FYCZEyN4=","BY4GeeFiQbYpWuSzb2XIY4JatmLNOZ6dhKs4ZT92nsM=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","YscOvhINdry\u002BI95UO\u002BBCycn6KSJEZQzHtH6Q7oRYqCI="],"CachedAssets":{},"CachedCopyCandidates":{}} | ||||
| @@ -0,0 +1,13 @@ | ||||
| // src/Elecciones.Core/DTOs/ApiResponses/Tablas/ResultadoFilaDto.cs | ||||
| namespace Elecciones.Core.DTOs.ApiResponses.Tablas; | ||||
|  | ||||
| public class ResultadoFilaDto | ||||
| { | ||||
|   public int AmbitoId { get; set; } | ||||
|   public string Nombre { get; set; } = string.Empty; | ||||
|   public int Orden { get; set; } | ||||
|   public string? Fuerza1Display { get; set; } | ||||
|   public decimal Fuerza1Porcentaje { get; set; } | ||||
|   public string? Fuerza2Display { get; set; } | ||||
|   public decimal Fuerza2Porcentaje { get; set; } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| // src/Elecciones.Core/DTOs/ApiResponses/Tablas/ResultadoSeccionDto.cs | ||||
| namespace Elecciones.Core.DTOs.ApiResponses.Tablas; | ||||
|  | ||||
| public class ResultadoSeccionDto | ||||
| { | ||||
|   public string SeccionId { get; set; } = string.Empty; | ||||
|   public string Nombre { get; set; } = string.Empty; | ||||
|   public List<ResultadoFilaDto> Municipios { get; set; } = new(); | ||||
| } | ||||
| @@ -13,7 +13,7 @@ using System.Reflection; | ||||
| [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Core")] | ||||
| [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | ||||
| [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+0ee092d6edd7454ee43318dc4c7e3d6f5348bff1")] | ||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+3c364ef373330eaa052fa0d2aad92e71d0bfd7df")] | ||||
| [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Core")] | ||||
| [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Core")] | ||||
| [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||
|   | ||||
| @@ -23,6 +23,7 @@ public class EleccionesDbContext(DbContextOptions<EleccionesDbContext> options) | ||||
|     public DbSet<CandidatoOverride> CandidatosOverrides { get; set; } | ||||
|     public DbSet<Eleccion> Elecciones { get; set; } | ||||
|     public DbSet<BancaPrevia> BancasPrevias { get; set; } | ||||
|     public DbSet<Conurbano> Conurbano { get; set; } | ||||
|  | ||||
|     protected override void OnModelCreating(ModelBuilder modelBuilder) | ||||
|     { | ||||
|   | ||||
							
								
								
									
										14
									
								
								Elecciones-Web/src/Elecciones.Database/Entities/Conurbano.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Elecciones-Web/src/Elecciones.Database/Entities/Conurbano.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| // src/Elecciones.Database/Entities/Conurbano.cs | ||||
| using System.ComponentModel.DataAnnotations; | ||||
| using System.ComponentModel.DataAnnotations.Schema; | ||||
|  | ||||
| namespace Elecciones.Database.Entities; | ||||
|  | ||||
| [Table("Conurbano")] | ||||
| public class Conurbano | ||||
| { | ||||
|   [Key] | ||||
|   public int AmbitoGeograficoId { get; set; } | ||||
|  | ||||
|   public int Orden { get; set; } | ||||
| } | ||||
| @@ -13,7 +13,7 @@ using System.Reflection; | ||||
| [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Database")] | ||||
| [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | ||||
| [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+0ee092d6edd7454ee43318dc4c7e3d6f5348bff1")] | ||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+3c364ef373330eaa052fa0d2aad92e71d0bfd7df")] | ||||
| [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Database")] | ||||
| [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Database")] | ||||
| [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||
|   | ||||
| @@ -13,7 +13,7 @@ using System.Reflection; | ||||
| [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Infrastructure")] | ||||
| [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | ||||
| [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+0ee092d6edd7454ee43318dc4c7e3d6f5348bff1")] | ||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+3c364ef373330eaa052fa0d2aad92e71d0bfd7df")] | ||||
| [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Infrastructure")] | ||||
| [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Infrastructure")] | ||||
| [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user