project.py 4.02 KB
import pydantic_core

from typing import List, Any, Optional, Union

from fastapi import APIRouter, Depends, Request, HTTPException, Body
from sqlalchemy.orm import Session
from sqlalchemy import and_, or_, select, func, desc

from presupuestov1 import model, schema, constant, schemas, models, search
from presupuestov1.routers._decorators import not_found


router = APIRouter(
    prefix='/programa_proyecto',
    tags=['programa_proyecto'],
)


###############################################################################
# GET
###############################################################################

@router.get('/{project_id}', response_model=List[schemas.project.ProyectoResumen])
@not_found
def fetch_programa_proyecto(
    project_id: str,
    db: Session = Depends(model.get_db),
):
    ProyectoResumenes = models.project.ProyectoResumenes
    project_items = db.query(ProyectoResumenes).filter(
    	ProyectoResumenes.codigo == project_id
    ).all()

    # TODO if devengado > mucho_dinero: cache

    for _ in ['entidad', 'objeto', 'finfun', 'acteco']:
        for __ in project_items:
            obj_ = getattr(__, _)
            setattr(__, _, pydantic_core.from_json(obj_))

    return project_items


@router.get('/{project_id}/proyectos', response_model=List[schemas.project.ProyectoProyectos])
@not_found
def fetch_programa_proyecto_proyectos(
    project_id: str,
    db: Session = Depends(model.get_db),
	query: schema.SearchQueryParams = Depends(),
):
    page = query.page or 1
    page_size = 20

    ProyectoResumenes = models.project.ProyectoResumenes
    return db.execute(
        select(
            ProyectoResumenes.nivel,
            ProyectoResumenes.codigo,
            ProyectoResumenes.desc,
            func.sum(ProyectoResumenes.devengado).label('devengado'),
        ).where(
            ProyectoResumenes.codigo_padre == project_id,
            ProyectoResumenes.nivel != 'programa',
        ).group_by(
            ProyectoResumenes.nivel,
            ProyectoResumenes.codigo,
            ProyectoResumenes.desc,
        ).order_by(desc('devengado')).offset(
    		(page - 1) * page_size
    	).limit(page_size)
    ).mappings().all()


@router.get('/{project_id}/objetos', response_model=List[schemas.project.ProyectoClasificadores])
def fetch_programa_proyecto_objetos(
    project_id: str,
    db: Session = Depends(model.get_db),
	query: schema.QueryParamsPaginated = Depends(),
):
    return get_clasificadores(db, 'objeto', project_id, query)


@router.get('/{project_id}/finfuns', response_model=List[schemas.project.ProyectoClasificadores])
def fetch_programa_proyecto_finfuns(
    project_id: str,
    db: Session = Depends(model.get_db),
	query: schema.QueryParamsPaginated = Depends(),
):
    return get_clasificadores(db, 'finfun', project_id, query)


@router.get('/{project_id}/actecos', response_model=List[schemas.project.ProyectoClasificadores])
def fetch_programa_proyecto_actecos(
    project_id: str,
    db: Session = Depends(model.get_db),
	query: schema.QueryParamsPaginated = Depends(),
):
    return get_clasificadores(db, 'acteco', project_id, query)


###############################################################################
# private
###############################################################################

@not_found
def get_clasificadores(db, tipo_codigo, programa_proyecto, query):
    page_size = 10
    page = query.page or 1

    ProyectoClasificadoresSchema = schemas.project.ProyectoClasificadores
    ProyectoClasificadores = models.project.ProyectoClasificadores

    schema_fields = ProyectoClasificadoresSchema.model_fields.keys()
    cols = [getattr(ProyectoClasificadores, name) for name in schema_fields]

    filters = [
        ProyectoClasificadores.tipo == tipo_codigo,
        ProyectoClasificadores.programa_proyecto == programa_proyecto,
    ]
    if query.gestion is not None:
    	filters.append(ProyectoClasificadores.gestion == query.gestion)

    return db.execute(
        select(*cols).where(*filters).offset(
            (page - 1) * page_size
        ).limit(page_size)
    ).mappings().all()