Untitled
4ae4d
plain_text
01/28/2026 1:31 PM
4.3 KB
9
Indexable
+++ b/src/backend/app/services/report.py
@@
+from __future__ import annotations
+
+from uuid import UUID
+
+from ..dependencies.administrator import Administrator
+from ..utils.errors import AuthError, ConflictError, NotFoundError
+
+
+class ReportService:
+ def __init__(self, administrator: Administrator):
+ self.administrator = administrator
+
+ @staticmethod
+ def _role_value(role) -> str | None:
+ if role is None:
+ return None
+ return str(getattr(role, "value", role))
+
+ async def create_report(
+ self,
+ *,
+ event_id: UUID,
+ requester_messenger_id: int,
+ how_it_went: str,
+ beneficiaries_count: int | None = None,
+ ):
+ async with self.administrator.start() as admin:
+ requester = await admin.user.get_by_messenger_id(requester_messenger_id)
+ if not requester:
+ raise NotFoundError("User not found")
+
+ event = await admin.event.get_by_id(event_id)
+ if not event:
+ raise NotFoundError("Event not found")
+
+ role = self._role_value(getattr(requester, "role", None))
+ is_admin = role == "admin"
+
+ # создавать отчёт: организатор + админ
+ if not is_admin:
+ if not event.creator_id or str(event.creator_id) != str(requester.id):
+ raise AuthError("Access denied: only organizer or admin can create report")
+
+ exists = await admin.report.get_by_event_id(event_id)
+ if exists:
+ raise ConflictError("Report already exists for this event")
+
+ participants_count = await admin.participation.count_by_event_id(event_id)
+
+ payload = {
+ "event_id": event_id,
+ "how_it_went": how_it_went,
+ "beneficiaries_count": beneficiaries_count,
+ "participants_count_snapshot": participants_count,
+ }
+
+ created = await admin.report.insert(payload)
+ return created
+
+ async def get_report(
+ self,
+ *,
+ event_id: UUID,
+ requester_messenger_id: int,
+ ):
+ async with self.administrator.start() as admin:
+ requester = await admin.user.get_by_messenger_id(requester_messenger_id)
+ if not requester:
+ raise NotFoundError("User not found")
+
+ event = await admin.event.get_by_id(event_id)
+ if not event:
+ raise NotFoundError("Event not found")
+
+ role = self._role_value(getattr(requester, "role", None))
+ is_admin = role == "admin"
+ is_moderator = role == "moderator"
+ is_organizer = bool(event.creator_id) and str(event.creator_id) == str(requester.id)
+
+ # смотреть отчёт: модератор/админ + организатор
+ if not (is_admin or is_moderator or is_organizer):
+ raise AuthError("Access denied")
+
+ report = await admin.report.get_by_event_id(event_id)
+ if not report:
+ raise NotFoundError("Report not found")
+
+ return report
Editor is loading...
Leave a Comment