Showing
7 changed files
with
78 additions
and
40 deletions
| ... | @@ -102,14 +102,7 @@ | ... | @@ -102,14 +102,7 @@ |
| 102 | codigo = String(meta.municipio_ubigeo || ''); | 102 | codigo = String(meta.municipio_ubigeo || ''); |
| 103 | tipo = 'ubigeo'; | 103 | tipo = 'ubigeo'; |
| 104 | } else if (isClass && cls === 'acteco') { | 104 | } else if (isClass && cls === 'acteco') { |
| 105 | - const s = meta.acteco_sector != null ? String(Math.round(meta.acteco_sector)) : ''; | 105 | + codigo = meta.acteco_actividad_armonizado || meta.acteco_subsector_armonizado || meta.acteco_sector_armonizado || ''; |
| 106 | - if (s) { | ||
| 107 | - codigo = s; | ||
| 108 | - if (meta.acteco_subsector != null) { | ||
| 109 | - codigo += '.' + Math.round(meta.acteco_subsector); | ||
| 110 | - if (meta.acteco_actividad != null) codigo += '.' + Math.round(meta.acteco_actividad); | ||
| 111 | - } | ||
| 112 | - } | ||
| 113 | tipo = 'acteco'; | 106 | tipo = 'acteco'; |
| 114 | } else if (!isClass) { | 107 | } else if (!isClass) { |
| 115 | // Programa/proyecto | 108 | // Programa/proyecto | ... | ... |
| ... | @@ -796,10 +796,7 @@ | ... | @@ -796,10 +796,7 @@ |
| 796 | } else if (isFinfunClass) { | 796 | } else if (isFinfunClass) { |
| 797 | url = `/finfun/${getFinfunCodigo(meta)}`; | 797 | url = `/finfun/${getFinfunCodigo(meta)}`; |
| 798 | } else if (hit.document.class_ === 'acteco') { | 798 | } else if (hit.document.class_ === 'acteco') { |
| 799 | - const s = String(meta.acteco_sector ? Math.round(meta.acteco_sector) : ''); | 799 | + const code = meta.acteco_actividad_armonizado || meta.acteco_subsector_armonizado || meta.acteco_sector_armonizado || ''; |
| 800 | - let code = s; | ||
| 801 | - if (meta.acteco_actividad !== undefined && meta.acteco_subsector !== undefined) code = `${s}.${Math.round(meta.acteco_subsector)}.${Math.round(meta.acteco_actividad)}`; | ||
| 802 | - else if (meta.acteco_subsector !== undefined) code = `${s}.${Math.round(meta.acteco_subsector)}`; | ||
| 803 | url = `/acteco/${code}`; | 800 | url = `/acteco/${code}`; |
| 804 | } else if (hit.document.class_ === 'rubro') { | 801 | } else if (hit.document.class_ === 'rubro') { |
| 805 | const code = meta.rubro_sub_cuenta || meta.rubro_cuenta || meta.rubro_clase || meta.rubro_tipo || ''; | 802 | const code = meta.rubro_sub_cuenta || meta.rubro_cuenta || meta.rubro_clase || meta.rubro_tipo || ''; |
| ... | @@ -1438,7 +1435,7 @@ | ... | @@ -1438,7 +1435,7 @@ |
| 1438 | {@const isOrganismoClass = hit.document.class_ === 'organismo'} | 1435 | {@const isOrganismoClass = hit.document.class_ === 'organismo'} |
| 1439 | {@const isClassResult = hit.document.is_class === true} | 1436 | {@const isClassResult = hit.document.is_class === true} |
| 1440 | {@const hitType = CLASS_REVERSE_MAP[hit.document.class_] || hit.document.class_} | 1437 | {@const hitType = CLASS_REVERSE_MAP[hit.document.class_] || hit.document.class_} |
| 1441 | - {@const actecoCode = isActecoClass ? (() => { const s = String(meta.acteco_sector ? Math.round(meta.acteco_sector) : ''); if (meta.acteco_actividad !== undefined && meta.acteco_subsector !== undefined) return `${s}.${Math.round(meta.acteco_subsector)}.${Math.round(meta.acteco_actividad)}`; if (meta.acteco_subsector !== undefined) return `${s}.${Math.round(meta.acteco_subsector)}`; return s; })() : ''} | 1438 | + {@const actecoCode = isActecoClass ? (meta.acteco_actividad_armonizado || meta.acteco_subsector_armonizado || meta.acteco_sector_armonizado || '') : ''} |
| 1442 | {@const rubroCode = isRubroClass ? (meta.rubro_sub_cuenta || meta.rubro_cuenta || meta.rubro_clase || meta.rubro_tipo || '') : ''} | 1439 | {@const rubroCode = isRubroClass ? (meta.rubro_sub_cuenta || meta.rubro_cuenta || meta.rubro_clase || meta.rubro_tipo || '') : ''} |
| 1443 | <a | 1440 | <a |
| 1444 | href={isEntidadClass | 1441 | href={isEntidadClass | ... | ... |
| ... | @@ -42,15 +42,8 @@ | ... | @@ -42,15 +42,8 @@ |
| 42 | const doc = hit.document || {}; | 42 | const doc = hit.document || {}; |
| 43 | let meta = {}; | 43 | let meta = {}; |
| 44 | try { meta = typeof doc.metadatos === 'string' ? JSON.parse(doc.metadatos) : (doc.metadatos || {}); } catch {} | 44 | try { meta = typeof doc.metadatos === 'string' ? JSON.parse(doc.metadatos) : (doc.metadatos || {}); } catch {} |
| 45 | - const s = meta.acteco_sector != null ? String(Math.round(meta.acteco_sector)) : ''; | 45 | + const code = meta.acteco_actividad_armonizado || meta.acteco_subsector_armonizado || meta.acteco_sector_armonizado || ''; |
| 46 | - if (!s) return null; | 46 | + if (!code) return null; |
| 47 | - let code = s; | ||
| 48 | - if (meta.acteco_subsector != null) { | ||
| 49 | - code += '.' + Math.round(meta.acteco_subsector); | ||
| 50 | - if (meta.acteco_actividad != null) { | ||
| 51 | - code += '.' + Math.round(meta.acteco_actividad); | ||
| 52 | - } | ||
| 53 | - } | ||
| 54 | return { code, label: doc.texto || '' }; | 47 | return { code, label: doc.texto || '' }; |
| 55 | }).filter(Boolean); | 48 | }).filter(Boolean); |
| 56 | } catch { | 49 | } catch { | ... | ... |
src/routes/api/ubigeo-todo/+server.js
0 → 100644
| 1 | +import { API_HOST } from '$lib/api.js'; | ||
| 2 | +const API_BASE = API_HOST + '/api/ubigeo/todo'; | ||
| 3 | + | ||
| 4 | +export async function GET({ url }) { | ||
| 5 | + const gestion = url.searchParams.get('gestion') || ''; | ||
| 6 | + | ||
| 7 | + const apiUrl = new URL(API_BASE); | ||
| 8 | + if (gestion) apiUrl.searchParams.set('gestion', gestion); | ||
| 9 | + | ||
| 10 | + try { | ||
| 11 | + const response = await fetch(apiUrl.toString()); | ||
| 12 | + if (!response.ok) { | ||
| 13 | + return new Response(JSON.stringify({ error: `API error: ${response.status}` }), { | ||
| 14 | + status: response.status, headers: { 'Content-Type': 'application/json' } | ||
| 15 | + }); | ||
| 16 | + } | ||
| 17 | + const data = await response.json(); | ||
| 18 | + return new Response(JSON.stringify(data), { | ||
| 19 | + headers: { 'Content-Type': 'application/json' } | ||
| 20 | + }); | ||
| 21 | + } catch { | ||
| 22 | + return new Response(JSON.stringify({ error: 'Failed to fetch' }), { | ||
| 23 | + status: 500, headers: { 'Content-Type': 'application/json' } | ||
| 24 | + }); | ||
| 25 | + } | ||
| 26 | +} |
| ... | @@ -96,7 +96,7 @@ | ... | @@ -96,7 +96,7 @@ |
| 96 | <!-- Completo --> | 96 | <!-- Completo --> |
| 97 | <div class="section"> | 97 | <div class="section"> |
| 98 | <h2 class="section-title">Completo</h2> | 98 | <h2 class="section-title">Completo</h2> |
| 99 | - <a href={buildUrl('completo', 'ultimo')} class="download-link"> | 99 | + <a href={buildUrl('completo', 'ultimo')} download rel="external" class="download-link"> |
| 100 | <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg> | 100 | <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg> |
| 101 | Descargar todo ({dataset === 'gasto' ? 'gastos' : 'ingresos'}) | 101 | Descargar todo ({dataset === 'gasto' ? 'gastos' : 'ingresos'}) |
| 102 | </a> | 102 | </a> |
| ... | @@ -107,7 +107,7 @@ | ... | @@ -107,7 +107,7 @@ |
| 107 | <h2 class="section-title">Por gestión</h2> | 107 | <h2 class="section-title">Por gestión</h2> |
| 108 | <div class="year-grid"> | 108 | <div class="year-grid"> |
| 109 | {#each YEARS as year} | 109 | {#each YEARS as year} |
| 110 | - <a href={buildUrl('gestion', year)} class="year-link">{year}</a> | 110 | + <a href={buildUrl('gestion', year)} download rel="external" class="year-link">{year}</a> |
| 111 | {/each} | 111 | {/each} |
| 112 | </div> | 112 | </div> |
| 113 | </div> | 113 | </div> |
| ... | @@ -155,7 +155,7 @@ | ... | @@ -155,7 +155,7 @@ |
| 155 | {#if selectedEntity} | 155 | {#if selectedEntity} |
| 156 | <div class="entity-result"> | 156 | <div class="entity-result"> |
| 157 | <span class="entity-name">{selectedEntity.desc_entidad}</span> | 157 | <span class="entity-name">{selectedEntity.desc_entidad}</span> |
| 158 | - <a href={buildUrl('entidad', selectedEntity.entidad)} class="download-link"> | 158 | + <a href={buildUrl('entidad', selectedEntity.entidad)} download rel="external" class="download-link"> |
| 159 | <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg> | 159 | <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg> |
| 160 | Descargar | 160 | Descargar |
| 161 | </a> | 161 | </a> | ... | ... |
| 1 | export const ssr = false; | 1 | export const ssr = false; |
| 2 | 2 | ||
| 3 | export async function load({ fetch }) { | 3 | export async function load({ fetch }) { |
| 4 | - const pobRes = await fetch('/poblacion.csv').then(r => r.text()); | 4 | + const [pobRes, ubigeoRes] = await Promise.all([ |
| 5 | + fetch('/poblacion.csv').then(r => r.text()), | ||
| 6 | + fetch('/api/ubigeo-todo?gestion=2025').then(r => r.json()) | ||
| 7 | + ]); | ||
| 5 | 8 | ||
| 6 | const poblacionMap = {}; | 9 | const poblacionMap = {}; |
| 7 | pobRes.split('\n').slice(1).forEach(line => { | 10 | pobRes.split('\n').slice(1).forEach(line => { |
| ... | @@ -11,10 +14,22 @@ export async function load({ fetch }) { | ... | @@ -11,10 +14,22 @@ export async function load({ fetch }) { |
| 11 | } | 14 | } |
| 12 | }); | 15 | }); |
| 13 | 16 | ||
| 17 | + const resumen = (ubigeoRes || []) | ||
| 18 | + .filter(d => d.ubigeo !== '0.0.0' && !d.ubigeo.endsWith('.0') && !/multimunicipal/i.test(d.desc_ubigeo) && !/multiprovincial/i.test(d.desc_ubigeo) && !/desconocido/i.test(d.desc_ubigeo)) | ||
| 19 | + .map(d => ({ | ||
| 20 | + codigo: d.ubigeo, | ||
| 21 | + desc: d.desc_ubigeo, | ||
| 22 | + gestion: d.gestion, | ||
| 23 | + devengado: d.monto, | ||
| 24 | + ranking: d.ranking, | ||
| 25 | + per_capita: d.per_capita, | ||
| 26 | + departamento: d.desc_departamento | ||
| 27 | + })); | ||
| 28 | + | ||
| 14 | const gestiones = [2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025]; | 29 | const gestiones = [2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025]; |
| 15 | 30 | ||
| 16 | return { | 31 | return { |
| 17 | - resumen: [], | 32 | + resumen, |
| 18 | poblacionMap, | 33 | poblacionMap, |
| 19 | gestiones, | 34 | gestiones, |
| 20 | gestionInicial: 2025 | 35 | gestionInicial: 2025 | ... | ... |
| ... | @@ -66,10 +66,7 @@ | ... | @@ -66,10 +66,7 @@ |
| 66 | return fin; | 66 | return fin; |
| 67 | }}, | 67 | }}, |
| 68 | acteco: { class_: 'acteco', codigoFn: (meta) => { | 68 | acteco: { class_: 'acteco', codigoFn: (meta) => { |
| 69 | - const s = String(meta.acteco_sector ? Math.round(meta.acteco_sector) : ''); | 69 | + return meta.acteco_actividad_armonizado || meta.acteco_subsector_armonizado || meta.acteco_sector_armonizado || ''; |
| 70 | - if (meta.acteco_actividad !== undefined) return `${s}.${Math.round(meta.acteco_subsector)}.${Math.round(meta.acteco_actividad)}`; | ||
| 71 | - if (meta.acteco_subsector !== undefined) return `${s}.${Math.round(meta.acteco_subsector)}`; | ||
| 72 | - return s; | ||
| 73 | }}, | 70 | }}, |
| 74 | }; | 71 | }; |
| 75 | 72 | ||
| ... | @@ -204,12 +201,7 @@ | ... | @@ -204,12 +201,7 @@ |
| 204 | const map = {}; | 201 | const map = {}; |
| 205 | const esClasificador = clasificadorSeleccionado !== 'total' && clasSeleccionado; | 202 | const esClasificador = clasificadorSeleccionado !== 'total' && clasSeleccionado; |
| 206 | resumen.forEach(d => { | 203 | resumen.forEach(d => { |
| 207 | - let val; | 204 | + const val = modoPerCapita ? (d.per_capita || 0) : d.devengado; |
| 208 | - if (modoPerCapita) { | ||
| 209 | - val = esClasificador ? (d.per_capita || 0) : (poblacionMap[d.codigo] ? d.devengado / poblacionMap[d.codigo] : d.devengado); | ||
| 210 | - } else { | ||
| 211 | - val = d.devengado; | ||
| 212 | - } | ||
| 213 | map[d.codigo] = { ...d, valor: val }; | 205 | map[d.codigo] = { ...d, valor: val }; |
| 214 | }); | 206 | }); |
| 215 | return map; | 207 | return map; |
| ... | @@ -378,9 +370,31 @@ | ... | @@ -378,9 +370,31 @@ |
| 378 | return; | 370 | return; |
| 379 | } | 371 | } |
| 380 | 372 | ||
| 381 | - // Modo total: datos no disponibles sin Supabase | 373 | + // Modo total: cargar gasto agregado por municipio |
| 382 | - // TODO: implementar endpoint API para resumen por municipio | 374 | + const key = `total_${gestion}`; |
| 375 | + if (resumenCache[key]) { | ||
| 376 | + resumen = resumenCache[key]; | ||
| 377 | + } else { | ||
| 378 | + try { | ||
| 379 | + const res = await fetch(`/api/ubigeo-todo?gestion=${gestion}`); | ||
| 380 | + const data = await res.json(); | ||
| 381 | + const mapped = (data || []) | ||
| 382 | + .filter(d => d.ubigeo !== '0.0.0' && !d.ubigeo.endsWith('.0') && !/multimunicipal/i.test(d.desc_ubigeo) && !/multiprovincial/i.test(d.desc_ubigeo) && !/desconocido/i.test(d.desc_ubigeo)) | ||
| 383 | + .map(d => ({ | ||
| 384 | + codigo: d.ubigeo, | ||
| 385 | + desc: d.desc_ubigeo, | ||
| 386 | + gestion: d.gestion, | ||
| 387 | + devengado: d.monto, | ||
| 388 | + ranking: d.ranking, | ||
| 389 | + per_capita: d.per_capita, | ||
| 390 | + departamento: d.desc_departamento | ||
| 391 | + })); | ||
| 392 | + resumenCache[key] = mapped; | ||
| 393 | + resumen = mapped; | ||
| 394 | + } catch { | ||
| 383 | resumen = []; | 395 | resumen = []; |
| 396 | + } | ||
| 397 | + } | ||
| 384 | poblacionMap = await getPoblacionAno(gestion); | 398 | poblacionMap = await getPoblacionAno(gestion); |
| 385 | } | 399 | } |
| 386 | 400 | ||
| ... | @@ -668,7 +682,7 @@ | ... | @@ -668,7 +682,7 @@ |
| 668 | <path d={pathGen(mapaData.bolivia)} class="mapa-pais-fill" /> | 682 | <path d={pathGen(mapaData.bolivia)} class="mapa-pais-fill" /> |
| 669 | <path d={pathGen(mapaData.bolivia)} class="mapa-pais-outline" /> | 683 | <path d={pathGen(mapaData.bolivia)} class="mapa-pais-outline" /> |
| 670 | {#each mapaData.municipios.features as feat} | 684 | {#each mapaData.municipios.features as feat} |
| 671 | - {@const cod = clasificadorSeleccionado !== 'total' ? feat.properties.ubigeo : String(feat.properties.codigo)} | 685 | + {@const cod = feat.properties.ubigeo} |
| 672 | {@const datos = datosPorCodigo[cod]} | 686 | {@const datos = datosPorCodigo[cod]} |
| 673 | {@const visible = enRango(cod)} | 687 | {@const visible = enRango(cod)} |
| 674 | {@const color = datos && visible ? colorScale(datos.valor) : 'transparent'} | 688 | {@const color = datos && visible ? colorScale(datos.valor) : 'transparent'} | ... | ... |
-
Please register or login to post a comment