websocket-projects: возвращается line_id, ошибка при удалении строки #23

Merged
tsygankoviva merged 1 commits from websocket-projects into test 2026-07-03 08:04:13 +03:00
6 changed files with 165 additions and 9 deletions

View File

@ -14,6 +14,8 @@ from sqlalchemy.exc import IntegrityError
from fastapi import APIRouter, WebSocket, WebSocketDisconnect, status from fastapi import APIRouter, WebSocket, WebSocketDisconnect, status
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from src.services.rf_project_report_service import RfProjectReportService
from src.services.rf_project_report_line_service import RfProjectReportLineService
from src.repository.user_repository import UserRepository from src.repository.user_repository import UserRepository
from src.services.budget_line_service import BudgetLineService from src.services.budget_line_service import BudgetLineService
from src.api.v1.deps import get_user_by_token from src.api.v1.deps import get_user_by_token
@ -490,7 +492,8 @@ class FormEventProcess:
class ProjectEventProcess: class ProjectEventProcess:
def __init__(self, db: AsyncSession): def __init__(self, db: AsyncSession):
self.project_service: ProjectService = ProjectService(db) self.project_service: ProjectService = ProjectService(db)
self.bf_service: BudgetFormService = BudgetFormService(db) self.prl_service: RfProjectReportLineService = RfProjectReportLineService(db)
self.pr_service: RfProjectReportService = RfProjectReportService(db)
self.user_service: UserService = UserService(db) self.user_service: UserService = UserService(db)
async def process( async def process(
@ -573,11 +576,16 @@ class ProjectEventProcess:
expense_item_id: Optional[int] = None expense_item_id: Optional[int] = None
} }
""" """
project = await self.project_service.get(project_id=project_id, user=user) project_report = await self.pr_service.get(
if not project: year=year,
report_type=report_type,
project_id=project_id,
)
if not project_report:
return None return None
return await self.project_service.add_form3_line( ids = await self.prl_service.get_ids(project_report_id=project_report.id)
result = await self.project_service.add_form3_line(
project_id=project_id, project_id=project_id,
year=year, year=year,
report_type=report_type, report_type=report_type,
@ -585,6 +593,16 @@ class ProjectEventProcess:
user=user, user=user,
) )
final_result = {
"data": result,
"new_line_id": None,
}
for el in result:
if el[3]["line_id"] and el[3]["line_id"] not in ids:
final_result["new_line_id"] = el[3]["line_id"]
return final_result
return final_result
async def __del_row( async def __del_row(
self, self,
event_data: dict, event_data: dict,
@ -595,7 +613,7 @@ class ProjectEventProcess:
) -> list[tuple]: ) -> list[tuple]:
""" """
data = { data = {
"line_id": int, "row_id": int,
} }
""" """
project = await self.project_service.get(project_id=project_id, user=user) project = await self.project_service.get(project_id=project_id, user=user)
@ -606,7 +624,7 @@ class ProjectEventProcess:
project_id=project_id, project_id=project_id,
year=year, year=year,
report_type=report_type, report_type=report_type,
line_id=event_data["line_id"], line_id=event_data["row_id"],
user=user, user=user,
) )
@ -776,6 +794,7 @@ async def process_websocket(
async with get_db_session(user_id=user_id) as db: async with get_db_session(user_id=user_id) as db:
processor = processor_cls(db) processor = processor_cls(db)
t0 = time.perf_counter() t0 = time.perf_counter()
data_old = data.copy()
data["result"] = await processor.process( data["result"] = await processor.process(
event_data=data, event_data=data,
user_id=user_id, user_id=user_id,
@ -789,7 +808,7 @@ async def process_websocket(
"time_ms": f"{db_ms:.2f}", "time_ms": f"{db_ms:.2f}",
"event": data.get("event"), "event": data.get("event"),
} }
extra.update(data) extra.update(data_old)
logger.info( logger.info(
f"db_time: {extra}", f"db_time: {extra}",
extra=extra, extra=extra,

View File

@ -12,7 +12,7 @@ class BudgetLineRepository:
query = select(BudgetLine).where(BudgetLine.id == budget_line_id).limit(1) query = select(BudgetLine).where(BudgetLine.id == budget_line_id).limit(1)
return (await self.db.execute(query)).scalar_one_or_none() return (await self.db.execute(query)).scalar_one_or_none()
async def get_list(self, budget_line_ids: list[int]) -> BudgetLine | None: async def get_list(self, budget_line_ids: list[int]) -> list[BudgetLine]:
query = select(BudgetLine).where(BudgetLine.id.in_(budget_line_ids)) query = select(BudgetLine).where(BudgetLine.id.in_(budget_line_ids))
return (await self.db.execute(query)).scalars().all() return (await self.db.execute(query)).scalars().all()

View File

@ -0,0 +1,39 @@
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from src.db.models.rf_project_report_line import RfProjectReportLine
class RfProjectReportLineRepository:
def __init__(self, db: AsyncSession):
self.db = db
async def get(self, line_id: int) -> RfProjectReportLine | None:
query = select(
RfProjectReportLine
).where(
RfProjectReportLine.id == line_id
).limit(1)
return (await self.db.execute(query)).scalar_one_or_none()
async def get_list(self, line_ids: list[int]) -> list[RfProjectReportLine]:
query = select(
RfProjectReportLine
).where(
RfProjectReportLine.id.in_(line_ids)
)
return (await self.db.execute(query)).scalars().all()
async def get_ids(
self,
project_report_id: int,
) -> list[int]:
query = select(
RfProjectReportLine.id
).where(
RfProjectReportLine.rf_project_report_id == project_report_id
)
return (await self.db.execute(query)).scalars().all()

View File

@ -0,0 +1,33 @@
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from src.db.models.rf_project_report import RfProjectReport
class RfProjectReportRepository:
def __init__(self, db: AsyncSession):
self.db = db
async def get(
self,
report_id: int | None = None,
year: int | None = None,
report_type: str | None = None,
project_id: int | None = None,
) -> RfProjectReport | None:
assert report_id is not None or all((el is not None for el in (year, report_type, project_id)))
query = select(
RfProjectReport
)
if report_id is not None:
query = query.where(RfProjectReport.id == report_id)
else:
query = query.where(
RfProjectReport.year == year,
RfProjectReport.report_type == report_type,
RfProjectReport.project_id == project_id
)
query = query.limit(1)
return (await self.db.execute(query)).scalar_one_or_none()

View File

@ -0,0 +1,34 @@
from sqlalchemy.ext.asyncio import AsyncSession
from src.db.models.rf_project_report_line import RfProjectReportLine
from src.repository.rf_project_report_line_repository import RfProjectReportLineRepository
from src.db.models.app_user import AppUser
class RfProjectReportLineService:
def __init__(self, db: AsyncSession):
self.db = db
self.prl_repo = RfProjectReportLineRepository(db)
async def get(
self,
user: AppUser,
line_id: int,
) -> RfProjectReportLine | None:
return await self.prl_repo.get(line_id=line_id)
async def get_list(
self,
user: AppUser,
line_ids: list[int],
) -> list[RfProjectReportLine]:
return await self.prl_repo.get_list(line_ids=line_ids)
async def get_ids(
self,
project_report_id: int,
) -> list[int]:
return await self.prl_repo.get_ids(project_report_id=project_report_id)

View File

@ -0,0 +1,31 @@
from sqlalchemy.ext.asyncio import AsyncSession
from src.db.models.rf_project_report import RfProjectReport
from src.repository.rf_project_report_repository import RfProjectReportRepository
from src.db.models.rf_project_report_line import RfProjectReportLine
from src.repository.rf_project_report_line_repository import RfProjectReportLineRepository
from src.db.models.app_user import AppUser
class RfProjectReportService:
def __init__(self, db: AsyncSession):
self.db = db
self.pr_repo = RfProjectReportRepository(db)
async def get(
self,
user: AppUser| None = None,
report_id: int | None = None,
year: int | None = None,
report_type: str | None = None,
project_id: int | None = None,
) -> RfProjectReport | None:
return await self.pr_repo.get(
report_id=report_id,
year=year,
report_type=report_type,
project_id=project_id,
)