185 lines
5.9 KiB
Python

from datetime import date
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.responses import StreamingResponse
from sqlalchemy.ext.asyncio import AsyncSession
from src.db.models.app_user import AppUser
from src.api.v1.deps import require_admin, require_executor
from src.db.session import get_db
from src.domain.schemas import (
BaseListResponse,
BaseSingleResponse,
VSPCreate,
VSPExportRequest,
VSPInDB,
VSPUpdate,
)
from src.services.vsp_service import VSPService
router = APIRouter(prefix="/dict/info", tags=["info"])
@router.get("", response_model=BaseListResponse[VSPInDB])
async def get_vsp(
registration_number: str | None = None,
address: str | None = None,
ssp_id: int | None = None,
open_date_start: date | None = None,
open_date_end: date | None = None,
placement_type: str | None = None,
staff_count_min: int | None = None,
staff_count_max: int | None = None,
db: AsyncSession = Depends(get_db),
current_user: AppUser = Depends(require_executor),
):
"""Получение записей справочника INFO."""
service = VSPService(db)
result = await service.get_list(
user=current_user,
registration_number=registration_number,
address=address,
ssp_id=ssp_id,
open_date_start=open_date_start,
open_date_end=open_date_end,
placement_type=placement_type,
staff_count_min=staff_count_min,
staff_count_max=staff_count_max,
load_org_unit=True,
with_count=True,
)
return BaseListResponse(
success=True,
message="Список INFO",
result=[VSPInDB.model_validate(vsp) for vsp in result[1]],
count=result[0]
)
@router.get("/dropdown", response_model=BaseListResponse[VSPInDB])
async def get_vsp_dropdown(
ssp_id: int | None = None,
form_id: int | None = None,
db: AsyncSession = Depends(get_db),
current_user: AppUser = Depends(require_executor),
):
"""Получение записей для выпадающего списка INFO."""
service = VSPService(db)
result = await service.get_dropdown(user=current_user, ssp_id=ssp_id, form_id=form_id, with_count=True)
return BaseListResponse(
success=True,
message="Список INFO для выпадающего списка",
result=[VSPInDB.model_validate(vsp) for vsp in result[1]],
count=result[0],
)
@router.post("/export")
async def export_info(
body: VSPExportRequest,
db: AsyncSession = Depends(get_db),
current_user: AppUser = Depends(require_executor),
):
"""Экспорт справочника INFO."""
service = VSPService(db)
stream, filename = await service.export_xlsx(
user=current_user,
registration_number=body.registration_number,
address=body.address,
ssp_ids=body.ssp_ids,
open_date_start=body.open_date_start,
open_date_end=body.open_date_end,
placement_type=body.placement_type,
staff_count_min=body.staff_count_min,
staff_count_max=body.staff_count_max,
)
return StreamingResponse(
stream,
media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
headers={"Content-Disposition": f'attachment; filename="{filename}"'},
)
@router.post("", response_model=BaseSingleResponse[VSPInDB], status_code=201)
async def add_vsp(
body: VSPCreate,
db: AsyncSession = Depends(get_db),
current_user: AppUser = Depends(require_admin),
):
"""Добавление строки в справочник INFO."""
service = VSPService(db)
result = await service.create(
body,
current_user,
load_org_unit=True,
)
return BaseSingleResponse(
success=True,
message="Запись INFO создана",
result=VSPInDB.model_validate(result),
)
@router.get("/{vsp_id}", response_model=BaseSingleResponse[VSPInDB])
async def get_vsp_by_id(
vsp_id: int,
db: AsyncSession = Depends(get_db),
current_user: AppUser = Depends(require_executor),
):
"""Получение записи справочника INFO по ID."""
service = VSPService(db)
result = await service.get(vsp_id, user=current_user, load_org_unit=True)
if not result:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ВСП не найден",
)
return BaseSingleResponse(
success=True,
message="Запись INFO",
result=VSPInDB.model_validate(result),
)
@router.put("/{vsp_id}", response_model=BaseSingleResponse[VSPInDB])
async def update_vsp(
vsp_id: int,
body: VSPUpdate,
db: AsyncSession = Depends(get_db),
current_user: AppUser = Depends(require_executor),
):
"""Редактирование строки справочника INFO."""
service = VSPService(db)
result = await service.update(
vsp_id,
body,
current_user,
load_org_unit=True,
)
if not result:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ВСП не найден",
)
return BaseSingleResponse(
success=True,
message="Запись INFO обновлена",
result=VSPInDB.model_validate(result),
)
@router.delete("/{vsp_id}", response_model=BaseSingleResponse[VSPInDB])
async def delete_vsp(
vsp_id: int,
db: AsyncSession = Depends(get_db),
current_user: AppUser = Depends(require_admin),
):
"""Удаление строки справочника INFO."""
service = VSPService(db)
if await service.logical_delete(vsp_id, current_user):
return BaseSingleResponse(success=True, message="Запись INFO удалена")
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ВСП не найден",
)