from sqlalchemy.ext.asyncio import AsyncSession from src.db.models.form4_project import Form4ProjectLevelEnum from src.db.models.role import UserRoleEnum from src.repository.budget_form_repository import BudgetFormRepository from src.repository.form4_project_repository import Form4ProjectRepository from src.repository.user_repository import UserRepository from src.db.models.app_user import AppUser from src.db.models.budget_form import BudgetForm from src.repository.sheet_repository import SheetRepository, SheetValidationError class SheetService: def __init__(self, db: AsyncSession): self.db = db self.sheet_repo = SheetRepository(db) self.bf_repo = BudgetFormRepository(db) self.user_repo = UserRepository(db) self.f4_project_repo = Form4ProjectRepository(db) async def get( self, sheet: str, direction: str | None, sections: list[str] | None = None, form_id: int | None = None, form: BudgetForm | None = None ) -> list[tuple]: return await self.sheet_repo.get( form_id=form_id, sheet=sheet, direction=direction, sections=sections, ) async def update_cells( self, form_id: int, sheet: str, direction: str | None, sections: list[str] | None, changes: list[dict], user: AppUser | None = None, ) -> list[tuple]: return await self.sheet_repo.update_cells( form_id=form_id, sheet=sheet, direction=direction, sections=sections, changes=changes, user_id=user.id if user else None, ) async def update_cell( self, form_id: int, sheet: str, direction: str | None, sections: list[str] | None, line_id: int, column: str, value: str | int | float | None = None, user: AppUser | None = None, ) -> list[tuple]: return await self.sheet_repo.update_cell( form_id=form_id, sheet=sheet, direction=direction, sections=sections, line_id=line_id, column=column, value=value, user_id=user.id if user else None, ) async def add_line( self, form_id: int, sheet: str, expense_item_id: int | None = None, item_id: str | None = None, section_code: str | None = None, direction: str | None = None, name: str | None = None, internal_order: str | None = None, vsp_id: int | None = None, project_id: int | None = None, justification: str | None = None, contract_number: str | None = None, contract_end_date: str | None = None, user: AppUser | None = None, ) -> list[tuple]: return await self.sheet_repo.add_line( form_id=form_id, sheet=sheet, expense_item_id=expense_item_id, item_id=item_id, section_code=section_code, direction=direction, name=name, internal_order=internal_order, vsp_id=vsp_id, project_id=project_id, justification=justification, contract_number=contract_number, contract_end_date=contract_end_date, user_id=user.id if user else None, ) async def add_program( self, form_id: int, sheet: str, name: str, user: AppUser | None = None, ) -> tuple[int, list[tuple]]: if user.role_id != UserRoleEnum.ADMIN: user = await self.user_repo.get( user_id=user.id, load_orgs=True, ) form = await self.bf_repo.get( budget_form_id=form_id, org_unit=[ou.id for ou in user.org_units], ) if not form: raise SheetValidationError("Форма не найдена") result = await self.sheet_repo.add_program( form_id=form_id, sheet=sheet, name=name, ) if result: return (result[0][0], [tuple(r[1:]) for r in result]) return None async def add_project( self, name: str, program_id: int, user: AppUser | None = None, ) -> tuple[int, list[tuple]]: if user.role_id != UserRoleEnum.ADMIN: program = await self.f4_project_repo.get( project_id=program_id, level=Form4ProjectLevelEnum.PROGRAM, ) if not program: raise SheetValidationError("Программа не найдена") user = await self.user_repo.get( user_id=user.id, load_orgs=True, ) form = await self.bf_repo.get( budget_form_id=program.form_id, org_unit=[ou.id for ou in user.org_units], ) if not form: raise SheetValidationError("Программа не найдена") result = await self.sheet_repo.add_project( program_id=program_id, name=name, ) if result: return (result[0][0], [tuple(r[1:]) for r in result]) return None async def delete_line( self, form_id: int, sheet: str, row_id: int, direction: str | None = None, user: AppUser | None = None, ) -> list[tuple]: return await self.sheet_repo.delete_line( sheet=sheet, row_id=row_id, direction=direction, )