Showing
9 changed files
with
208 additions
and
32 deletions
| ... | @@ -100,7 +100,10 @@ class ClasGeografico(ClasBase, Base): | ... | @@ -100,7 +100,10 @@ class ClasGeografico(ClasBase, Base): |
| 100 | ) | 100 | ) |
| 101 | 101 | ||
| 102 | ubigeo: Mapped[str] = mapped_column(Text, primary_key=True) | 102 | ubigeo: Mapped[str] = mapped_column(Text, primary_key=True) |
| 103 | + | ||
| 104 | + desc_departamento: Mapped[str] = mapped_column(String(12)) | ||
| 103 | desc_ubigeo: Mapped[str | None] = mapped_column(Text) | 105 | desc_ubigeo: Mapped[str | None] = mapped_column(Text) |
| 106 | + | ||
| 104 | municipio_ubigeo: Mapped[int | None] = mapped_column(Integer) | 107 | municipio_ubigeo: Mapped[int | None] = mapped_column(Integer) |
| 105 | 108 | ||
| 106 | 109 | ... | ... |
| ... | @@ -9,9 +9,10 @@ from sqlalchemy import ( | ... | @@ -9,9 +9,10 @@ from sqlalchemy import ( |
| 9 | Index, | 9 | Index, |
| 10 | MetaData, | 10 | MetaData, |
| 11 | Boolean, | 11 | Boolean, |
| 12 | - DateTime | 12 | + DateTime, |
| 13 | + Date | ||
| 13 | ) | 14 | ) |
| 14 | -from datetime import datetime | 15 | +from datetime import datetime, date |
| 15 | 16 | ||
| 16 | 17 | ||
| 17 | class UpdateStatus(Base): | 18 | class UpdateStatus(Base): |
| ... | @@ -92,7 +93,7 @@ class TimeSeries(Base): | ... | @@ -92,7 +93,7 @@ class TimeSeries(Base): |
| 92 | 93 | ||
| 93 | id: Mapped[int] = mapped_column(Integer, primary_key=True) | 94 | id: Mapped[int] = mapped_column(Integer, primary_key=True) |
| 94 | 95 | ||
| 95 | - fecha: Mapped[str] = mapped_column(String(10)) | 96 | + fecha: Mapped[date] = mapped_column(Date) |
| 96 | devengado: Mapped[float] = mapped_column(Numeric(30, 15)) | 97 | devengado: Mapped[float] = mapped_column(Numeric(30, 15)) |
| 97 | diferencia: Mapped[float] = mapped_column(Numeric(30, 15)) | 98 | diferencia: Mapped[float] = mapped_column(Numeric(30, 15)) |
| 98 | dias: Mapped[int] = mapped_column(Integer) | 99 | dias: Mapped[int] = mapped_column(Integer) | ... | ... |
models/entity.py
0 → 100644
| 1 | +from sqlalchemy.orm import Mapped, mapped_column | ||
| 2 | +from presupuestov1.model import Base | ||
| 3 | + | ||
| 4 | +from sqlalchemy import ( | ||
| 5 | + Integer, | ||
| 6 | + String, | ||
| 7 | + Text, | ||
| 8 | + Numeric, | ||
| 9 | + Index, | ||
| 10 | + MetaData, | ||
| 11 | +) | ||
| 12 | + | ||
| 13 | + | ||
| 14 | +class EntidadDistribuciones(Base): | ||
| 15 | + __tablename__ = "entidad_distribuciones" | ||
| 16 | + __table_args__ = ( | ||
| 17 | + Index("idx_entidad_distribuciones_tipo", "tipo"), | ||
| 18 | + Index("idx_entidad_distribuciones_tipo_codigo", "tipo_codigo"), | ||
| 19 | + Index("idx_entidad_distribuciones_codigo", "codigo"), | ||
| 20 | + Index("idx_entidad_distribuciones_dimension", "dimension"), | ||
| 21 | + Index("idx_entidad_distribuciones_gestion", "gestion"), | ||
| 22 | + {"schema": "web"}, | ||
| 23 | + ) | ||
| 24 | + | ||
| 25 | + id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) | ||
| 26 | + | ||
| 27 | + tipo: Mapped[str] = mapped_column(String(8)) | ||
| 28 | + tipo_codigo: Mapped[str] = mapped_column(String(16)) | ||
| 29 | + codigo: Mapped[str] = mapped_column(String(8)) | ||
| 30 | + dimension: Mapped[str] = mapped_column(String(10)) | ||
| 31 | + gestion: Mapped[int] = mapped_column(Integer) | ||
| 32 | + padre: Mapped[str] = mapped_column(String(8)) | ||
| 33 | + hijo: Mapped[str] = mapped_column(String(8)) | ||
| 34 | + devengado: Mapped[float] = mapped_column(Numeric(30, 15)) | ||
| 35 | + | ||
| 36 | + desc_padre: Mapped[str] = mapped_column(Text) | ||
| 37 | + desc_hijo: Mapped[str] = mapped_column(Text) | ||
| 38 | + | ||
| 39 | + | ||
| 40 | +class EntidadResumenes(Base): | ||
| 41 | + __tablename__ = "entidad_resumenes" | ||
| 42 | + __table_args__ = ( | ||
| 43 | + Index("idx_entidad_resumenes_tipo", "tipo"), | ||
| 44 | + Index("idx_entidad_resumenes_tipo_codigo", "tipo_codigo"), | ||
| 45 | + Index("idx_entidad_resumenes_codigo", "codigo"), | ||
| 46 | + Index("idx_entidad_resumenes_gestion", "gestion"), | ||
| 47 | + {"schema": "web"}, | ||
| 48 | + ) | ||
| 49 | + | ||
| 50 | + id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) | ||
| 51 | + | ||
| 52 | + tipo: Mapped[str] = mapped_column(String(8)) | ||
| 53 | + tipo_codigo: Mapped[str] = mapped_column(String(16)) | ||
| 54 | + codigo: Mapped[str] = mapped_column(String(8)) | ||
| 55 | + gestion: Mapped[int] = mapped_column(Integer) | ||
| 56 | + | ||
| 57 | + devengado: Mapped[float] = mapped_column(Numeric(30, 15)) | ||
| 58 | + ranking: Mapped[int] = mapped_column(Integer) | ||
| 59 | + | ||
| 60 | + | ||
| 61 | + desc: Mapped[str] = mapped_column(Text) | ||
| 62 | + desc_padre: Mapped[str] = mapped_column(Text) |
| ... | @@ -105,6 +105,9 @@ def get_clas_entities(query_filters, db, query, ClassObject, object_id): | ... | @@ -105,6 +105,9 @@ def get_clas_entities(query_filters, db, query, ClassObject, object_id): |
| 105 | ClassObject.gestion == query.gestion, | 105 | ClassObject.gestion == query.gestion, |
| 106 | ]) | 106 | ]) |
| 107 | 107 | ||
| 108 | + if query.nivel is not None: | ||
| 109 | + query_filters.append(ClassObject.nivel == query.nivel) | ||
| 110 | + | ||
| 108 | if query.id is not None: | 111 | if query.id is not None: |
| 109 | ids = query.id.split(',') | 112 | ids = query.id.split(',') |
| 110 | ids = [int(_.strip()) for _ in ids] | 113 | ids = [int(_.strip()) for _ in ids] | ... | ... |
| ... | @@ -9,75 +9,153 @@ from sqlalchemy import and_, or_ | ... | @@ -9,75 +9,153 @@ from sqlalchemy import and_, or_ |
| 9 | from presupuestov1 import model, schema, constant, schemas, models, search | 9 | from presupuestov1 import model, schema, constant, schemas, models, search |
| 10 | 10 | ||
| 11 | 11 | ||
| 12 | -router = APIRouter( | 12 | +router_entidad = APIRouter( |
| 13 | prefix='/entidad', | 13 | prefix='/entidad', |
| 14 | tags=['entidad'], | 14 | tags=['entidad'], |
| 15 | ) | 15 | ) |
| 16 | +router_ubigeo = APIRouter( | ||
| 17 | + prefix='/ubigeo', | ||
| 18 | + tags=['ubigeo'], | ||
| 19 | +) | ||
| 20 | +router_da = APIRouter( | ||
| 21 | + prefix='/direccion_administrativa', | ||
| 22 | + tags=['direccion_administrativa'], | ||
| 23 | +) | ||
| 16 | 24 | ||
| 17 | 25 | ||
| 18 | ############################################################################### | 26 | ############################################################################### |
| 19 | # GET | 27 | # GET |
| 20 | ############################################################################### | 28 | ############################################################################### |
| 21 | 29 | ||
| 22 | -@router.get('/{entity_id:int}', response_model=schemas.entity.ClasInstitucionalIngresosGastos) | 30 | +# clas |
| 31 | + | ||
| 32 | +@router_entidad.get('/clasificador', response_model=List[schemas.classifier.ClasInstitucional]) | ||
| 33 | +def fetch_classifier( | ||
| 34 | + db: Session = Depends(model.get_db), | ||
| 35 | +): | ||
| 36 | + return db.query(models.classifier.ClasInstitucional).all() | ||
| 37 | + | ||
| 38 | + | ||
| 39 | +@router_ubigeo.get('/clasificador', response_model=List[schemas.classifier.ClasGeografico]) | ||
| 40 | +def fetch_classifier( | ||
| 41 | + db: Session = Depends(model.get_db), | ||
| 42 | +): | ||
| 43 | + return db.query(models.classifier.ClasGeografico).all() | ||
| 44 | + | ||
| 45 | + | ||
| 46 | +# base | ||
| 47 | + | ||
| 48 | +@router_entidad.get('/{entity_id:str}', response_model=schemas.entity.ClasInstitucionalIngresosGastos) | ||
| 23 | def fetch_entity( | 49 | def fetch_entity( |
| 24 | entity_id: int, | 50 | entity_id: int, |
| 25 | db: Session = Depends(model.get_db), | 51 | db: Session = Depends(model.get_db), |
| 26 | ): | 52 | ): |
| 27 | - TreemapObjeto = models.treemap.TreemapObjeto | ||
| 28 | - gastos = db.query(TreemapObjeto).filter( | ||
| 29 | - TreemapObjeto.entidad == entity_id, | ||
| 30 | - TreemapObjeto.objeto == 0 | ||
| 31 | - ).all() | ||
| 32 | - | ||
| 33 | ClasInstitucional = models.classifier.ClasInstitucional | 53 | ClasInstitucional = models.classifier.ClasInstitucional |
| 34 | entidad = db.query(ClasInstitucional).filter( | 54 | entidad = db.query(ClasInstitucional).filter( |
| 35 | ClasInstitucional.entidad == entity_id | 55 | ClasInstitucional.entidad == entity_id |
| 36 | ).one() | 56 | ).one() |
| 37 | 57 | ||
| 38 | - setattr(entidad, 'gastos', gastos) | 58 | + gastos_ingresos = get_resumen('entidad', entity_id) |
| 59 | + setattr(entidad, 'gastos_ingresos', gastos_ingresos) | ||
| 39 | 60 | ||
| 40 | return entidad | 61 | return entidad |
| 41 | 62 | ||
| 42 | 63 | ||
| 43 | -@router.get('/clasificador', response_model=List[schemas.classifier.ClasInstitucional]) | 64 | +@router_ubigeo.get('/{ubigeo_id:str}', response_model=schemas.entity.ClasGeograficoIngresosGastos) |
| 44 | -def fetch_classifier( | 65 | +def fetch_entity( |
| 66 | + ubigeo_id: int, | ||
| 45 | db: Session = Depends(model.get_db), | 67 | db: Session = Depends(model.get_db), |
| 46 | ): | 68 | ): |
| 47 | - return db.query(models.classifier.ClasInstitucional).all() | 69 | + ClasGeografico = models.classifier.ClasGeografico |
| 70 | + ubigeo = db.query(ClasGeografico).filter( | ||
| 71 | + ClasGeografico.ubigeo == ubigeo_id | ||
| 72 | + ).one() | ||
| 48 | 73 | ||
| 74 | + gastos_ingresos = get_resumen('municipio_ubigeo', ubigeo_id) | ||
| 75 | + setattr(ubigeo, 'gastos_ingresos', gastos_ingresos) | ||
| 49 | 76 | ||
| 50 | -@router.get('/{entity_id:int}/objetos', response_model=List[schemas.treemap.TreemapObjeto]) | 77 | + return ubigeo |
| 78 | + | ||
| 79 | + | ||
| 80 | +# objetos | ||
| 81 | + | ||
| 82 | +@router_entidad.get('/{entity_id:str}/objetos', response_model=List[schemas.entity.EntidadDistribucion]) | ||
| 51 | def fetch_entity_objetos( | 83 | def fetch_entity_objetos( |
| 52 | entity_id: int, | 84 | entity_id: int, |
| 53 | db: Session = Depends(model.get_db), | 85 | db: Session = Depends(model.get_db), |
| 54 | query: schema.QueryParams = Depends(), | 86 | query: schema.QueryParams = Depends(), |
| 55 | ): | 87 | ): |
| 56 | - TreemapObjeto = models.treemap.TreemapObjeto | 88 | + return get_distribuciones('entidad', entidad_id, 'objeto', query) |
| 57 | - return models.treemap.get_entity_connections( | ||
| 58 | - entity_id, db, query, TreemapObjeto, 'objeto' | ||
| 59 | - ) | ||
| 60 | 89 | ||
| 61 | 90 | ||
| 62 | -@router.get('/{entity_id:int}/finfuns', response_model=List[schemas.treemap.TreemapFinFun]) | 91 | +@router_ubigeo.get('/{ubigeo_id:str}/objetos', response_model=List[schemas.entity.EntidadDistribucion]) |
| 92 | +def fetch_entity_objetos( | ||
| 93 | + ubigeo_id: int, | ||
| 94 | + db: Session = Depends(model.get_db), | ||
| 95 | + query: schema.QueryParams = Depends(), | ||
| 96 | +): | ||
| 97 | + return get_distribuciones('municipio_ubigeo', ubigeo_id, 'objeto', query) | ||
| 98 | + | ||
| 99 | + | ||
| 100 | +@router_entidad.get('/{entity_id:str}/finfuns', response_model=List[schemas.entity.EntidadDistribucion]) | ||
| 63 | def fetch_entity_finfuns( | 101 | def fetch_entity_finfuns( |
| 64 | entity_id: int, | 102 | entity_id: int, |
| 65 | db: Session = Depends(model.get_db), | 103 | db: Session = Depends(model.get_db), |
| 66 | query: schema.QueryParams = Depends(), | 104 | query: schema.QueryParams = Depends(), |
| 67 | ): | 105 | ): |
| 68 | - TreemapFinFun = models.treemap.TreemapFinFun | 106 | + return get_distribuciones('entidad', entidad_id, 'finfun', query) |
| 69 | - return models.treemap.get_entity_connections( | 107 | + |
| 70 | - entity_id, db, query, TreemapFinFun, 'finfun' | 108 | + |
| 71 | - ) | 109 | +@router_ubigeo.get('/{ubigeo_id:str}/finfuns', response_model=List[schemas.entity.EntidadDistribucion]) |
| 110 | +def fetch_entity_finfuns( | ||
| 111 | + ubigeo_id: int, | ||
| 112 | + db: Session = Depends(model.get_db), | ||
| 113 | + query: schema.QueryParams = Depends(), | ||
| 114 | +): | ||
| 115 | + return get_distribuciones('municipio_ubigeo', ubigeo_id, 'finfun', query) | ||
| 72 | 116 | ||
| 73 | 117 | ||
| 74 | -@router.get('/{entity_id:int}/actecos', response_model=List[schemas.treemap.TreemapActeco]) | 118 | +@router_entidad.get('/{entity_id:str}/actecos', response_model=List[schemas.entity.EntidadDistribucion]) |
| 75 | def fetch_entity_actecos( | 119 | def fetch_entity_actecos( |
| 76 | entity_id: int, | 120 | entity_id: int, |
| 77 | db: Session = Depends(model.get_db), | 121 | db: Session = Depends(model.get_db), |
| 78 | query: schema.QueryParams = Depends(), | 122 | query: schema.QueryParams = Depends(), |
| 79 | ): | 123 | ): |
| 80 | - TreemapActeco = models.treemap.TreemapActeco | 124 | + return get_distribuciones('entidad', entidad_id, 'acteco', query) |
| 81 | - return models.treemap.get_entity_connections( | 125 | + |
| 82 | - entity_id, db, query, TreemapActeco, 'acteco' | 126 | + |
| 127 | +@router_ubigeo.get('/{ubigeo_id:str}/actecos', response_model=List[schemas.entity.EntidadDistribucion]) | ||
| 128 | +def fetch_entity_actecos( | ||
| 129 | + ubigeo_id: int, | ||
| 130 | + db: Session = Depends(model.get_db), | ||
| 131 | + query: schema.QueryParams = Depends(), | ||
| 132 | +): | ||
| 133 | + return get_distribuciones('municipio_ubigeo', ubigeo_id, 'acteco', query) | ||
| 134 | + | ||
| 135 | + | ||
| 136 | +############################################################################### | ||
| 137 | +# private | ||
| 138 | +############################################################################### | ||
| 139 | + | ||
| 140 | +def get_distribuciones(tipo_codigo, entidad_id, dimension, query): | ||
| 141 | + EntidadDistribuciones = models.entity.EntidadDistribuciones | ||
| 142 | + | ||
| 143 | + filters = [] | ||
| 144 | + if query.gestion is not None: | ||
| 145 | + filters.append(EntidadDistribuciones.gestion == query.gestion) | ||
| 146 | + | ||
| 147 | + filters.extend( | ||
| 148 | + EntidadDistribuciones.tipo_codigo == tipo_codigo, | ||
| 149 | + EntidadDistribuciones.codigo == entity_id, | ||
| 150 | + EntidadDistribuciones.dimension == dimension, | ||
| 83 | ) | 151 | ) |
| 152 | + | ||
| 153 | + return db.query(EntidadDistribuciones).filter(*filters).all() | ||
| 154 | + | ||
| 155 | + | ||
| 156 | +def get_resumen(tipo_codigo, codigo): | ||
| 157 | + EntidadResumenes = models.entity.EntidadResumenes | ||
| 158 | + return db.query(EntidadResumenes).filter( | ||
| 159 | + EntidadResumenes.tipo_codigo == tipo_codigo, | ||
| 160 | + EntidadResumenes.codigo == codigo, | ||
| 161 | + ).all() | ... | ... |
| ... | @@ -63,6 +63,7 @@ class ClasActeco(ClasBase): | ... | @@ -63,6 +63,7 @@ class ClasActeco(ClasBase): |
| 63 | class ClasGeografico(ClasBase): | 63 | class ClasGeografico(ClasBase): |
| 64 | ubigeo: str | 64 | ubigeo: str |
| 65 | desc_ubigeo: str | None | 65 | desc_ubigeo: str | None |
| 66 | + desc_departamento: str | None | ||
| 66 | municipio_ubigeo: int | None | 67 | municipio_ubigeo: int | None |
| 67 | descripciones: list[get_clasdesc('ubigeo')] | None | 68 | descripciones: list[get_clasdesc('ubigeo')] | None |
| 68 | 69 | ... | ... |
| 1 | -from datetime import datetime | 1 | +from datetime import datetime, date |
| 2 | 2 | ||
| 3 | from presupuestov1.schema import OrmBaseModel | 3 | from presupuestov1.schema import OrmBaseModel |
| 4 | 4 | ||
| ... | @@ -38,7 +38,7 @@ class Timeline(OrmBaseModel): | ... | @@ -38,7 +38,7 @@ class Timeline(OrmBaseModel): |
| 38 | 38 | ||
| 39 | 39 | ||
| 40 | class TimeSeries(OrmBaseModel): | 40 | class TimeSeries(OrmBaseModel): |
| 41 | - fecha: str | 41 | + fecha: date |
| 42 | devengado: float | None | 42 | devengado: float | None |
| 43 | diferencia: float | None | 43 | diferencia: float | None |
| 44 | dias: int | 44 | dias: int | ... | ... |
| ... | @@ -4,5 +4,32 @@ from presupuestov1.schema import OrmBaseModel | ... | @@ -4,5 +4,32 @@ from presupuestov1.schema import OrmBaseModel |
| 4 | from presupuestov1 import schemas | 4 | from presupuestov1 import schemas |
| 5 | 5 | ||
| 6 | 6 | ||
| 7 | +class EntidadDistribucion(OrmBaseModel): | ||
| 8 | + tipo: str | ||
| 9 | + tipo_codigo: str | ||
| 10 | + codigo: str | ||
| 11 | + dimension: str | ||
| 12 | + gestion: int | ||
| 13 | + padre: str | ||
| 14 | + hijo: str | ||
| 15 | + devengado: float | ||
| 16 | + desc_padre: str | None | ||
| 17 | + desc_hijo: str | None | ||
| 18 | + | ||
| 19 | + | ||
| 20 | +class EntidadResumen(OrmBaseModel): | ||
| 21 | + tipo: str | ||
| 22 | + tipo_codigo: str | ||
| 23 | + codigo: str | ||
| 24 | + gestion: int | ||
| 25 | + devengado: float | ||
| 26 | + ranking: int | None | ||
| 27 | + desc: str | None | ||
| 28 | + desc_padre: str | None | ||
| 29 | + | ||
| 30 | + | ||
| 7 | class ClasInstitucionalIngresosGastos(schemas.classifier.ClasInstitucional): | 31 | class ClasInstitucionalIngresosGastos(schemas.classifier.ClasInstitucional): |
| 8 | - gastos: List[schemas.treemap.TreemapObjeto] | 32 | + gastos_ingresos: List[EntidadResumen] |
| 33 | + | ||
| 34 | +class ClasGeograficoIngresosGastos(schemas.classifier.ClasGeografico): | ||
| 35 | + gastos_ingresos: List[EntidadResumen] | ... | ... |
-
Please register or login to post a comment