feat(reports): refine exports and restore project access

This commit is contained in:
2026-05-14 17:06:35 +03:30
parent 77c07adec8
commit d4a52d6f3b
16 changed files with 1594 additions and 136 deletions

View File

@@ -3,6 +3,7 @@ from rest_framework import serializers
from core.serializers.base import BaseModelSerializer
from apps.time_entries.models import TimeEntry
from apps.projects.models import Project
from apps.projects.services.access import ensure_project_access
from apps.tags.models import Tag
@@ -99,6 +100,8 @@ class TimeEntryCreateSerializer(serializers.Serializer):
is_billable = serializers.BooleanField(default=False)
def validate(self, attrs):
user = self.context.get("request").user if self.context.get("request") else None
workspace_id = attrs.get("workspace_id")
project_id = attrs.pop("project_id", serializers.empty)
if project_id is not serializers.empty:
if project_id is None:
@@ -107,6 +110,10 @@ class TimeEntryCreateSerializer(serializers.Serializer):
project = Project.objects.filter(id=project_id).first()
if not project:
raise serializers.ValidationError({"project_id": "Selected project is unavailable."})
if workspace_id and str(project.workspace_id) != str(workspace_id):
raise serializers.ValidationError({"project_id": "Selected project is unavailable."})
if user:
ensure_project_access(user, project)
attrs["project"] = project
tag_ids = attrs.pop("tags", serializers.empty)
@@ -134,6 +141,7 @@ class TimeEntryUpdateSerializer(serializers.Serializer):
def validate(self, attrs):
entry = self.instance
user = self.context.get("request").user if self.context.get("request") else None
project_id = attrs.pop("project_id", serializers.empty)
if project_id is not serializers.empty:
@@ -146,6 +154,10 @@ class TimeEntryUpdateSerializer(serializers.Serializer):
project = Project.objects.filter(id=project_id).first()
if not project:
raise serializers.ValidationError({"project_id": "Selected project is unavailable."})
if entry and str(project.workspace_id) != str(entry.workspace_id):
raise serializers.ValidationError({"project_id": "Selected project is unavailable."})
if user:
ensure_project_access(user, project)
attrs["project"] = project
tag_ids = attrs.pop("tags", serializers.empty)