pr0nstar

VII

...@@ -4,5 +4,6 @@ from . import ( ...@@ -4,5 +4,6 @@ from . import (
4 finfun, 4 finfun,
5 objeto, 5 objeto,
6 treemap, 6 treemap,
7 + entity,
7 daily, 8 daily,
8 ) 9 )
......
...@@ -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)
......
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]
......