from urllib.parse import urlsplit from django.urls import reverse from drf_spectacular.utils import extend_schema_field from rest_framework import serializers from api.v1.employees.serializers import EmployeeBriefSerializer from tasks.models import ( TaskActivity, TaskAttachment, TaskChecklistItem, TaskExternalLink, ) class TaskActivitySerializer(serializers.ModelSerializer): actor = EmployeeBriefSerializer(read_only=True) action_display = serializers.CharField(source="get_action_display", read_only=True) class Meta: model = TaskActivity fields = [ "id", "action", "action_display", "actor", "object_kind", "object_id", "metadata", "created_at", ] read_only_fields = fields class TaskAttachmentSerializer(serializers.ModelSerializer): uploaded_by = EmployeeBriefSerializer(read_only=True) download_url = serializers.SerializerMethodField() thumbnail_url = serializers.SerializerMethodField() class Meta: model = TaskAttachment fields = [ "id", "task", "comment", "file_name", "file_size", "mime_type", "uploaded_by", "created_at", "download_url", "thumbnail_url", ] read_only_fields = fields @extend_schema_field(serializers.URLField()) def get_download_url(self, obj): url = reverse( "api:v1:tasks:task-attachment-download", kwargs={"pk": obj.task_id, "attachment_id": obj.id}, ) request = self.context.get("request") return request.build_absolute_uri(url) if request else url @extend_schema_field(serializers.URLField(allow_null=True)) def get_thumbnail_url(self, obj): from tasks.media import task_attachment_media_kind if not task_attachment_media_kind(obj): return None url = reverse( "api:v1:tasks:task-attachment-thumbnail", kwargs={"pk": obj.task_id, "attachment_id": obj.id}, ) request = self.context.get("request") return request.build_absolute_uri(url) if request else url class TaskChecklistItemSerializer(serializers.ModelSerializer): created_by = EmployeeBriefSerializer(read_only=True) completed_by = EmployeeBriefSerializer(read_only=True) class Meta: model = TaskChecklistItem fields = [ "id", "task", "title", "position", "is_completed", "created_by", "completed_by", "completed_at", "created_at", "updated_at", ] read_only_fields = [ "id", "task", "created_by", "completed_by", "completed_at", "created_at", "updated_at", ] def validate_title(self, value): value = value.strip() if not value: raise serializers.ValidationError("Введите текст пункта чек-листа.") return value class TaskExternalLinkSerializer(serializers.ModelSerializer): created_by = EmployeeBriefSerializer(read_only=True) class Meta: model = TaskExternalLink fields = ["id", "task", "url", "title", "created_by", "created_at"] read_only_fields = ["id", "task", "created_by", "created_at"] def validate_url(self, value): value = value.strip() if urlsplit(value).scheme.lower() not in {"http", "https"}: raise serializers.ValidationError( "Разрешены только ссылки с протоколом http или https." ) return value def validate_title(self, value): return value.strip()