192 lines
6.4 KiB
Python
192 lines
6.4 KiB
Python
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from src.db.models.app_user import AppUser
|
|
from src.db.models.role import UserRoleEnum
|
|
from src.core.errors import AccessDeniedException, ValidationException
|
|
from src.repository.project_repository import ProjectRepository
|
|
from src.repository.user_repository import UserRepository
|
|
|
|
|
|
class ProjectService:
|
|
def __init__(self, db: AsyncSession):
|
|
self.db = db
|
|
self.project_repo = ProjectRepository(db)
|
|
self.user_repo = UserRepository(db)
|
|
|
|
async def get_list(
|
|
self,
|
|
user: AppUser,
|
|
year: int | None = None,
|
|
branch_id: int | None = None,
|
|
offset: int | None = None,
|
|
limit: int | None = None,
|
|
with_count: bool = False,
|
|
with_org_unit: bool = False,
|
|
) -> list[dict] | tuple[int, list[dict]]:
|
|
org_unit_ids = await self._allowed_org_unit_ids(user)
|
|
return await self.project_repo.get_list(
|
|
year=year,
|
|
branch_id=branch_id,
|
|
offset=offset,
|
|
limit=limit,
|
|
with_count=with_count,
|
|
org_unit_ids=org_unit_ids,
|
|
)
|
|
|
|
async def get(self, project_id: int, user: AppUser) -> dict | None:
|
|
org_unit_ids = await self._allowed_org_unit_ids(user)
|
|
project = await self.project_repo.get(project_id=project_id, org_unit_ids=org_unit_ids)
|
|
if not project:
|
|
return None
|
|
project["reports"] = await self.project_repo.get_reports(project_id=project_id)
|
|
return project
|
|
|
|
async def resolve_report_id(
|
|
self,
|
|
project_id: int,
|
|
year: int,
|
|
report_type: str,
|
|
user: AppUser,
|
|
) -> int | None:
|
|
normalized_type = report_type.upper()
|
|
if normalized_type not in ("LIMIT", "CURRENT_EXPENSES"):
|
|
raise ValidationException("report_type должен быть LIMIT или CURRENT_EXPENSES")
|
|
org_unit_ids = await self._allowed_org_unit_ids(user)
|
|
return await self.project_repo.resolve_report_id(
|
|
project_id=project_id,
|
|
year=year,
|
|
report_type=normalized_type,
|
|
org_unit_ids=org_unit_ids,
|
|
)
|
|
|
|
async def get_report_rows(
|
|
self,
|
|
project_id: int,
|
|
year: int,
|
|
report_type: str,
|
|
sections: list[str] | None,
|
|
user: AppUser,
|
|
) -> list[tuple]:
|
|
report_id = await self.resolve_report_id(project_id, year, report_type, user)
|
|
if not report_id:
|
|
raise ValidationException("Отчёт не найден")
|
|
return await self.project_repo.get_report_rows(report_id=report_id, sections=sections)
|
|
|
|
async def get_rf_rollup_rows(
|
|
self,
|
|
branch_id: int,
|
|
year: int,
|
|
sections: list[str] | None,
|
|
user: AppUser,
|
|
) -> list[tuple]:
|
|
org_unit_ids = await self._allowed_org_unit_ids(user)
|
|
if org_unit_ids is not None and branch_id not in org_unit_ids:
|
|
raise AccessDeniedException()
|
|
return await self.project_repo.get_rf_rollup_rows(
|
|
branch_id=branch_id,
|
|
year=year,
|
|
sections=sections,
|
|
)
|
|
|
|
async def upd_form3_cell(
|
|
self,
|
|
project_id: int,
|
|
year: int,
|
|
report_type: str,
|
|
line_id: int,
|
|
column: str,
|
|
value,
|
|
user: AppUser,
|
|
) -> list[tuple]:
|
|
report_id = await self.resolve_report_id(project_id, year, report_type, user)
|
|
if not report_id:
|
|
raise ValidationException("Отчёт не найден")
|
|
return await self.project_repo.upd_form3_cell(report_id, line_id, column, value)
|
|
|
|
async def upd_form3_cells(
|
|
self,
|
|
project_id: int,
|
|
year: int,
|
|
report_type: str,
|
|
changes: list[dict],
|
|
user: AppUser,
|
|
) -> list[tuple]:
|
|
report_id = await self.resolve_report_id(project_id, year, report_type, user)
|
|
if not report_id:
|
|
raise ValidationException("Отчёт не найден")
|
|
return await self.project_repo.upd_form3_cells(report_id, changes)
|
|
|
|
async def add_form3_line(
|
|
self,
|
|
project_id: int,
|
|
year: int,
|
|
report_type: str,
|
|
expense_item_id: int,
|
|
user: AppUser,
|
|
) -> list[tuple]:
|
|
report_id = await self.resolve_report_id(project_id, year, report_type, user)
|
|
if not report_id:
|
|
raise ValidationException("Отчёт не найден")
|
|
return await self.project_repo.add_form3_line(report_id, expense_item_id)
|
|
|
|
async def del_form3_line(
|
|
self,
|
|
project_id: int,
|
|
year: int,
|
|
report_type: str,
|
|
line_id: int,
|
|
user: AppUser,
|
|
) -> list[tuple]:
|
|
report_id = await self.resolve_report_id(project_id, year, report_type, user)
|
|
if not report_id:
|
|
raise ValidationException("Отчёт не найден")
|
|
return await self.project_repo.del_form3_line(line_id)
|
|
|
|
async def upd_project(
|
|
self,
|
|
project_id: int,
|
|
column: str,
|
|
value,
|
|
user: AppUser,
|
|
):
|
|
project = await self.get(project_id, user)
|
|
if not project:
|
|
raise ValidationException("Проект не найден")
|
|
return await self.project_repo.upd_project(project_id, column, value)
|
|
|
|
async def add_project(
|
|
self,
|
|
name: str,
|
|
year: int,
|
|
org_unit_id: int,
|
|
level: str = "project",
|
|
parent_id: int | None = None,
|
|
project_type: str | None = None,
|
|
vsp_format: str | None = None,
|
|
placement_type: str | None = None,
|
|
object_address: str | None = None,
|
|
staff_count: int | None = None,
|
|
total_area: float | None = None,
|
|
) -> tuple[int, int, int]:
|
|
return await self.project_repo.add_project(
|
|
name=name,
|
|
year=year,
|
|
org_unit_id=org_unit_id,
|
|
level=level,
|
|
parent_id=parent_id,
|
|
project_type=project_type,
|
|
vsp_format=vsp_format,
|
|
placement_type=placement_type,
|
|
object_address=object_address,
|
|
staff_count=staff_count,
|
|
total_area=total_area,
|
|
)
|
|
|
|
async def _allowed_org_unit_ids(self, user: AppUser) -> list[int] | None:
|
|
if user.role_id == UserRoleEnum.ADMIN:
|
|
return None
|
|
db_user = await self.user_repo.get(user_id=user.id, load_orgs=True)
|
|
if not db_user:
|
|
return []
|
|
return [ou.id for ou in db_user.org_units]
|