pr0nstar

VI

__pycache__/
*.pyc
.codex
......
......@@ -15,7 +15,8 @@ from aiocache import caches
from presupuestov1.routers import (
project,
entity,
classifier
classifier,
daily,
)
......@@ -28,7 +29,7 @@ logging.getLogger('api_proy2').setLevel(logging.DEBUG)
app = FastAPI(
title='Jorvi API',
title='MEFP presupuestosv1 API',
middleware=[
Middleware(
RawContextMiddleware,
......@@ -44,6 +45,7 @@ app.include_router(entity.router)
app.include_router(classifier.router_objeto)
app.include_router(classifier.router_acteco)
app.include_router(classifier.router_finfun)
app.include_router(daily.router)
......
......@@ -4,4 +4,5 @@ from . import (
finfun,
objeto,
treemap,
daily,
)
......
......@@ -14,6 +14,10 @@ from sqlalchemy.dialects.postgresql import JSONB
from typing import Any
###############################################################################
# Gasto
###############################################################################
class ClasInstitucional(Base):
__tablename__ = "clas_institucional"
__table_args__ = (
......@@ -45,16 +49,8 @@ class ClasInstitucional(Base):
n_gestiones: Mapped[int | None] = mapped_column(Integer)
class ClasObjetos(Base):
__tablename__ = "clas_objetos"
__table_args__ = (
Index("idx_clas_objetos_entidad", "objeto"),
{"schema": "web"},
)
class ClasBase():
nivel: Mapped[str | None] = mapped_column(Text)
objeto: Mapped[str] = mapped_column(Text, primary_key=True)
desc_objeto: Mapped[str | None] = mapped_column(Text)
gestiones: Mapped[str | None] = mapped_column(Text)
n_gestiones: Mapped[int | None] = mapped_column(Integer)
......@@ -63,55 +59,98 @@ class ClasObjetos(Base):
descripciones: Mapped[list[dict[str, Any]] | None] = mapped_column(JSONB)
class ClasRubros(Base):
__tablename__ = "clas_rubros"
class ClasObjetos(ClasBase, Base):
__tablename__ = "clas_objetos"
__table_args__ = (
Index("idx_clas_rubros_entidad", "rubro"),
Index("idx_clas_objetos_entidad", "objeto"),
{"schema": "web"},
)
nivel: Mapped[str | None] = mapped_column(Text)
rubro: Mapped[str] = mapped_column(Text, primary_key=True)
desc_rubro: Mapped[str | None] = mapped_column(Text)
gestiones: Mapped[str | None] = mapped_column(Text)
n_gestiones: Mapped[int | None] = mapped_column(Integer)
n_variaciones: Mapped[int | None] = mapped_column(Integer)
descripciones: Mapped[list[dict[str, Any]] | None] = mapped_column(JSONB)
objeto: Mapped[str] = mapped_column(Text, primary_key=True)
desc_objeto: Mapped[str | None] = mapped_column(Text)
class ClasFinfun(Base):
class ClasFinfun(ClasBase, Base):
__tablename__ = "clas_finfun"
__table_args__ = (
Index("idx_clas_finfun_entidad", "finfun"),
{"schema": "web"},
)
nivel: Mapped[str | None] = mapped_column(Text)
finfun: Mapped[str] = mapped_column(Text, primary_key=True)
desc_finfun: Mapped[str | None] = mapped_column(Text)
gestiones: Mapped[str | None] = mapped_column(Text)
n_gestiones: Mapped[int | None] = mapped_column(Integer)
n_variaciones: Mapped[int | None] = mapped_column(Integer)
descripciones: Mapped[list[dict[str, Any]] | None] = mapped_column(JSONB)
class ClasActeco(Base):
class ClasActeco(ClasBase, Base):
__tablename__ = "clas_acteco"
__table_args__ = (
Index("idx_clas_acteco_entidad", "acteco"),
{"schema": "web"},
)
nivel: Mapped[str | None] = mapped_column(Text)
acteco: Mapped[str] = mapped_column(Text, primary_key=True)
desc_acteco: Mapped[str | None] = mapped_column(Text)
class ClasGeografico(ClasBase, Base):
__tablename__ = "clas_geografico"
__table_args__ = (
Index("idx_clas_geografico_ubigeo", "ubigeo"),
{"schema": "web"},
)
ubigeo: Mapped[str] = mapped_column(Text, primary_key=True)
desc_ubigeo: Mapped[str | None] = mapped_column(Text)
municipio_ubigeo: Mapped[int | None] = mapped_column(Integer)
###############################################################################
# Ingreso
###############################################################################
class ClasRubros(ClasBase, Base):
__tablename__ = "clas_rubros"
__table_args__ = (
Index("idx_clas_rubros_entidad", "rubro"),
{"schema": "web"},
)
rubro: Mapped[str] = mapped_column(Text, primary_key=True)
desc_rubro: Mapped[str | None] = mapped_column(Text)
class ClasFuentes(ClasBase, Base):
__tablename__ = "clas_fuentes"
__table_args__ = (
Index("idx_clas_fuentes_fuente", "fuente"),
{"schema": "web"},
)
fuente: Mapped[int] = mapped_column(Integer, primary_key=True)
desc_fuente: Mapped[str] = mapped_column(Text)
grupo_fuente: Mapped[int] = mapped_column(Integer)
desc_grupo_fuente: Mapped[str] = mapped_column(Text)
class ClasOrganismos(Base):
__tablename__ = "clas_organismos"
__table_args__ = (
Index("idx_clas_organismos_organismo", "organismo"),
{"schema": "web"},
)
organismo: Mapped[int] = mapped_column(Integer, primary_key=True)
desc_organismo: Mapped[str] = mapped_column(Text)
sigla_organismo: Mapped[str] = mapped_column(String(20))
organismo_grupo: Mapped[int] = mapped_column(Integer)
desc_organismo_grupo: Mapped[str] = mapped_column(Text)
sigla_organismo_grupo: Mapped[str] = mapped_column(String(20))
organismo_subgrupo: Mapped[int] = mapped_column(Integer)
desc_organismo_subgrupo: Mapped[str] = mapped_column(Text)
sigla_organismo_subgrupo: Mapped[str] = mapped_column(String(20))
gestiones: Mapped[str | None] = mapped_column(Text)
n_gestiones: Mapped[int | None] = mapped_column(Integer)
n_variaciones: Mapped[int | None] = mapped_column(Integer)
descripciones: Mapped[list[dict[str, Any]] | None] = mapped_column(JSONB)
......
from sqlalchemy.orm import Mapped, mapped_column
from presupuestov1.model import Base
from sqlalchemy import (
Integer,
String,
Text,
Numeric,
Index,
MetaData,
Boolean,
DateTime
)
from datetime import datetime
class UpdateStatus(Base):
__tablename__ = "diario_status"
__table_args__ = (
{"schema": "web"},
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
fecha_actualizacion: Mapped[datetime] = mapped_column(DateTime)
status: Mapped[bool] = mapped_column(Boolean)
class EjecucionClasificadores(Base):
__tablename__ = "diario_ejecucion_clasificadores"
__table_args__ = (
Index("idx_ejecucion_clasificadores_dias", "dias"),
Index("idx_ejecucion_clasificadores_transferencias", "transferencias"),
{"schema": "web"},
)
id: Mapped[int] = mapped_column(Integer, primary_key=True)
transferencias: Mapped[bool] = mapped_column(Boolean)
dias: Mapped[int] = mapped_column(Integer)
clasificador: Mapped[str] = mapped_column(String(48))
devengado: Mapped[float] = mapped_column(Numeric(30, 15))
padre: Mapped[str] = mapped_column(Text)
hijo: Mapped[str] = mapped_column(Text)
class EjecucionEntidades(Base):
__tablename__ = "diario_ejecucion_entidades"
__table_args__ = (
Index("idx_ejecucion_entidades_dias", "dias"),
Index("idx_ejecucion_entidades_transferencias", "transferencias"),
Index("idx_ejecucion_entidades_entidad", "entidad"),
{"schema": "web"},
)
id: Mapped[int] = mapped_column(Integer, primary_key=True)
transferencias: Mapped[bool] = mapped_column(Boolean)
dias: Mapped[int] = mapped_column(Integer)
entidad: Mapped[int] = mapped_column(Integer)
vigente: Mapped[float] = mapped_column(Numeric(30, 15))
devengado: Mapped[float] = mapped_column(Numeric(30, 15))
ejecucion: Mapped[float] = mapped_column(Numeric)
entidad_desc_area: Mapped[str] = mapped_column(Text)
entidad_desc_entidad: Mapped[str] = mapped_column(Text)
class Timeline(Base):
__tablename__ = "diario_timeline"
__table_args__ = (
Index("idx_diario_timeline_entidad", "entidad"),
{"schema": "web"},
)
id: Mapped[int] = mapped_column(Integer, primary_key=True)
entidad: Mapped[int] = mapped_column(Integer)
devengado: Mapped[float] = mapped_column(Numeric(30, 15))
entidad_desc_area: Mapped[str] = mapped_column(Text)
entidad_desc_entidad: Mapped[str] = mapped_column(Text)
desc_programa: Mapped[str] = mapped_column(Text)
desc_actividad_proyecto: Mapped[str] = mapped_column(Text)
class TimeSeries(Base):
__tablename__ = "diario_timeseries"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
fecha: Mapped[str] = mapped_column(String(10))
devengado: Mapped[float] = mapped_column(Numeric(30, 15))
diferencia: Mapped[float] = mapped_column(Numeric(30, 15))
dias: Mapped[int] = mapped_column(Integer)
......@@ -9,6 +9,7 @@ from sqlalchemy import (
Index,
MetaData,
)
from sqlalchemy import and_, or_
class TreemapObjeto(Base):
......@@ -23,14 +24,17 @@ class TreemapObjeto(Base):
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
gestion: Mapped[int] = mapped_column(Integer)
entidad_area: Mapped[str | None] = mapped_column(String(9))
entidad: Mapped[int] = mapped_column(Integer)
objeto: Mapped[int] = mapped_column(Integer)
nivel: Mapped[str | None] = mapped_column(String(20))
desc_objeto: Mapped[str | None] = mapped_column(Text)
parent: Mapped[int | None] = mapped_column(Integer)
devengado: Mapped[float | None] = mapped_column(Numeric(30, 15))
desc_entidad: Mapped[str | None] = mapped_column(Text)
desc_objeto: Mapped[str | None] = mapped_column(Text)
class TreemapFinFun(Base):
__tablename__ = "treemap_finfun"
......@@ -44,14 +48,17 @@ class TreemapFinFun(Base):
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
gestion: Mapped[int] = mapped_column(Integer)
entidad_area: Mapped[str | None] = mapped_column(String(9))
entidad: Mapped[int] = mapped_column(Integer)
finfun: Mapped[str] = mapped_column(String(9))
nivel: Mapped[str | None] = mapped_column(String(20))
desc_finfun: Mapped[str | None] = mapped_column(Text)
parent: Mapped[str | None] = mapped_column(String(9))
devengado: Mapped[float | None] = mapped_column(Numeric(30, 15))
desc_entidad: Mapped[str | None] = mapped_column(Text)
desc_finfun: Mapped[str | None] = mapped_column(Text)
class TreemapActeco(Base):
__tablename__ = "treemap_acteco"
......@@ -65,14 +72,17 @@ class TreemapActeco(Base):
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
gestion: Mapped[int] = mapped_column(Integer)
entidad_area: Mapped[str | None] = mapped_column(String(9))
entidad: Mapped[int] = mapped_column(Integer)
acteco: Mapped[str] = mapped_column(String(9))
nivel: Mapped[str | None] = mapped_column(String(20))
desc_acteco: Mapped[str | None] = mapped_column(Text)
parent: Mapped[str | None] = mapped_column(String(9))
devengado: Mapped[float | None] = mapped_column(Numeric(30, 15))
desc_entidad: Mapped[str | None] = mapped_column(Text)
desc_acteco: Mapped[str | None] = mapped_column(Text)
###############################################################################
# fns
......@@ -90,7 +100,10 @@ def get_clas_entities(query_filters, db, query, ClassObject, object_id):
if query.gestion is None:
query.gestion = 0
query_filters.append(ClassObject.gestion == query.gestion)
query_filters.extend([
ClassObject.devengado > 0,
ClassObject.gestion == query.gestion,
])
if query.id is not None:
ids = query.id.split(',')
......
......@@ -26,6 +26,11 @@ router_finfun = APIRouter(
tags=['finfun'],
)
router_ubigeo = APIRouter(
prefix='/ubigeo',
tags=['ubigeo'],
)
###############################################################################
# GET
......@@ -46,21 +51,50 @@ def fetch_object_classifier(db: Session = Depends(model.get_db)):
return _fetch_classifier('finfun', db)
@router_objeto.get('/{object_id}', response_model=schemas.classifier.ClasObjetos)
def fetch_clas(
@router_ubigeo.get('/clasificador', response_model=List[schemas.classifier.ClasGeografico])
def fetch_object_classifier(db: Session = Depends(model.get_db)):
return _fetch_classifier('ubigeo', db)
@router_objeto.get('/{object_id}', response_model=schemas.objeto.ClasObjetosEstados)
def fetch_objeto_estado(
object_id: str,
db: Session = Depends(model.get_db),
):
ClasEstado = models.objeto.ObjetoEstado
estados = db.query(ClasEstado).filter(
ClasEstado.objeto == object_id,
).all()
ClasObjetos = models.classifier.ClasObjetos
return db.query(ClasObjetos).filter(
ClasObjetos.objeto == '{}.0'.format(object_id)
objeto = db.query(ClasObjetos).filter(
ClasObjetos.objeto == object_id
).one()
setattr(objeto, 'estados', estados)
return objeto
@router_objeto.get('/{object_id}/entidades', response_model=List[schemas.objeto.ObjetoEntidad])
def fetch_objeto_entidad(
object_id: str,
db: Session = Depends(model.get_db),
query: schema.QueryParams = Depends(),
):
gestion = query.gestion or 0
ClasObjetos = models.objeto.ObjetoEntidad
return db.query(ClasObjetos).filter(
ClasObjetos.objeto == object_id,
ClasObjetos.gestion == gestion
).all()
@router_objeto.get('/{object_id}/entidades', response_model=List[schemas.treemap.TreemapObjeto])
def fetch_clas(
@router_objeto.get('/{object_id}/entidades/map', response_model=List[schemas.treemap.TreemapObjeto])
def fetch_objeto_treemap(
object_id: str,
db: Session = Depends(model.get_db),
query: schema.QueryParams = Depends(),
):
Treemap = models.treemap.TreemapObjeto
return models.treemap.get_clas_entities(
......@@ -69,21 +103,60 @@ def fetch_clas(
], db, query, Treemap, 'entidad'
)
@router_acteco.get('/{acteco_id}', response_model=schemas.classifier.ClasActeco)
def fetch_clas(
@router_objeto.get('/{object_id}/entidades/{entidad_id}', response_model=List[schemas.objeto.ObjetoEntidad])
def fetch_objeto_entidad_single(
object_id: str,
entidad_id: int,
db: Session = Depends(model.get_db),
query: schema.QueryParams = Depends(),
):
ClasObjetos = models.objeto.ObjetoEntidad
return db.query(ClasObjetos).filter(
ClasObjetos.objeto == object_id,
ClasObjetos.entidad == entidad_id
).all()
@router_acteco.get('/{acteco_id}', response_model=schemas.acteco.ClasActecoEstados)
def fetch_objeto_estado(
acteco_id: str,
db: Session = Depends(model.get_db),
):
ClasEstado = models.objeto.ActecoEstado
estados = db.query(ClasEstado).filter(
ClasEstado.acteco == acteco_id,
).all()
ClasActeco = models.classifier.ClasActeco
return db.query(ClasActeco).filter(
acteco = db.query(ClasActeco).filter(
ClasActeco.acteco == acteco_id
).one()
setattr(acteco, 'estados', estados)
return acteco
@router_acteco.get('/{acteco_id}/entidades', response_model=List[schemas.acteco.ActecoEntidad])
def fetch_acteco_entidad(
acteco_id: str,
db: Session = Depends(model.get_db),
query: schema.QueryParams = Depends(),
):
gestion = query.gestion or 0
ClasObjetos = models.acteco.ActecoEntidad
return db.query(ClasObjetos).filter(
ClasObjetos.acteco == acteco_id,
ClasObjetos.gestion == gestion
).all()
@router_acteco.get('/{acteco_id}/entidades', response_model=List[schemas.treemap.TreemapActeco])
def fetch_clas(
@router_acteco.get('/{acteco_id}/entidades/map', response_model=List[schemas.treemap.TreemapActeco])
def fetch_acteco_treemap(
acteco_id: str,
db: Session = Depends(model.get_db),
query: schema.QueryParams = Depends(),
):
Treemap = models.treemap.TreemapActeco
return models.treemap.get_clas_entities(
......@@ -93,21 +166,60 @@ def fetch_clas(
)
@router_finfun.get('/{finfun_id}', response_model=schemas.classifier.ClasFinfun)
def fetch_clas(
@router_acteco.get('/{acteco_id}/entidades/{entidad_id}', response_model=List[schemas.acteco.ActecoEntidad])
def fetch_acteco_entidad_single(
acteco_id: str,
entidad_id: int,
db: Session = Depends(model.get_db),
query: schema.QueryParams = Depends(),
):
ClasObjetos = models.acteco.ActecoEntidad
return db.query(ClasObjetos).filter(
ClasObjetos.acteco == acteco_id,
ClasObjetos.entidad == entidad_id
).all()
@router_finfun.get('/{finfun_id}', response_model=schemas.finfun.ClasFinfunEstados)
def fetch_finfun_estado(
finfun_id: str,
db: Session = Depends(model.get_db),
):
ClasEstado = models.finfun.FinfunEstado
estados = db.query(ClasEstado).filter(
ClasEstado.finfun == finfun_id
).all()
ClasFinfun = models.classifier.ClasFinfun
return db.query(ClasFinfun).filter(
finfun = db.query(ClasFinfun).filter(
ClasFinfun.finfun == finfun_id
).one()
setattr(finfun, 'estados', estados)
return finfun
@router_finfun.get('/{finfun_id}/entidades', response_model=List[schemas.treemap.TreemapFinFun])
def fetch_clas(
@router_finfun.get('/{finfun_id}/entidades', response_model=List[schemas.finfun.FinfunEntidad])
def fetch_finfun_entidad(
finfun_id: str,
db: Session = Depends(model.get_db),
query: schema.QueryParams = Depends(),
):
gestion = query.gestion or 0
ClasObjetos = models.finfun.FinfunEntidad
return db.query(ClasObjetos).filter(
ClasObjetos.finfun == finfun_id,
ClasObjetos.gestion == gestion
).all()
@router_finfun.get('/{finfun_id}/entidades/map', response_model=List[schemas.treemap.TreemapFinFun])
def fetch_finfun_treemap(
finfun_id: str,
db: Session = Depends(model.get_db),
query: schema.QueryParams = Depends(),
):
Treemap = models.treemap.TreemapFinFun
return models.treemap.get_clas_entities(
......@@ -116,6 +228,19 @@ def fetch_clas(
], db, query, Treemap, 'entidad'
)
@router_finfun.get('/{finfun_id}/entidades/{entidad_id}', response_model=List[schemas.finfun.FinfunEntidad])
def fetch_finfun_entidad_single(
finfun_id: str,
entidad_id: int,
db: Session = Depends(model.get_db),
query: schema.QueryParams = Depends(),
):
ClasObjetos = models.finfun.FinfunEntidad
return db.query(ClasObjetos).filter(
ClasObjetos.finfun == finfun_id,
ClasObjetos.entidad == entidad_id
).all()
###############################################################################
# priv
......@@ -126,5 +251,6 @@ def _fetch_classifier(clas, db):
'objeto': models.classifier.ClasObjetos,
'acteco': models.classifier.ClasActeco,
'finfun': models.classifier.ClasFinfun,
'ubigeo': models.classifier.ClasGeografico,
}[clas]
return db.query(ClassObject).all()
......
from typing import List
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session, aliased
from sqlalchemy import func
from presupuestov1 import model, schema, schemas, models
router = APIRouter(
prefix='/diario',
tags=['diario'],
)
###############################################################################
# GET
###############################################################################
@router.get('/status', response_model=schemas.daily.UpdateStatus)
def fetch_status(
db: Session = Depends(model.get_db),
):
Daily = models.daily.UpdateStatus
return db.query(Daily).order_by(
Daily.fecha_actualizacion.desc()
).first()
@router.get('/clasificadores', response_model=List[schemas.daily.EjecucionClasificadores])
def fetch_clasificadores(
db: Session = Depends(model.get_db),
query: schema.DailyParams = Depends(),
):
Daily = models.daily.EjecucionClasificadores
filters = []
if query.transferencias is not None:
filters.append(Daily.transferencias == query.transferencias)
if query.dias is not None:
filters.append(Daily.dias == query.dias)
return db.query(Daily).filter(*filters).all()
@router.get('/entidades', response_model=List[schemas.daily.EjecucionEntidades])
def fetch_entidades(
db: Session = Depends(model.get_db),
query: schema.DailyParams = Depends(),
):
Daily = models.daily.EjecucionEntidades
transferencias = query.transferencias or False # :O
page = query.page or 1
page_size = 10
filters = []
if not transferencias:
filters.append(Daily.transferencias == query.transferencias)
if query.dias is not None:
filters.append(Daily.dias == query.dias)
if query.entidad is not None:
filters.append(Daily.entidad == query.entidad)
return db.query(Daily).filter(*filters).offset(
(page - 1) * page_size
).limit(page_size).all()
@router.get('/timeline', response_model=List[schemas.daily.Timeline])
def fetch_timeline(
db: Session = Depends(model.get_db),
query: schema.DailyParams = Depends(),
):
Daily = models.daily.Timeline
page = query.page or 1
page_size = 10
if query.entidad is not None:
return db.query(Daily).filter(
Daily.entidad == query.entidad
).order_by(
Daily.devengado.desc()
).offset(
(page - 1) * page_size
).limit(page_size).all()
# top 10 entidades
top_entities = db.query(
Daily.entidad
).group_by(
Daily.entidad
).order_by(
func.sum(Daily.devengado).desc()
).limit(10).subquery()
# ordena las filas por devengado desc por cada una de las top 10 entidades
ranked = db.query(
Daily,
func.row_number().over(
partition_by=Daily.entidad,
order_by=Daily.devengado.desc()
).label('row_num')
).filter(
Daily.entidad.in_(top_entities)
).subquery()
# top 10 filas por cada una de las top 10 entidades
RankedTimeline = aliased(Daily, ranked)
return db.query(RankedTimeline).filter(
ranked.c.row_num <= page_size
).order_by(
RankedTimeline.entidad,
RankedTimeline.devengado.desc()
).all()
@router.get('/timeseries', response_model=List[schemas.daily.TimeSeries])
def fetch_timeseries(
db: Session = Depends(model.get_db),
):
return db.query(models.daily.TimeSeries).all()
......@@ -8,8 +8,6 @@ from sqlalchemy import and_, or_
from presupuestov1 import model, schema, constant, schemas, models, search
from aiocache import cached
router = APIRouter(
prefix='/entidad',
......@@ -21,16 +19,26 @@ router = APIRouter(
# GET
###############################################################################
@router.get('/{entity_id:int}', response_model=schemas.classifier.ClasInstitucional)
@router.get('/{entity_id:int}', response_model=schemas.entity.ClasInstitucionalIngresosGastos)
def fetch_entity(
entity_id: int,
db: Session = Depends(model.get_db),
):
TreemapObjeto = models.treemap.TreemapObjeto
gastos = db.query(TreemapObjeto).filter(
TreemapObjeto.entidad == entity_id,
TreemapObjeto.objeto == 0
).all()
ClasInstitucional = models.classifier.ClasInstitucional
return db.query(ClasInstitucional).filter(
entidad = db.query(ClasInstitucional).filter(
ClasInstitucional.entidad == entity_id
).one()
setattr(entidad, 'gastos', gastos)
return entidad
@router.get('/clasificador', response_model=List[schemas.classifier.ClasInstitucional])
def fetch_classifier(
......@@ -51,7 +59,7 @@ def fetch_entity_objetos(
)
router.get('/{entity_id:int}/finfuns', response_model=List[schemas.treemap.TreemapFinFun])
@router.get('/{entity_id:int}/finfuns', response_model=List[schemas.treemap.TreemapFinFun])
def fetch_entity_finfuns(
entity_id: int,
db: Session = Depends(model.get_db),
......@@ -73,4 +81,3 @@ def fetch_entity_actecos(
return models.treemap.get_entity_connections(
entity_id, db, query, TreemapActeco, 'acteco'
)
......
......@@ -4,18 +4,23 @@ from typing import Optional
from pydantic import BaseModel, ConfigDict, Field, root_validator
from fastapi import Query
class OrmBaseModel(BaseModel):
model_config = ConfigDict(from_attributes=True)
class SearchQueryParams(BaseModel):
page: Optional[int] = Query(default=1)
q: Optional[str] = Query(default=None, max_length=128)
page: Optional[int] = Query(default=1, le=100)
q: Optional[str] = Query(default=None, min_length=3, max_length=128)
order: Optional[str] = Query(default=None, max_length=5)
is_class: Optional[bool] = Query(default=None)
class_: Optional[str] = Query(default=None)
class QueryParams(BaseModel):
id: Optional[str] = Query(default=None)
gestion: Optional[int] = Query(default=None)
gestion: Optional[int] = Query(default=0)
class DailyParams(BaseModel):
transferencias: Optional[bool] = Query(default=False)
dias: Optional[int] = Query(default=None)
entidad: Optional[int] = Query(default=None, ge=0, le=10000)
page: Optional[int] = Query(default=1, ge=1, le=100)
......
from . import (
acteco,
classifier,
acteco,
finfun,
objeto,
treemap,
project
project,
entity,
daily,
)
......
from typing import List
from presupuestov1.schema import OrmBaseModel
from presupuestov1 import schemas
class ActecoEstado(OrmBaseModel):
gestion: int
acteco: str
total: float | None
poblacion: int | None
poblacion: float | None
n_entidades: int | None
per_capita: float | None
total_gestion: float | None
......@@ -16,11 +19,11 @@ class ActecoEstado(OrmBaseModel):
top1_entidad_desc: str | None
top1_monto: float | None
top1_pct: float | None
top2_entidad: int | None
top2_entidad: int | None | float
top2_entidad_desc: str | None
top2_monto: float | None
top2_pct: float | None
top3_entidad: int | None
top3_entidad: int | None | float
top3_entidad_desc: str | None
top3_monto: float | None
top3_pct: float | None
......@@ -37,3 +40,7 @@ class ActecoEntidad(OrmBaseModel):
ranking: int | None
prop: float | None
n_entidades: int | None
class ClasActecoEstados(schemas.classifier.ClasActeco):
estados: List[ActecoEstado]
......
......@@ -24,7 +24,7 @@ class ClasInstitucional(OrmBaseModel):
subarea: str | None
desc_subarea: str | None
sigla_subarea: str | None
gestiones: str | None
n_gestiones: int | None
......@@ -35,42 +35,66 @@ def get_clasdesc(name):
**{'gestion': str, 'desc_{}'.format(name): str},
)
class ClasObjetos(OrmBaseModel):
class ClasBase(OrmBaseModel):
nivel: str | None
objeto: str
desc_objeto: str | None
gestiones: str | None
n_gestiones: int | None
n_variaciones: int | None
descripciones: list[get_clasdesc('objeto')] | None
class ClasRubros(OrmBaseModel):
nivel: str | None
rubro: str
desc_rubro: str | None
gestiones: str | None
n_gestiones: int | None
n_variaciones: int | None
descripciones: list[get_clasdesc('rubro')] | None
class ClasObjetos(ClasBase):
objeto: str
desc_objeto: str | None
descripciones: list[get_clasdesc('objeto')] | None
class ClasFinfun(OrmBaseModel):
nivel: str | None
class ClasFinfun(ClasBase):
finfun: str
desc_finfun: str | None
gestiones: str | None
n_gestiones: int | None
n_variaciones: int | None
descripciones: list[get_clasdesc('finfun')] | None
class ClasActeco(OrmBaseModel):
nivel: str | None
class ClasActeco(ClasBase):
acteco: str
desc_acteco: str | None
descripciones: list[get_clasdesc('acteco')] | None
class ClasGeografico(ClasBase):
ubigeo: str
desc_ubigeo: str | None
municipio_ubigeo: int | None
descripciones: list[get_clasdesc('ubigeo')] | None
# Ingresos
class ClasOrganismos(OrmBaseModel):
organismo: int
desc_organismo: str | None
sigla_organismo: str | None
organismo_grupo: int | None
desc_organismo_grupo: str | None
sigla_organismo_grupo: str | None
organismo_subgrupo: int | None
desc_organismo_subgrupo: str | None
sigla_organismo_subgrupo: str | None
gestiones: str | None
n_gestiones: int | None
n_variaciones: int | None
descripciones: list[get_clasdesc('acteco')] | None
class ClasRubros(ClasBase):
rubro: str
desc_rubro: str | None
descripciones: list[get_clasdesc('rubro')] | None
class ClasFuentes(ClasBase):
fuente: str
desc_fuente: str | None
grupo_fuente: str
desc_grupo_fuente: str | None
descripciones: list[get_clasdesc('fuente')] | None
......
from datetime import datetime
from presupuestov1.schema import OrmBaseModel
class UpdateStatus(OrmBaseModel):
fecha_actualizacion: datetime
status: bool
class EjecucionClasificadores(OrmBaseModel):
transferencias: bool
dias: int
clasificador: str
devengado: float | None
padre: str | None
hijo: str | None
class EjecucionEntidades(OrmBaseModel):
transferencias: bool
dias: int
entidad: int
vigente: float | None
devengado: float | None
ejecucion: float | None
entidad_desc_area: str | None
entidad_desc_entidad: str | None
class Timeline(OrmBaseModel):
entidad: int
devengado: float | None
entidad_desc_area: str | None
entidad_desc_entidad: str | None
desc_programa: str | None
desc_actividad_proyecto: str | None
class TimeSeries(OrmBaseModel):
fecha: str
devengado: float | None
diferencia: float | None
dias: int
from typing import List
from presupuestov1.schema import OrmBaseModel
from presupuestov1 import schemas
class ClasInstitucionalIngresosGastos(schemas.classifier.ClasInstitucional):
gastos: List[schemas.treemap.TreemapObjeto]
from typing import List
from presupuestov1.schema import OrmBaseModel
from presupuestov1 import schemas
class EntidadesPorFinfun(OrmBaseModel):
......@@ -12,7 +15,7 @@ class FinfunEstado(OrmBaseModel):
gestion: int
finfun: str
total: float | None
poblacion: int | None
poblacion: float | None
n_entidades: int | None
per_capita: float | None
total_gestion: float | None
......@@ -23,11 +26,11 @@ class FinfunEstado(OrmBaseModel):
top1_entidad_desc: str | None
top1_monto: float | None
top1_pct: float | None
top2_entidad: int | None
top2_entidad: int | None | float
top2_entidad_desc: str | None
top2_monto: float | None
top2_pct: float | None
top3_entidad: int | None
top3_entidad: int | None | float
top3_entidad_desc: str | None
top3_monto: float | None
top3_pct: float | None
......@@ -44,3 +47,7 @@ class FinfunEntidad(OrmBaseModel):
ranking: int | None
prop: float | None
n_entidades: int | None
class ClasFinfunEstados(schemas.classifier.ClasFinfun):
estados: List[FinfunEstado]
......
from typing import List
from presupuestov1.schema import OrmBaseModel
from presupuestov1 import schemas
class EntidadesPorObjeto(OrmBaseModel):
......@@ -12,7 +15,7 @@ class ObjetoEstado(OrmBaseModel):
gestion: int
objeto: str
total: float | None
poblacion: int | None
poblacion: float | None
n_entidades: int | None
per_capita: float | None
total_gestion: float | None
......@@ -44,3 +47,7 @@ class ObjetoEntidad(OrmBaseModel):
ranking: int | None
prop: float | None
n_entidades: int | None
class ClasObjetosEstados(schemas.classifier.ClasObjetos):
estados: List[ObjetoEstado]
......
......@@ -4,7 +4,6 @@ from presupuestov1.schema import BaseModel
class ProjectSearch(BaseModel):
gestion: int
devengado: float
is_class: bool
class_: str
......
......@@ -7,8 +7,8 @@ from pydantic import field_serializer
class Treemap(OrmBaseModel):
gestion: int
entidad: int
entidad_area: str | None
nivel: str | None
parent: int | None
devengado: float | None
@field_serializer('devengado')
......@@ -18,15 +18,21 @@ class Treemap(OrmBaseModel):
class TreemapObjeto(Treemap):
objeto: str
objeto: int
parent: int | None
desc_objeto: str | None
desc_entidad: str | None
class TreemapFinFun(Treemap):
finfun: str
parent: str | None
desc_finfun: str | None
desc_entidad: str | None
class TreemapActeco(Treemap):
acteco: str
desc_actividad: str | None
parent: str | None
desc_acteco: str | None
desc_entidad: str | None
......
......@@ -15,7 +15,6 @@ COLLECTION = 'presup_actpro_fts'
schema = {
'name': COLLECTION,
'fields': [
{'name': 'gestion', 'type': 'int32', 'facet': True},
{'name': 'devengado', 'type': 'float'},
{'name': 'is_class', 'type': 'bool'},
{'name': 'class_', 'type': 'string'},
......@@ -58,7 +57,6 @@ def do_search(query, page, is_class, class_=None, order=None):
if (page is not None) and (page > 0) and (page < 100):
search_parameters_['page'] = page
search_parameters_['sort_by'] = 'devengado:desc'
if order == 'asc':
search_parameters_['sort_by'] = 'devengado:asc'
......