Untitled

4ae4d avatar
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